Merge pull request #58 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
L_J 2018-06-01 20:38:19 +02:00 committed by GitHub
commit b368d3f832
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18239 changed files with 52051 additions and 39322 deletions

6
.gitignore vendored
View file

@ -89,6 +89,8 @@ Mage.Verify/target
Mage.Verify/mageclient.log
Mage.Verify/AllCards.json.zip
Mage.Verify/AllSets.json.zip
Mage.Verify/AllCards.json
Mage.Verify/AllSets.json
releases
Utils/author.txt
@ -140,3 +142,7 @@ client_secrets.json
dependency-reduced-pom.xml
mage-bundle
/Mage.Client/game-*.json
# build-tools config and log files when building client/server with Atom
.build-tools.cson
build-output.log

View file

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

View file

@ -105,6 +105,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final String GRAY_MODE_ARG = "-gray";
private static final String FILL_SCREEN_ARG = "-fullscreen";
private static final String SKIP_DONE_SYMBOLS = "-skipDoneSymbols";
private static final String USER_ARG = "-user";
private static final String PASSWORD_ARG = "-pw";
private static final String SERVER_ARG = "-server";
private static final String PORT_ARG = "-port";
private static final String NOT_CONNECTED_TEXT = "<not connected>";
private static MageFrame instance;
@ -123,6 +127,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static boolean grayMode = false;
private static boolean fullscreenMode = false;
private static boolean skipSmallSymbolGenerationForExisting = false;
private static String startUser = null;
private static String startPassword = "";
private static String startServer = "localhost";
private static int startPort = -1;
private static final Map<UUID, ChatPanelBasic> CHATS = new HashMap<>();
private static final Map<UUID, GamePanel> GAMES = new HashMap<>();
@ -732,7 +740,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
public boolean autoConnect() {
boolean autoConnectParamValue = Boolean.parseBoolean(PREFS.get("autoConnect", "false"));
boolean autoConnectParamValue = startUser != null || Boolean.parseBoolean(PREFS.get("autoConnect", "false"));
boolean status = false;
if (autoConnectParamValue) {
status = performConnect(false);
@ -1186,8 +1194,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
startTime = System.currentTimeMillis();
Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.fatal(null, e));
SwingUtilities.invokeLater(() -> {
for (String arg : args) {
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith(LITE_MODE_ARG)) {
liteMode = true;
}
@ -1200,6 +1210,22 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (arg.startsWith(SKIP_DONE_SYMBOLS)) {
skipSmallSymbolGenerationForExisting = true;
}
if (arg.startsWith(USER_ARG)){
startUser = args[i+1];
i++;
}
if (arg.startsWith(PASSWORD_ARG)){
startPassword = args[i+1];
i++;
}
if (arg.startsWith(SERVER_ARG)){
startServer = args[i+1];
i++;
}
if (arg.startsWith(PORT_ARG)){
startPort = Integer.valueOf(args[i+1]);
i++;
}
}
if (!liteMode) {
final SplashScreen splash = SplashScreen.getSplashScreen();
@ -1212,6 +1238,19 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
}
instance = new MageFrame();
if( startUser != null){
instance.currentConnection = new Connection();
instance.currentConnection.setUsername(startUser);
instance.currentConnection.setHost(startServer);
if (startPort > 0){
instance.currentConnection.setPort(startPort);
}else {
instance.currentConnection.setPort(MagePreferences.getServerPortWithDefault(Config.port));
}
PreferencesDialog.setProxyInformation(instance.currentConnection);
instance.currentConnection.setPassword(startPassword);
}
instance.setVisible(true);
});

View file

@ -851,7 +851,6 @@
</Component>
<Component class="javax.swing.JCheckBox" name="chkUnique">
<Properties>
<Property name="selected" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" value="Unique"/>
<Property name="toolTipText" type="java.lang.String" value="Show only the first found card of every card name."/>
<Property name="focusable" type="boolean" value="false"/>

View file

@ -51,13 +51,13 @@ import mage.client.MageFrame;
import mage.client.cards.*;
import mage.client.constants.Constants.SortBy;
import mage.client.deckeditor.table.TableModel;
import mage.client.dialog.CheckBoxList;
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_NAMES;
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_RULES;
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_TYPES;
import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_UNIQUE;
import mage.client.util.GUISizeHelper;
import mage.client.util.gui.FastSearchUtil;
import mage.client.dialog.CheckBoxList;
import mage.client.util.sets.ConstructedFormats;
import mage.constants.CardType;
import mage.constants.Rarity;
@ -85,7 +85,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
private final SortSetting sortSetting;
private static final Map<String, Integer> pdAllowed = new HashMap<>();
private final String TEST_MULTI_SET="Multiple Sets selected";
private final String TEST_MULTI_SET = "Multiple Sets selected";
private final ActionListener searchAction = evt -> jButtonSearchActionPerformed(evt);
@ -100,22 +100,20 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
initListViewComponents();
setGUISize();
currentView = mainModel; // by default we use List View
listCodeSelected = new CheckBoxList();
listCodeSelected = new CheckBoxList();
// remove the all option
boolean is_removeFinish=false;
String[] setCodes = ConstructedFormats.getTypes();
java.util.List<String> result = new ArrayList<>();
for(int i=0; (i<setCodes.length)&&(!is_removeFinish);i++)
{
boolean is_removeFinish = false;
String[] setCodes = ConstructedFormats.getTypes();
java.util.List<String> result = new ArrayList<>();
for (int i = 0; (i < setCodes.length) && (!is_removeFinish); i++) {
String item = setCodes[i];
if(!item.equals(ConstructedFormats.ALL))
{
if (!item.equals(ConstructedFormats.ALL)) {
result.add(item);
}
}
}
listCodeSelected.setListData(result.toArray());
}
@ -377,33 +375,29 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
criteria.rarities(Rarity.BONUS);
}
if (this.cbExpansionSet.isVisible()) {
if(listCodeSelected.getCheckedIndices().length <= 1)
{
String expansionSelection = this.cbExpansionSet.getSelectedItem().toString();
if (!expansionSelection.equals("- All Sets")) {
java.util.List<String> setCodes = ConstructedFormats.getSetsByFormat(expansionSelection);
criteria.setCodes(setCodes.toArray(new String[0]));
}
}
else
{
java.util.List<String> setCodes = new ArrayList<>() ;
//java.util.List<String> listReceived=new ArrayList<>() ;
if (listCodeSelected.getCheckedIndices().length <= 1) {
String expansionSelection = this.cbExpansionSet.getSelectedItem().toString();
if (!expansionSelection.equals("- All Sets")) {
java.util.List<String> setCodes = ConstructedFormats.getSetsByFormat(expansionSelection);
criteria.setCodes(setCodes.toArray(new String[0]));
}
} else {
java.util.List<String> setCodes = new ArrayList<>();
//java.util.List<String> listReceived=new ArrayList<>() ;
int[] choiseValue=listCodeSelected.getCheckedIndices();
ListModel x= listCodeSelected.getModel();
int[] choiseValue = listCodeSelected.getCheckedIndices();
ListModel x = listCodeSelected.getModel();
for(int itemIndex: choiseValue){
java.util.List<String> listReceived=ConstructedFormats.getSetsByFormat(x.getElementAt(itemIndex).toString());
listReceived.stream().filter((item) -> (setCodes.contains(item)==false)).forEachOrdered((item) -> {
setCodes.add(item);
});
}
criteria.setCodes(setCodes.toArray(new String[0]));
}
}
for (int itemIndex : choiseValue) {
java.util.List<String> listReceived = ConstructedFormats.getSetsByFormat(x.getElementAt(itemIndex).toString());
listReceived.stream().filter((item) -> (setCodes.contains(item) == false)).forEachOrdered((item) -> {
setCodes.add(item);
});
}
criteria.setCodes(setCodes.toArray(new String[0]));
}
}
return criteria;
}
@ -1234,22 +1228,19 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
}// </editor-fold>//GEN-END:initComponents
private void cbExpansionSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbExpansionSetActionPerformed
if(!cbExpansionSet.getSelectedItem().toString().contains(TEST_MULTI_SET))
{
int index=cbExpansionSet.getSelectedIndex();
if(cbExpansionSet.getItemAt(0).contains(TEST_MULTI_SET))
{
if (!cbExpansionSet.getSelectedItem().toString().contains(TEST_MULTI_SET)) {
int index = cbExpansionSet.getSelectedIndex();
if (cbExpansionSet.getItemAt(0).contains(TEST_MULTI_SET)) {
cbExpansionSet.removeItemAt(0);
index--;
}
listCodeSelected.uncheckAll();
if(index > 0)
{
listCodeSelected.uncheckAll();
if (index > 0) {
//ofset because all sets is removed from the list
listCodeSelected.setChecked(index-1, true);
listCodeSelected.setChecked(index - 1, true);
}
}
filterCards();
}//GEN-LAST:event_cbExpansionSetActionPerformed
@ -1422,62 +1413,53 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
// TODO add your handling code here:
}//GEN-LAST:event_chkTypesActionPerformed
private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) {
private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
}
private void chkUniqueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkRulesActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_chkRulesActionPerformed
private void btnExpansionSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExpansionSearchActionPerformed
FastSearchUtil.showFastSearchForStringComboBox(listCodeSelected, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE);
FastSearchUtil.showFastSearchForStringComboBox(listCodeSelected, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE);
//
int[] choiseValue=listCodeSelected.getCheckedIndices();
ListModel x= listCodeSelected.getModel();
if(choiseValue.length==0)//none
int[] choiseValue = listCodeSelected.getCheckedIndices();
ListModel x = listCodeSelected.getModel();
if (choiseValue.length == 0)//none
{
cbExpansionSet.setSelectedIndex(0);
}
else if(choiseValue.length==1)//one
cbExpansionSet.setSelectedIndex(0);
} else if (choiseValue.length == 1)//one
{
String itemSelected=listCodeSelected.getModel().getElementAt(choiseValue[0]).toString();
for(int index=0;index < cbExpansionSet.getItemCount();index++)
{
if(cbExpansionSet.getItemAt(index).equals(itemSelected))
{
String itemSelected = listCodeSelected.getModel().getElementAt(choiseValue[0]).toString();
for (int index = 0; index < cbExpansionSet.getItemCount(); index++) {
if (cbExpansionSet.getItemAt(index).equals(itemSelected)) {
cbExpansionSet.setSelectedIndex(index);
}
}
}
else//many
} else//many
{
String message=String.format("%s:%d",TEST_MULTI_SET,choiseValue.length);
String message = String.format("%s:%d", TEST_MULTI_SET, choiseValue.length);
cbExpansionSet.insertItemAt(message, 0);
cbExpansionSet.setSelectedIndex(0);
if(cbExpansionSet.getItemAt(1).contains(TEST_MULTI_SET))
{
cbExpansionSet.removeItemAt(1);
if (cbExpansionSet.getItemAt(1).contains(TEST_MULTI_SET)) {
cbExpansionSet.removeItemAt(1);
}
//listCodeSelected.setChecked(index-1, true);
//cbExpansionSet.
//cbExpansionSet.
}
/*for(int itemIndex: choiseValue){
/*for(int itemIndex: choiseValue){
// LogLog.warn(String.format("%d:%s",itemIndex,x.getElementAt(itemIndex).toString()));
}
*/
*/
//
filterCards();
filterCards();
}//GEN-LAST:event_btnExpansionSearchActionPerformed
private void tbCommonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbCommonActionPerformed
@ -1537,8 +1519,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
private TableModel mainModel;
private JTable mainTable;
private ICardGrid currentView;
private CheckBoxList listCodeSelected;
private final CheckBoxList listCodeSelected;
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup bgView;

View file

@ -26,11 +26,10 @@
*/
package mage.client.deckeditor.table;
import java.util.Comparator;
import mage.cards.MageCard;
import mage.view.CardView;
import java.util.Comparator;
/**
* {@link MageCard} comparator. Used to sort cards in Deck Editor Table View
* pane.
@ -75,7 +74,7 @@ public class MageCardComparator implements Comparator<CardView> {
// Color
case 3:
aCom = a.getColorText();
bCom = a.getColorText();
bCom = b.getColorText();
break;
// Type
case 4:

View file

@ -203,6 +203,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_TABLES_DIVIDER_LOCATION_1 = "tablePanelDividerLocation1";
public static final String KEY_TABLES_DIVIDER_LOCATION_2 = "tablePanelDividerLocation2";
public static final String KEY_TABLES_DIVIDER_LOCATION_3 = "tablePanelDividerLocation3";
public static final String KEY_TABLES_DIVIDER_LOCATION_4 = "tablePanelDividerLocation4";
// Positions of deck editor divider bars
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION = "editorHorizontalDividerLocation";

View file

@ -111,7 +111,7 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="tableSeats">
<Component class="javax.swing.JTable" name="jTableSeats">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="tableWaitModel" type="code"/>

View file

@ -34,6 +34,7 @@
package mage.client.dialog;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -43,22 +44,26 @@ import java.util.concurrent.TimeUnit;
import javax.swing.Icon;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import org.apache.log4j.Logger;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
import mage.client.components.MageComponents;
import mage.client.components.tray.MageTray;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.client.util.gui.GuiDisplayUtil;
import mage.players.PlayerType;
import mage.remote.Session;
import mage.view.SeatView;
import mage.view.TableView;
import org.apache.log4j.Logger;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_4;
/**
* @author BetaSteward_at_googlemail.com
@ -66,7 +71,7 @@ import org.apache.log4j.Logger;
public class TableWaitingDialog extends MageDialog {
private static final Logger LOGGER = Logger.getLogger(TableWaitingDialog.class);
private static final int[] DEFAULT_COLUMS_WIDTH = {20, 50, 100, 100, 100};
private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 50, 100, 100, 100, 100};
private UUID tableId;
private UUID roomId;
@ -89,12 +94,11 @@ public class TableWaitingDialog extends MageDialog {
this.setSize(prefWidth, prefHeight);
}
chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
tableSeats.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableSeats, DEFAULT_COLUMS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer());
setGUISize();
jTableSeats.createDefaultColumnsFromModel();
jTableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer());
TableUtil.setColumnWidthAndOrder(jTableSeats, DEFAULT_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart);
}
@ -104,9 +108,9 @@ public class TableWaitingDialog extends MageDialog {
}
private void setGUISize() {
tableSeats.getTableHeader().setFont(GUISizeHelper.tableFont);
tableSeats.setFont(GUISizeHelper.tableFont);
tableSeats.setRowHeight(GUISizeHelper.getTableRowHeight());
jTableSeats.getTableHeader().setFont(GUISizeHelper.tableFont);
jTableSeats.setFont(GUISizeHelper.tableFont);
jTableSeats.setRowHeight(GUISizeHelper.getTableRowHeight());
jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize);
jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0));
@ -131,14 +135,14 @@ public class TableWaitingDialog extends MageDialog {
closeDialog();
return;
}
int row = this.tableSeats.getSelectedRow();
int row = this.jTableSeats.getSelectedRow();
if (getTitle().equals("Waiting for players")) {
this.title = getTitle() + " - " + table.getDeckType() + " / " + table.getGameType();
this.repaint();
}
tableWaitModel.loadData(table);
this.tableSeats.repaint();
this.tableSeats.getSelectionModel().setSelectionInterval(row, row);
this.jTableSeats.repaint();
this.jTableSeats.getSelectionModel().setSelectionInterval(row, row);
} else {
closeDialog();
}
@ -148,10 +152,15 @@ public class TableWaitingDialog extends MageDialog {
}
public void showDialog(UUID roomId, UUID tableId, boolean isTournament) {
Rectangle currentBounds = MageFrame.getDesktop().getBounds();
Optional<UUID> chatId = SessionHandler.getTableChatId(tableId);
String tournamentChatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_4, null);
updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this);
this.roomId = roomId;
this.tableId = tableId;
this.isTournament = isTournament;
updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this);
if (SessionHandler.isTableOwner(roomId, tableId)) {
this.btnStart.setVisible(true);
this.btnMoveDown.setVisible(true);
@ -161,13 +170,15 @@ public class TableWaitingDialog extends MageDialog {
this.btnMoveDown.setVisible(false);
this.btnMoveUp.setVisible(false);
}
Optional<UUID> chatId = SessionHandler.getTableChatId(tableId);
if (chatId.isPresent()) {
this.chatPanel.connect(chatId.get());
updateTask.execute();
this.setModal(false);
this.setLocation(100, 100);
this.setVisible(true);
GuiDisplayUtil.restoreDividerLocations(currentBounds, tournamentChatDivider, jSplitPane1);
} else {
closeDialog();
}
@ -177,12 +188,13 @@ public class TableWaitingDialog extends MageDialog {
if (updateTask != null) {
updateTask.cancel(true);
}
this.chatPanel.disconnect();
MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON);
this.removeDialog();
TableUtil.saveColumnWidthAndOrderToPrefs(tableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_WIDTH, Integer.toString(getWidth()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_HEIGHT, Integer.toString(getHeight()));
TableUtil.saveColumnWidthAndOrderToPrefs(jTableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
GuiDisplayUtil.saveCurrentBoundsToPrefs();
GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_4, this.jSplitPane1.getDividerLocation());
}
/**
@ -200,7 +212,7 @@ public class TableWaitingDialog extends MageDialog {
btnStart = new javax.swing.JButton();
jSplitPane1 = new javax.swing.JSplitPane();
jScrollPane1 = new javax.swing.JScrollPane();
tableSeats = new javax.swing.JTable();
jTableSeats = new javax.swing.JTable();
chatPanel = new mage.client.chat.ChatPanelBasic();
setResizable(true);
@ -226,9 +238,9 @@ public class TableWaitingDialog extends MageDialog {
jSplitPane1.setResizeWeight(1.0);
jSplitPane1.setToolTipText("");
tableSeats.setModel(tableWaitModel);
tableSeats.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(tableSeats);
jTableSeats.setModel(tableWaitModel);
jTableSeats.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(jTableSeats);
jSplitPane1.setLeftComponent(jScrollPane1);
jSplitPane1.setRightComponent(chatPanel);
@ -288,19 +300,19 @@ public class TableWaitingDialog extends MageDialog {
}//GEN-LAST:event_btnCancelActionPerformed
private void btnMoveDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveDownActionPerformed
int row = this.tableSeats.getSelectedRow();
if (row < this.tableSeats.getRowCount() - 1) {
int row = this.jTableSeats.getSelectedRow();
if (row < this.jTableSeats.getRowCount() - 1) {
SessionHandler.swapSeats(roomId, tableId, row, row + 1);
this.tableSeats.getSelectionModel().setSelectionInterval(row + 1, row + 1);
this.jTableSeats.getSelectionModel().setSelectionInterval(row + 1, row + 1);
}
}//GEN-LAST:event_btnMoveDownActionPerformed
private void btnMoveUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveUpActionPerformed
int row = this.tableSeats.getSelectedRow();
int row = this.jTableSeats.getSelectedRow();
if (row > 0) {
SessionHandler.swapSeats(roomId, tableId, row, row - 1);
this.tableSeats.getSelectionModel().setSelectionInterval(row - 1, row - 1);
this.jTableSeats.getSelectionModel().setSelectionInterval(row - 1, row - 1);
}
}//GEN-LAST:event_btnMoveUpActionPerformed
@ -312,14 +324,14 @@ public class TableWaitingDialog extends MageDialog {
private mage.client.chat.ChatPanelBasic chatPanel;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JTable tableSeats;
private javax.swing.JTable jTableSeats;
// End of variables declaration//GEN-END:variables
}
class TableWaitModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Seat", "Loc", "Player Name", "Constructed Rating", "Player Type", "History"};
private final String[] columnNames = new String[]{"Seat", "Loc", "Player Name", "Rating", "Player Type", "History"};
private SeatView[] seats = new SeatView[0];
private boolean limited;
@ -327,8 +339,6 @@ class TableWaitModel extends AbstractTableModel {
seats = table.getSeats().toArray(new SeatView[0]);
if (limited != table.isLimited()) {
limited = table.isLimited();
columnNames[3] = limited ? "Limited Rating" : "Constructed Rating";
this.fireTableStructureChanged();
}
this.fireTableDataChanged();
}

View file

@ -56,6 +56,10 @@ import mage.client.components.MageComponents;
import mage.client.dialog.*;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2;
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3;
import mage.client.util.ButtonColumn;
import mage.client.util.GUISizeHelper;
import mage.client.util.IgnoreList;
@ -191,8 +195,7 @@ public class TablesPanel extends javax.swing.JPanel {
list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING));
activeTablesSorter.setSortKeys(list);
TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH,
PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); // TODO: is sort order save and restore after app restart/window open?
TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER);
// 2. TABLE COMPLETED
completedTablesSorter = new MageTableRowSorter(matchesModel);
@ -227,8 +230,7 @@ public class TablesPanel extends javax.swing.JPanel {
jScrollPaneTablesActive.getViewport().setBackground(new Color(255, 255, 255, 50));
jScrollPaneTablesFinished.getViewport().setBackground(new Color(255, 255, 255, 50));
restoreSettings();
restoreFilters();
setGUISize();
Action openTableAction;
@ -343,7 +345,7 @@ public class TablesPanel extends javax.swing.JPanel {
}
public void cleanUp() {
saveSettings();
saveGuiSettings();
chatPanelMain.cleanUp();
}
@ -406,65 +408,32 @@ public class TablesPanel extends javax.swing.JPanel {
}
private void saveDividerLocations() {
// save panel sizes and divider locations.
Rectangle rec = MageFrame.getDesktop().getBounds();
String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
PreferencesDialog.saveValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, sb);
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, Integer.toString(this.jSplitPane1.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, Integer.toString(this.jSplitPaneTables.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, Integer.toString(chatPanelMain.getSplitDividerLocation()));
// save divider locations and divider saveDividerLocations
GuiDisplayUtil.saveCurrentBoundsToPrefs();
GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation());
GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation());
GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation());
}
private void restoreSettings() {
// filter settings
String formatSettings = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, "");
int i = 0;
for (JToggleButton component : filterButtons) {
if (formatSettings.length() > i) {
component.setSelected(formatSettings.substring(i, i + 1).equals("x"));
} else {
component.setSelected(true);
}
i++;
}
private void restoreFilters() {
TableUtil.setActiveFilters(KEY_TABLES_FILTER_SETTINGS, filterButtons);
setTableFilter();
}
private void saveSettings() {
// Filters
StringBuilder formatSettings = new StringBuilder();
for (JToggleButton component : filterButtons) {
formatSettings.append(component.isSelected() ? "x" : "-");
}
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, formatSettings.toString());
private void saveGuiSettings() {
TableUtil.saveActiveFiltersToPrefs(KEY_TABLES_FILTER_SETTINGS, filterButtons);
TableUtil.saveColumnWidthAndOrderToPrefs(tableTables, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER);
}
private void restoreDividerLocations() {
Rectangle rec = MageFrame.getDesktop().getBounds();
if (rec != null) {
String size = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, null);
String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
// use divider positions only if screen size is the same as it was the time the settings were saved
if (size != null && size.equals(sb)) {
String location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, null);
if (location != null && jSplitPane1 != null) {
jSplitPane1.setDividerLocation(Integer.parseInt(location));
}
if (this.btnStateFinished.isSelected()) {
this.jSplitPaneTables.setDividerLocation(-1);
} else {
location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, null);
if (location != null && jSplitPaneTables != null) {
jSplitPaneTables.setDividerLocation(Integer.parseInt(location));
}
}
location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, null);
if (location != null && chatPanelMain != null) {
chatPanelMain.setSplitDividerLocation(Integer.parseInt(location));
}
}
private void restoreDividers() {
Rectangle currentBounds = MageFrame.getDesktop().getBounds();
if (currentBounds != null) {
String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null);
String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null);
String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null);
GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1);
GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables);
GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain);
}
}
@ -565,7 +534,7 @@ public class TablesPanel extends javax.swing.JPanel {
MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable);
// divider locations have to be set with delay else values set are overwritten with system defaults
Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividerLocations(), 300, TimeUnit.MILLISECONDS);
Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividers(), 300, TimeUnit.MILLISECONDS);
}
@ -580,6 +549,7 @@ public class TablesPanel extends javax.swing.JPanel {
this.jPanelBottom.setVisible(false);
} else {
this.jPanelBottom.setVisible(true);
URLHandler.RemoveMouseAdapter(jLabelFooterText);
URLHandler.handleMessage(serverMessages.get(0), this.jLabelFooterText);
this.jButtonFooterNext.setVisible(serverMessages.size() > 1);
}
@ -1284,7 +1254,7 @@ public class TablesPanel extends javax.swing.JPanel {
if (currentMessage >= messages.size()) {
currentMessage = 0;
}
URLHandler.RemoveMouseAdapter(jLabelFooterText);
URLHandler.handleMessage(messages.get(currentMessage), this.jLabelFooterText);
}
@ -1447,7 +1417,7 @@ class TableTableModel extends AbstractTableModel {
if (tables[arg0].isTournament()) {
return "Show";
} else {
owner = tables[arg0].getControllerName();
owner = tables[arg0].getControllerName();
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
return "";
}

View file

@ -9,10 +9,10 @@ import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import javax.swing.JLabel;
/**
@ -47,6 +47,7 @@ public class URLHandler {
private static MouseAdapter createMouseAdapter(String url) {
currentMouseAdapter = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 0) {
if (Desktop.isDesktopSupported()) {
@ -57,7 +58,7 @@ public class URLHandler {
} catch (IOException | URISyntaxException ex) {
// do nothing
}
}
}
}
}
};

View file

@ -4,8 +4,11 @@ import java.awt.*;
import java.util.ArrayList;
import java.util.Locale;
import javax.swing.*;
import mage.client.dialog.PreferencesDialog;
import static mage.client.dialog.PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE;
import mage.client.MageFrame;
import mage.client.util.GUISizeHelper;
import mage.client.table.*;
import mage.constants.*;
import mage.view.CardView;
import mage.view.CounterView;
@ -26,6 +29,35 @@ public final class GuiDisplayUtil {
public ArrayList<String> lines;
}
public static void restoreDividerLocations(Rectangle bounds, String lastDividerLocation, JComponent component) {
String currentBounds = Double.toString(bounds.getWidth()) + 'x' + Double.toString(bounds.getHeight());
String savedBounds = PreferencesDialog.getCachedValue(KEY_MAGE_PANEL_LAST_SIZE, null);
// use divider positions only if screen size is the same as it was the time the settings were saved
if (savedBounds != null && savedBounds.equals(currentBounds)) {
if (lastDividerLocation != null && component != null) {
if (component instanceof JSplitPane) {
JSplitPane jSplitPane = (JSplitPane) component;
jSplitPane.setDividerLocation(Integer.parseInt(lastDividerLocation));
}
if (component instanceof PlayersChatPanel) {
PlayersChatPanel playerChatPanel = (PlayersChatPanel) component;
playerChatPanel.setSplitDividerLocation(Integer.parseInt(lastDividerLocation));
}
}
}
}
public static void saveCurrentBoundsToPrefs() {
Rectangle rec = MageFrame.getDesktop().getBounds();
String currentBounds = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
PreferencesDialog.saveValue(KEY_MAGE_PANEL_LAST_SIZE, currentBounds);
}
public static void saveDividerLocationToPrefs(String dividerPrefKey, int position) {
PreferencesDialog.saveValue(dividerPrefKey, Integer.toString(position));
}
public static JXPanel getDescription(CardView card, int width, int height) {
JXPanel descriptionPanel = new JXPanel();

View file

@ -5,8 +5,11 @@
*/
package mage.client.util.gui;
import java.util.Arrays;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.table.TableColumn;
import org.apache.log4j.Logger;
import mage.client.dialog.PreferencesDialog;
/**
@ -22,7 +25,32 @@ public final class TableUtil {
* @param widthPrefKey
* @param orderPrefKey
*/
static public void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) {
private static final Logger LOGGER = Logger.getLogger(TableUtil.class);
public static void saveActiveFiltersToPrefs(String filterPrefKey, JToggleButton[] buttons) {
StringBuilder currentFilters = new StringBuilder();
for (JToggleButton component : buttons) {
currentFilters.append(component.isSelected() ? "x" : "-");
}
PreferencesDialog.saveValue(filterPrefKey, currentFilters.toString());
}
public static void setActiveFilters(String filterPrefKey, JToggleButton[] buttons) {
String formatSettings = PreferencesDialog.getCachedValue(filterPrefKey, "");
int i = 0;
for (JToggleButton component : buttons) {
if (formatSettings.length() > i) {
component.setSelected(formatSettings.substring(i, i + 1).equals("x"));
} else {
component.setSelected(true);
}
i++;
}
}
public static void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// set the column width from saved value or defaults
@ -51,11 +79,11 @@ public final class TableUtil {
}
static public void saveColumnWidthAndOrderToPrefs(JTable table, String widthPrefKey, String orderPrefKey) {
// Column width
public static void saveColumnWidthAndOrderToPrefs(JTable table, String widthPrefKey, String orderPrefKey) {
StringBuilder columnWidthSettings = new StringBuilder();
StringBuilder columnOrderSettings = new StringBuilder();
boolean firstValue = true;
for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
TableColumn column = table.getColumnModel().getColumn(table.convertColumnIndexToView(i));
if (!firstValue) {
@ -67,12 +95,12 @@ public final class TableUtil {
columnWidthSettings.append(column.getWidth());
columnOrderSettings.append(table.convertColumnIndexToModel(i));
}
PreferencesDialog.saveValue(widthPrefKey, columnWidthSettings.toString());
PreferencesDialog.saveValue(orderPrefKey, columnOrderSettings.toString());
}
public static int[] getIntArrayFromString(String stringData) {
private static int[] getIntArrayFromString(String stringData) {
int[] intArray = null;
if (stringData != null && !stringData.isEmpty()) {
String[] items = stringData.split(",");

View file

@ -55,7 +55,7 @@ public class EventListenerList extends javax.swing.event.EventListenerList {
* @param listenerClass
* @return
*/
public <T extends EventListener> Iterator<T> getIterator(Class<? extends T>... listenerClass) {
public <T extends EventListener> Iterator<T> getIterator(Class<T>... listenerClass) {
return getIterable(listenerClass).iterator();
}

View file

@ -257,6 +257,7 @@ public enum MythicspoilerComSource implements CardImageSource {
supportedSets.add("UST");
supportedSets.add("RIX");
supportedSets.add("DOM");
supportedSets.add("BBD");
sets = new LinkedHashMap<>();
setsAliases = new HashMap<>();

View file

@ -210,6 +210,7 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("PPRO");
supportedSets.add("A25");
supportedSets.add("DOM");
supportedSets.add("BBD");
// supportedSets.add("M19");
}

View file

@ -97,6 +97,7 @@
|Generate|PLANE:PCA|Plane - Hedron Fields of Agadeem|||HedronFieldsOfAgadeemPlane|
|Generate|PLANE:PCA|Plane - Lethe Lake|||LetheLakePlane|
|Generate|PLANE:PCA|Plane - Naya|||NayaPlane|
|Generate|PLANE:PCA|Plane - Panopticon|||PanopticonPlane|
|Generate|PLANE:PCA|Plane - Tazeem|||TazeemPlane|
|Generate|PLANE:PCA|Plane - The Dark Barony|||TheDarkBaronyPlane|
|Generate|PLANE:PCA|Plane - The Eon Fog|||TheEonFogPlane|

View file

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

View file

@ -40,8 +40,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
*/
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 29;
public final static String MAGE_VERSION_MINOR_PATCH = "V4";
public final static int MAGE_VERSION_PATCH = 30;
public final static String MAGE_VERSION_MINOR_PATCH = "V2";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

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

View file

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

View file

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

View file

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

View file

@ -149,10 +149,12 @@ public class Brawl extends Constructed {
if (commanderColor.isGreen()) {
colorIdentity.setGreen(true);
}
if (commanderColor.isColorless()) {
colorIdentity.setColorless(true);
}
}
}
List<String> basicsInDeck = new ArrayList<>();
Set<String> basicsInDeck = new HashSet<>();
if (colorIdentity.isColorless()) {
for (Card card : deck.getCards()) {
if (basicLandNames.contains(card.getName())) {

View file

@ -33,6 +33,7 @@ import mage.abilities.Ability;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.keyword.PartnerAbility;
import mage.abilities.keyword.PartnerWithAbility;
import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
@ -133,6 +134,10 @@ public class Commander extends Constructed {
invalid.put("Commander", "Sideboard must contain only the commander(s)");
valid = false;
} else {
Set<String> commanderNames = new HashSet<>();
for (Card commander : deck.getSideboard()) {
commanderNames.add(commander.getName());
}
for (Card commander : deck.getSideboard()) {
if (bannedCommander.contains(commander.getName())) {
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
@ -144,8 +149,18 @@ public class Commander extends Constructed {
valid = false;
}
if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
boolean partnersWith = false;
for (Ability ability : commander.getAbilities()) {
if (ability instanceof PartnerWithAbility
&& commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) {
partnersWith = true;
break;
}
}
if (!partnersWith) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
}
}
FilterMana commanderColor = commander.getColorIdentity();
if (commanderColor.isWhite()) {

View file

@ -100,6 +100,7 @@ public class DuelCommander extends Commander {
bannedCommander.add("Tasigur, the Golden Fang");
bannedCommander.add("Vial Smasher the Fierce");
bannedCommander.add("Zur the Enchanter");
bannedCommander.add("Zurgo Bellstriker");
}
}

View file

@ -28,15 +28,14 @@
package mage.deck;
import java.util.*;
import java.util.Map.Entry;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.Ability;
import mage.abilities.keyword.PartnerAbility;
import mage.abilities.keyword.PartnerWithAbility;
import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
import mage.cards.decks.Constructed;
import mage.cards.decks.Deck;
import mage.constants.SetType;
import mage.filter.FilterMana;
/**
@ -90,15 +89,29 @@ public class FreeformCommander extends Constructed {
invalid.put("Commander", "Sideboard must contain only the commander(s)");
valid = false;
} else {
Set<String> commanderNames = new HashSet<>();
for (Card commander : deck.getSideboard()) {
if (!(commander.isCreature() ||
commander.isLegendary())) {
commanderNames.add(commander.getName());
}
for (Card commander : deck.getSideboard()) {
if (!(commander.isCreature()
|| commander.isLegendary())) {
invalid.put("Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName());
valid = false;
}
if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
boolean partnersWith = false;
for (Ability ability : commander.getAbilities()) {
if (ability instanceof PartnerWithAbility
&& commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) {
partnersWith = true;
break;
}
}
if (!partnersWith) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
}
}
FilterMana commanderColor = commander.getColorIdentity();
if (commanderColor.isWhite()) {

View file

@ -29,8 +29,10 @@ package mage.deck;
import java.util.*;
import java.util.Map.Entry;
import mage.abilities.Ability;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.keyword.PartnerAbility;
import mage.abilities.keyword.PartnerWithAbility;
import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
@ -98,6 +100,10 @@ public class PennyDreadfulCommander extends Constructed {
invalid.put("Commander", "Sideboard must contain only the commander(s)");
valid = false;
} else {
Set<String> commanderNames = new HashSet<>();
for (Card commander : deck.getSideboard()) {
commanderNames.add(commander.getName());
}
for (Card commander : deck.getSideboard()) {
if ((!commander.isCreature() || !commander.isLegendary())
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
@ -105,8 +111,18 @@ public class PennyDreadfulCommander extends Constructed {
valid = false;
}
if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
boolean partnersWith = false;
for (Ability ability : commander.getAbilities()) {
if (ability instanceof PartnerWithAbility
&& commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) {
partnersWith = true;
break;
}
}
if (!partnersWith) {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false;
}
}
FilterMana commanderColor = commander.getColorIdentity();
if (commanderColor.isWhite()) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,21 +20,16 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.game;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType;
import mage.players.Player;
/**
*
@ -67,22 +62,6 @@ public class FreeForAll extends GameImpl {
this.numPlayers = numPlayers;
}
@Override
public Set<UUID> getOpponents(UUID playerId) {
Set<UUID> opponents = new HashSet<>();
for (UUID opponentId: this.getPlayer(playerId).getInRange()) {
if (!opponentId.equals(playerId)) {
opponents.add(opponentId);
}
}
return opponents;
}
@Override
public boolean isOpponent(Player player, UUID playerToCheck) {
return !player.getId().equals(playerToCheck) && player.getInRange().contains(playerToCheck);
}
@Override
public FreeForAll copy() {
return new FreeForAll(this);

View file

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

View file

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

View file

@ -27,8 +27,6 @@
*/
package mage.game;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -83,22 +81,6 @@ public class MomirDuel extends GameImpl {
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
}
@Override
public Set<UUID> getOpponents(UUID playerId) {
Set<UUID> opponents = new HashSet<>();
for (UUID opponentId : this.getPlayer(playerId).getInRange()) {
if (!opponentId.equals(playerId)) {
opponents.add(opponentId);
}
}
return opponents;
}
@Override
public boolean isOpponent(Player player, UUID playerToCheck) {
return !player.getId().equals(playerToCheck);
}
@Override
public MomirDuel copy() {
return new MomirDuel(this);

View file

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

View file

@ -27,8 +27,6 @@
*/
package mage.game;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -44,13 +42,12 @@ import mage.game.match.MatchType;
import mage.game.turn.TurnMod;
import mage.players.Player;
/**
*
* @author nigelzor
*/
public class MomirGame extends GameImpl {
private int numPlayers;
public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans, int startLife) {
@ -59,8 +56,8 @@ public class MomirGame extends GameImpl {
public MomirGame(final MomirGame game) {
super(game);
}
}
@Override
public MatchType getGameType() {
return new MomirFreeForAllType();
@ -86,22 +83,6 @@ public class MomirGame extends GameImpl {
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
}
@Override
public Set<UUID> getOpponents(UUID playerId) {
Set<UUID> opponents = new HashSet<>();
for (UUID opponentId : this.getPlayer(playerId).getInRange()) {
if (!opponentId.equals(playerId)) {
opponents.add(opponentId);
}
}
return opponents;
}
@Override
public boolean isOpponent(Player player, UUID playerToCheck) {
return !player.getId().equals(playerToCheck) && player.getInRange().contains(playerToCheck);
}
@Override
public MomirGame copy() {
return new MomirGame(this);

View file

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

View file

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

View file

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

View file

@ -24,19 +24,15 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.game;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType;
import mage.game.turn.TurnMod;
import mage.players.Player;
public class TwoPlayerDuel extends GameImpl {
@ -64,22 +60,6 @@ public class TwoPlayerDuel extends GameImpl {
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
}
@Override
public Set<UUID> getOpponents(UUID playerId) {
Set<UUID> opponents = new HashSet<>();
for (UUID opponentId: this.getPlayer(playerId).getInRange()) {
if (!opponentId.equals(playerId)) {
opponents.add(opponentId);
}
}
return opponents;
}
@Override
public boolean isOpponent(Player player, UUID playerToCheck) {
return !player.getId().equals(playerToCheck);
}
@Override
public TwoPlayerDuel copy() {
return new TwoPlayerDuel(this);

View file

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

View file

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

View file

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

View file

@ -31,7 +31,9 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import mage.ConditionalMana;
import mage.MageObject;
import mage.MageObjectReference;
import mage.Mana;
import mage.abilities.*;
import mage.abilities.costs.VariableCost;
@ -1026,7 +1028,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
findPlayables(game);
if (!playableAbilities.isEmpty()) {
for (ActivatedAbility ability : playableAbilities) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
if (ability.getEffects().hasOutcome(Outcome.PutLandInPlay)) {
if (this.activateAbility(ability, game)) {
return true;
@ -1057,7 +1059,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (game.getStack().isEmpty()) {
if (!playableNonInstant.isEmpty()) {
for (Card card : playableNonInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
if (this.activateAbility(card.getSpellAbility(), game)) {
return true;
}
@ -1066,7 +1068,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (!playableAbilities.isEmpty()) {
for (ActivatedAbility ability : playableAbilities) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
if (!(ability.getEffects().get(0) instanceof BecomesCreatureSourceEffect)) {
if (this.activateAbility(ability, game)) {
return true;
@ -1186,7 +1188,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (Mana avail : available) {
if (mana.enough(avail)) {
SpellAbility ability = card.getSpellAbility();
if (ability != null && ability.canActivate(playerId, game)
if (ability != null && ability.canActivate(playerId, game).canActivate()
&& game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
if (card.getCardType().contains(CardType.INSTANT)
|| card.hasAbility(FlashAbility.getInstance().getId(), game)) {
@ -1203,7 +1205,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game).canActivate()) {
if (ability instanceof EquipAbility && permanent.getAttachedTo() != null) {
continue;
}
@ -1230,7 +1232,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
for (Card card : graveyard.getCards(game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.GRAVEYARD)) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
ManaOptions abilityOptions = ability.getManaCosts().getOptions();
if (abilityOptions.isEmpty()) {
playableAbilities.add(ability);
@ -1261,9 +1263,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
return result;
}
protected boolean playManaHandling(Ability ability, ManaCost unpaid, Game game) {
protected boolean playManaHandling(Ability ability, ManaCost unpaid, final Game game) {
// log.info("paying for " + unpaid.getText());
UUID spendAnyManaId = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
MageObjectReference permittingObject = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
ManaCost cost;
List<MageObject> producers;
if (unpaid instanceof ManaCosts) {
@ -1279,7 +1281,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
// use color producing mana abilities with costs first that produce all color manas that are needed to pay
// otherwise the computer may not be able to pay the cost for that source
ManaAbility:
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
int colored = 0;
for (Mana mana : manaAbility.getNetMana(game)) {
if (!unpaid.getMana().includesMana(mana)) {
@ -1288,9 +1290,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
colored += mana.countColored();
}
if (colored > 1 && (cost instanceof ColoredManaCost)) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana)) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1302,10 +1306,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (MageObject mageObject : producers) {
// pay all colored costs first
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof ColoredManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1314,10 +1321,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// pay snow covered mana
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof SnowManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1326,10 +1336,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// then pay hybrid
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof HybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1338,10 +1351,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// then pay mono hybrid
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof MonoHybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1350,10 +1366,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// pay colorless
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof ColorlessManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1362,10 +1381,13 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
}
// finally pay generic
for (ActivatedManaAbilityImpl manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof GenericManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
if (activateAbility(manaAbility, game)) {
return true;
}
@ -1376,13 +1398,39 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
// pay phyrexian life costs
if (cost instanceof PhyrexianManaCost) {
if (cost.pay(null, game, null, playerId, false, null) || spendAnyManaId != null) {
if (cost.pay(null, game, null, playerId, false, null) || permittingObject != null) {
return true;
}
}
return false;
}
private Abilities<ActivatedManaAbilityImpl> getManaAbilitiesSortedByManaCount(MageObject mageObject, final Game game) {
Abilities<ActivatedManaAbilityImpl> manaAbilities = mageObject.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game);
if (manaAbilities.size() > 1) {
// Sort mana abilities by numbver of produced manas, to use ability first that produces most mana (maybe also conditional if possible)
Collections.sort(manaAbilities, new Comparator<ActivatedManaAbilityImpl>() {
@Override
public int compare(ActivatedManaAbilityImpl a1, ActivatedManaAbilityImpl a2) {
int a1Max = 0;
for (Mana netMana : a1.getNetMana(game)) {
if (netMana.count() > a1Max) {
a1Max = netMana.count();
}
}
int a2Max = 0;
for (Mana netMana : a2.getNetMana(game)) {
if (netMana.count() > a2Max) {
a2Max = netMana.count();
}
}
return a2Max - a1Max;
}
});
}
return manaAbilities;
}
/**
*
* returns a list of Permanents that produce mana sorted by the number of
@ -2339,7 +2387,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
private void playRemoval(List<UUID> creatures, Game game) {
for (UUID creatureId : creatures) {
for (Card card : this.playableInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
for (Effect effect : card.getSpellAbility().getEffects()) {
if (effect.getOutcome() == Outcome.DestroyPermanent || effect.getOutcome() == Outcome.ReturnToHand) {
if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) {
@ -2358,7 +2406,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (UUID creatureId : creatures) {
Permanent creature = game.getPermanent(creatureId);
for (Card card : this.playableInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
for (Effect effect : card.getSpellAbility().getEffects()) {
if (effect instanceof DamageTargetEffect) {
if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) {

View file

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

View file

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

View file

@ -25,17 +25,16 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.player.ai;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.abilities.ActivatedAbility;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.BoostCounter;
import mage.counters.Counter;
import mage.counters.CounterType;
@ -71,18 +70,20 @@ public final class GameStateEvaluator {
Player player = game.getPlayer(playerId);
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
if (game.checkIfGameIsOver()) {
if (player.hasLost() || opponent.hasWon())
if (player.hasLost() || opponent.hasWon()) {
return LOSE_SCORE;
if (opponent.hasLost() || player.hasWon())
}
if (opponent.hasLost() || player.hasWon()) {
return WIN_SCORE;
}
}
int lifeScore = (player.getLife() - opponent.getLife()) * LIFE_FACTOR;
int poisonScore = (opponent.getCounters().getCount(CounterType.POISON) - player.getCounters().getCount(CounterType.POISON)) * LIFE_FACTOR * 2;
int permanentScore = 0;
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
permanentScore += evaluatePermanent(permanent, game, ignoreTapped);
}
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(opponent.getId())) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponent.getId())) {
permanentScore -= evaluatePermanent(permanent, game, ignoreTapped);
}
permanentScore *= PERMANENT_FACTOR;
@ -92,26 +93,29 @@ public final class GameStateEvaluator {
handScore *= HAND_FACTOR;
int score = lifeScore + poisonScore + permanentScore + handScore;
if (logger.isDebugEnabled())
if (logger.isDebugEnabled()) {
logger.debug("game state for player " + player.getName() + " evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score);
}
return score;
}
public static int evaluatePermanent(Permanent permanent, Game game, boolean ignoreTapped) {
int value = 0;
if (ignoreTapped)
if (ignoreTapped) {
value = 5;
else
value = permanent.isTapped()?4:5;
} else {
value = permanent.isTapped() ? 4 : 5;
}
if (permanent.getCardType().contains(CardType.CREATURE)) {
value += evaluateCreature(permanent, game) * CREATURE_FACTOR;
}
value += permanent.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD).size();
for (ActivatedAbility ability: permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game))
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game).canActivate()) {
value += ability.getEffects().size();
}
}
for (Counter counter: permanent.getCounters(game).values()) {
for (Counter counter : permanent.getCounters(game).values()) {
if (!(counter instanceof BoostCounter)) {
value += counter.getCount();
}
@ -133,9 +137,9 @@ public final class GameStateEvaluator {
// value += 2;
value += creature.getAbilities().getEvasionAbilities().size();
value += creature.getAbilities().getProtectionAbilities().size();
value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0;
value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0;
value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0;
value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0;
value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0;
value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0;
return value;
}

View file

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

View file

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

View file

@ -37,15 +37,15 @@ public class AdamStyborskisPauperCube extends DraftCube {
public AdamStyborskisPauperCube() {
super("Adam Styborkski's Pauper Cube"); // https://docs.google.com/spreadsheets/d/12iQhC4bHqFW7hEWxPBjyC8yBDehFZ0_4DkqzyA8EL3o/edit#gid=0
// last updated with Hour of Devastation, Iconic Masters and Ixalan 10/18/17
// last updated with Dominaria 5/1/18
cubeCards.add(new CardIdentity("Academy Journeymage", ""));
cubeCards.add(new CardIdentity("Act of Treason", ""));
cubeCards.add(new CardIdentity("Adventuring Gear", ""));
cubeCards.add(new CardIdentity("Aerie Bowmasters", ""));
cubeCards.add(new CardIdentity("Aerie Ouphes", ""));
cubeCards.add(new CardIdentity("Aether Adept", ""));
cubeCards.add(new CardIdentity("Aethersnipe", ""));
cubeCards.add(new CardIdentity("Agony Warp", ""));
cubeCards.add(new CardIdentity("Aim High", ""));
cubeCards.add(new CardIdentity("Ambuscade", ""));
cubeCards.add(new CardIdentity("Ambush Viper", ""));
cubeCards.add(new CardIdentity("Angelic Purge", ""));
cubeCards.add(new CardIdentity("Arachnus Web", ""));
@ -61,7 +61,7 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Aven Riftwatcher", ""));
cubeCards.add(new CardIdentity("Aven Surveyor", ""));
cubeCards.add(new CardIdentity("Azorius Guildgate", ""));
cubeCards.add(new CardIdentity("Baleful Eidolon", ""));
cubeCards.add(new CardIdentity("Baloth Gorger", ""));
cubeCards.add(new CardIdentity("Barbed Lightning", ""));
cubeCards.add(new CardIdentity("Basking Rootwalla", ""));
cubeCards.add(new CardIdentity("Battle Screech", ""));
@ -72,33 +72,31 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Blazing Torch", ""));
cubeCards.add(new CardIdentity("Blightning", ""));
cubeCards.add(new CardIdentity("Blinding Beam", ""));
cubeCards.add(new CardIdentity("Blink of an Eye", ""));
cubeCards.add(new CardIdentity("Bloodfell Caves", ""));
cubeCards.add(new CardIdentity("Blossoming Sands", ""));
cubeCards.add(new CardIdentity("Bonded Construct", ""));
cubeCards.add(new CardIdentity("Bonds of Faith", ""));
cubeCards.add(new CardIdentity("Bonesplitter", ""));
cubeCards.add(new CardIdentity("Borderland Marauder", ""));
cubeCards.add(new CardIdentity("Boros Guildgate", ""));
cubeCards.add(new CardIdentity("Borrowed Grace", ""));
cubeCards.add(new CardIdentity("Branching Bolt", ""));
cubeCards.add(new CardIdentity("Brazen Buccaneers", ""));
cubeCards.add(new CardIdentity("Brazen Wolves", ""));
cubeCards.add(new CardIdentity("Burning-Tree Emissary", ""));
cubeCards.add(new CardIdentity("Burst Lightning", ""));
cubeCards.add(new CardIdentity("Butcher Ghoul", ""));
cubeCards.add(new CardIdentity("Byway Courier", ""));
cubeCards.add(new CardIdentity("Cage of Hands", ""));
cubeCards.add(new CardIdentity("Calcite Snapper", ""));
cubeCards.add(new CardIdentity("Call of the Conclave", ""));
cubeCards.add(new CardIdentity("Call the Cavalry", ""));
cubeCards.add(new CardIdentity("Capsize", ""));
cubeCards.add(new CardIdentity("Carnivorous Death-Parrot", ""));
cubeCards.add(new CardIdentity("Cartouche of Strength", ""));
cubeCards.add(new CardIdentity("Cathodion", ""));
cubeCards.add(new CardIdentity("Cavern Harpy", ""));
cubeCards.add(new CardIdentity("Centaur Healer", ""));
cubeCards.add(new CardIdentity("Chain Lightning", ""));
cubeCards.add(new CardIdentity("Chainer's Edict", ""));
cubeCards.add(new CardIdentity("Chatter of the Squirrel", ""));
cubeCards.add(new CardIdentity("Chivalrous Chevalier", ""));
cubeCards.add(new CardIdentity("Cinder Barrens", ""));
cubeCards.add(new CardIdentity("Citanul Woodreaders", ""));
cubeCards.add(new CardIdentity("Claustrophobia", ""));
@ -108,13 +106,14 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Coalition Honor Guard", ""));
cubeCards.add(new CardIdentity("Cogwork Librarian", ""));
cubeCards.add(new CardIdentity("Colossal Might", ""));
cubeCards.add(new CardIdentity("Common Iguana", ""));
cubeCards.add(new CardIdentity("Compulsive Research", ""));
cubeCards.add(new CardIdentity("Compulsory Rest", ""));
cubeCards.add(new CardIdentity("Consume Strength", ""));
cubeCards.add(new CardIdentity("Corrupted Zendikon", ""));
cubeCards.add(new CardIdentity("Counterspell", ""));
cubeCards.add(new CardIdentity("Court Hussar", ""));
cubeCards.add(new CardIdentity("Crippling Fatigue", ""));
cubeCards.add(new CardIdentity("Crow of Dark Tidings", ""));
cubeCards.add(new CardIdentity("Crypt Rats", ""));
cubeCards.add(new CardIdentity("Crystallization", ""));
cubeCards.add(new CardIdentity("Cunning Strike", ""));
@ -126,24 +125,23 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Dead Weight", ""));
cubeCards.add(new CardIdentity("Deadeye Tormentor", ""));
cubeCards.add(new CardIdentity("Death Denied", ""));
cubeCards.add(new CardIdentity("Deathbloom Thallid", ""));
cubeCards.add(new CardIdentity("Deep Analysis", ""));
cubeCards.add(new CardIdentity("Deprive", ""));
cubeCards.add(new CardIdentity("Depths of Desire", ""));
cubeCards.add(new CardIdentity("Deputy of Acquittals", ""));
cubeCards.add(new CardIdentity("Desert", ""));
cubeCards.add(new CardIdentity("Desperate Sentry", ""));
cubeCards.add(new CardIdentity("Devour Flesh", ""));
cubeCards.add(new CardIdentity("Diabolic Edict", ""));
cubeCards.add(new CardIdentity("Dimir Guildgate", ""));
cubeCards.add(new CardIdentity("Dinrova Horror", ""));
cubeCards.add(new CardIdentity("Dire Fleet Hoarder", ""));
cubeCards.add(new CardIdentity("Disfigure", ""));
cubeCards.add(new CardIdentity("Dismal Backwater", ""));
cubeCards.add(new CardIdentity("Disowned Ancestor", ""));
cubeCards.add(new CardIdentity("Doom Blade", ""));
cubeCards.add(new CardIdentity("Doomed Traveler", ""));
cubeCards.add(new CardIdentity("Drag Under", ""));
cubeCards.add(new CardIdentity("Dragon Fodder", ""));
cubeCards.add(new CardIdentity("Dusk Legion Zealot", ""));
cubeCards.add(new CardIdentity("Dynacharge", ""));
cubeCards.add(new CardIdentity("Eager Construct", ""));
cubeCards.add(new CardIdentity("Eldrazi Devastator", ""));
@ -154,12 +152,13 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Emperor Crocodile", ""));
cubeCards.add(new CardIdentity("Epic Confrontation", ""));
cubeCards.add(new CardIdentity("Errant Ephemeron", ""));
cubeCards.add(new CardIdentity("Esper Cormorants", ""));
cubeCards.add(new CardIdentity("Evincar's Justice", ""));
cubeCards.add(new CardIdentity("Evolving Wilds", ""));
cubeCards.add(new CardIdentity("Extremely Slow Zombie (C)", ""));
cubeCards.add(new CardIdentity("Faceless Butcher", ""));
cubeCards.add(new CardIdentity("Faith's Fetters", ""));
cubeCards.add(new CardIdentity("Falkenrath Noble", ""));
cubeCards.add(new CardIdentity("Fanatical Firebrand", ""));
cubeCards.add(new CardIdentity("Feeling of Dread", ""));
cubeCards.add(new CardIdentity("Fervent Cathar", ""));
cubeCards.add(new CardIdentity("Firebolt", ""));
@ -170,25 +169,27 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Forsaken Sanctuary", ""));
cubeCards.add(new CardIdentity("Fortify", ""));
cubeCards.add(new CardIdentity("Foul Orchard", ""));
cubeCards.add(new CardIdentity("Frenzied Goblin", ""));
cubeCards.add(new CardIdentity("Frilled Deathspitter", ""));
cubeCards.add(new CardIdentity("Frilled Oculus", ""));
cubeCards.add(new CardIdentity("Frostburn Weird", ""));
cubeCards.add(new CardIdentity("Fungal Infection", ""));
cubeCards.add(new CardIdentity("GO TO JAIL", ""));
cubeCards.add(new CardIdentity("Gathan Raiders", ""));
cubeCards.add(new CardIdentity("Gather the Townsfolk", ""));
cubeCards.add(new CardIdentity("Ghastly Demise", ""));
cubeCards.add(new CardIdentity("Ghirapur Gearcrafter", ""));
cubeCards.add(new CardIdentity("Ghitu Slinger", ""));
cubeCards.add(new CardIdentity("Giant Growth", ""));
cubeCards.add(new CardIdentity("Gideon's Lawkeeper", ""));
cubeCards.add(new CardIdentity("Glint-Sleeve Artisan", ""));
cubeCards.add(new CardIdentity("Gnawing Zombie", ""));
cubeCards.add(new CardIdentity("Goblin Freerunner", ""));
cubeCards.add(new CardIdentity("Goblin Heelcutter", ""));
cubeCards.add(new CardIdentity("Goblin Trailblazer", ""));
cubeCards.add(new CardIdentity("Gods Willing", ""));
cubeCards.add(new CardIdentity("Goldmeadow Harrier", ""));
cubeCards.add(new CardIdentity("Golgari Guildgate", ""));
cubeCards.add(new CardIdentity("Gravedigger", ""));
cubeCards.add(new CardIdentity("Gray Merchant of Asphodel", ""));
cubeCards.add(new CardIdentity("Grazing Whiptail", ""));
cubeCards.add(new CardIdentity("Grim Contest", ""));
cubeCards.add(new CardIdentity("Grisly Salvage", ""));
cubeCards.add(new CardIdentity("Grixis Slavedriver", ""));
@ -204,9 +205,8 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Highland Lake", ""));
cubeCards.add(new CardIdentity("Hissing Iguanar", ""));
cubeCards.add(new CardIdentity("Hooting Mandrills", ""));
cubeCards.add(new CardIdentity("Humble", ""));
cubeCards.add(new CardIdentity("Hordeling Outburst", ""));
cubeCards.add(new CardIdentity("Imperiosaur", ""));
cubeCards.add(new CardIdentity("Incinerate", ""));
cubeCards.add(new CardIdentity("Inner-Flame Acolyte", ""));
cubeCards.add(new CardIdentity("Insolent Neonate", ""));
cubeCards.add(new CardIdentity("Into the Roil", ""));
@ -214,17 +214,20 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Ivy Elemental", ""));
cubeCards.add(new CardIdentity("Izzet Chronarch", ""));
cubeCards.add(new CardIdentity("Izzet Guildgate", ""));
cubeCards.add(new CardIdentity("Jackal Pup", ""));
cubeCards.add(new CardIdentity("Jilt", ""));
cubeCards.add(new CardIdentity("Journey to Nowhere", ""));
cubeCards.add(new CardIdentity("Jungle Hollow", ""));
cubeCards.add(new CardIdentity("Kabuto Moth", ""));
cubeCards.add(new CardIdentity("Jungleborn Pioneer", ""));
cubeCards.add(new CardIdentity("Keldon Marauders", ""));
cubeCards.add(new CardIdentity("Keldon Overseer", ""));
cubeCards.add(new CardIdentity("Keldon Raider", ""));
cubeCards.add(new CardIdentity("Kingpin's Pet", ""));
cubeCards.add(new CardIdentity("Kitesail Corsair", ""));
cubeCards.add(new CardIdentity("Kor Skyfisher", ""));
cubeCards.add(new CardIdentity("Kozilek's Channeler", ""));
cubeCards.add(new CardIdentity("Krenko's Command", ""));
cubeCards.add(new CardIdentity("Krosan Tusker", ""));
cubeCards.add(new CardIdentity("Kruin Striker", ""));
cubeCards.add(new CardIdentity("Lash Out", ""));
cubeCards.add(new CardIdentity("Last Gasp", ""));
cubeCards.add(new CardIdentity("Leave in the Dust", ""));
@ -232,16 +235,15 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Lifecraft Cavalry", ""));
cubeCards.add(new CardIdentity("Lightning Bolt", ""));
cubeCards.add(new CardIdentity("Liliana's Specter", ""));
cubeCards.add(new CardIdentity("Lotus Path Djinn", ""));
cubeCards.add(new CardIdentity("Loyal Pegasus", ""));
cubeCards.add(new CardIdentity("Lurking Automaton", ""));
cubeCards.add(new CardIdentity("Magma Jet", ""));
cubeCards.add(new CardIdentity("Makeshift Mauler", ""));
cubeCards.add(new CardIdentity("Man-o'-War", ""));
cubeCards.add(new CardIdentity("Mana Leak", ""));
cubeCards.add(new CardIdentity("Manticore of the Gauntlet", ""));
cubeCards.add(new CardIdentity("Mardu Hordechief", ""));
cubeCards.add(new CardIdentity("Mardu Skullhunter", ""));
cubeCards.add(new CardIdentity("Martyr of Dusk", ""));
cubeCards.add(new CardIdentity("Maul Splicer", ""));
cubeCards.add(new CardIdentity("Maze of Ith", ""));
cubeCards.add(new CardIdentity("Meandering River", ""));
@ -263,7 +265,6 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Mulldrifter", ""));
cubeCards.add(new CardIdentity("Nameless Inversion", ""));
cubeCards.add(new CardIdentity("Narcolepsy", ""));
cubeCards.add(new CardIdentity("Necromancer's Assistant", ""));
cubeCards.add(new CardIdentity("Nessian Asp", ""));
cubeCards.add(new CardIdentity("Nest Robber", ""));
cubeCards.add(new CardIdentity("Nezumi Cutthroat", ""));
@ -272,25 +273,22 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Ninja of the Deep Hours", ""));
cubeCards.add(new CardIdentity("Oblivion Ring", ""));
cubeCards.add(new CardIdentity("Oona's Grace", ""));
cubeCards.add(new CardIdentity("Ordinary Pony", ""));
cubeCards.add(new CardIdentity("Orzhov Guildgate", ""));
cubeCards.add(new CardIdentity("Otherworldly Journey", ""));
cubeCards.add(new CardIdentity("Overgrown Armasaur", ""));
cubeCards.add(new CardIdentity("Pacifism", ""));
cubeCards.add(new CardIdentity("Paladin of the Bloodstained", ""));
cubeCards.add(new CardIdentity("Peema Outrider", ""));
cubeCards.add(new CardIdentity("Penumbra Spider", ""));
cubeCards.add(new CardIdentity("Peregrine Drake", ""));
cubeCards.add(new CardIdentity("Perilous Myr", ""));
cubeCards.add(new CardIdentity("Pestermite", ""));
cubeCards.add(new CardIdentity("Pestilence", ""));
cubeCards.add(new CardIdentity("Phantom Nomad", ""));
cubeCards.add(new CardIdentity("Phantom Tiger", ""));
cubeCards.add(new CardIdentity("Pharika's Chosen", ""));
cubeCards.add(new CardIdentity("Phyrexian Rager", ""));
cubeCards.add(new CardIdentity("Pillory of the Sleepless", ""));
cubeCards.add(new CardIdentity("Pit Fight", ""));
cubeCards.add(new CardIdentity("Pit Keeper", ""));
cubeCards.add(new CardIdentity("Plated Geopede", ""));
cubeCards.add(new CardIdentity("Plover Knights", ""));
cubeCards.add(new CardIdentity("Porcelain Legionnaire", ""));
cubeCards.add(new CardIdentity("Pounce", ""));
cubeCards.add(new CardIdentity("Predatory Nightstalker", ""));
@ -321,16 +319,18 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Renegade Freighter", ""));
cubeCards.add(new CardIdentity("Rift Bolt", ""));
cubeCards.add(new CardIdentity("Rishadan Airship", ""));
cubeCards.add(new CardIdentity("Ronin Houndmaster", ""));
cubeCards.add(new CardIdentity("Rugged Highlands", ""));
cubeCards.add(new CardIdentity("Runed Servitor", ""));
cubeCards.add(new CardIdentity("Rushing River", ""));
cubeCards.add(new CardIdentity("Ruthless Ripper", ""));
cubeCards.add(new CardIdentity("Sailor of Means", ""));
cubeCards.add(new CardIdentity("Sakura-Tribe Elder", ""));
cubeCards.add(new CardIdentity("Sandsteppe Outcast", ""));
cubeCards.add(new CardIdentity("Sangrite Backlash", ""));
cubeCards.add(new CardIdentity("Saproling Migration", ""));
cubeCards.add(new CardIdentity("Sarkhan's Rage", ""));
cubeCards.add(new CardIdentity("Savage Punch", ""));
cubeCards.add(new CardIdentity("Savannah Lions", ""));
cubeCards.add(new CardIdentity("Scatter the Seeds", ""));
cubeCards.add(new CardIdentity("Scion Summoner", ""));
cubeCards.add(new CardIdentity("Scion of the Wild", ""));
@ -343,9 +343,10 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Seeker of Insight", ""));
cubeCards.add(new CardIdentity("Seeker of the Way", ""));
cubeCards.add(new CardIdentity("Selesnya Guildgate", ""));
cubeCards.add(new CardIdentity("Sentinel Spider", ""));
cubeCards.add(new CardIdentity("Selfie Preservation", ""));
cubeCards.add(new CardIdentity("Separatist Voidmage", ""));
cubeCards.add(new CardIdentity("Seraph of Dawn", ""));
cubeCards.add(new CardIdentity("Sergeant-at-Arms", ""));
cubeCards.add(new CardIdentity("Serrated Arrows", ""));
cubeCards.add(new CardIdentity("Shaper Parasite", ""));
cubeCards.add(new CardIdentity("Sheer Drop", ""));
@ -360,11 +361,12 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Snakeform", ""));
cubeCards.add(new CardIdentity("Snap", ""));
cubeCards.add(new CardIdentity("Soul Manipulation", ""));
cubeCards.add(new CardIdentity("Soul of the Rapids", ""));
cubeCards.add(new CardIdentity("Soulstinger", ""));
cubeCards.add(new CardIdentity("Sparring Construct", ""));
cubeCards.add(new CardIdentity("Sphere of the Suns", ""));
cubeCards.add(new CardIdentity("Spike Jester", ""));
cubeCards.add(new CardIdentity("Spined Thopter", ""));
cubeCards.add(new CardIdentity("Splatter Thug", ""));
cubeCards.add(new CardIdentity("Squirrel Dealer", ""));
cubeCards.add(new CardIdentity("Staggershock", ""));
cubeCards.add(new CardIdentity("Star Compass", ""));
cubeCards.add(new CardIdentity("Stitched Drake", ""));
@ -372,20 +374,19 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Storm Fleet Pyromancer", ""));
cubeCards.add(new CardIdentity("Stormfront Pegasus", ""));
cubeCards.add(new CardIdentity("Stormscape Apprentice", ""));
cubeCards.add(new CardIdentity("Strip Mine", ""));
cubeCards.add(new CardIdentity("Strip Min", ""));
cubeCards.add(new CardIdentity("Striped Riverwinder", ""));
cubeCards.add(new CardIdentity("Stronghold Confessor", ""));
cubeCards.add(new CardIdentity("Submerged Boneyard", ""));
cubeCards.add(new CardIdentity("Sultai Scavenger", ""));
cubeCards.add(new CardIdentity("Suppression Bonds", ""));
cubeCards.add(new CardIdentity("Swiftwater Cliffs", ""));
cubeCards.add(new CardIdentity("Sylvan Might", ""));
cubeCards.add(new CardIdentity("Sylvok Lifestaff", ""));
cubeCards.add(new CardIdentity("Tah-Crop Elite", ""));
cubeCards.add(new CardIdentity("Temporal Isolation", ""));
cubeCards.add(new CardIdentity("Tenement Crasher", ""));
cubeCards.add(new CardIdentity("Terminate", ""));
cubeCards.add(new CardIdentity("Terramorphic Expanse", ""));
cubeCards.add(new CardIdentity("Test of Faith", ""));
cubeCards.add(new CardIdentity("Thorn of the Black Rose", ""));
cubeCards.add(new CardIdentity("Thornweald Archer", ""));
cubeCards.add(new CardIdentity("Thornwood Falls", ""));
@ -393,7 +394,6 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Thraben Inspector", ""));
cubeCards.add(new CardIdentity("Thrill-Kill Assassin", ""));
cubeCards.add(new CardIdentity("Thundering Giant", ""));
cubeCards.add(new CardIdentity("Thundering Tanadon", ""));
cubeCards.add(new CardIdentity("Thunderous Wrath", ""));
cubeCards.add(new CardIdentity("Timber Gorge", ""));
cubeCards.add(new CardIdentity("Time to Feed", ""));
@ -408,7 +408,6 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Typhoid Rats", ""));
cubeCards.add(new CardIdentity("Ulamog's Crusher", ""));
cubeCards.add(new CardIdentity("Ulvenwald Captive", ""));
cubeCards.add(new CardIdentity("Undying Rage", ""));
cubeCards.add(new CardIdentity("Unearth", ""));
cubeCards.add(new CardIdentity("Unmake", ""));
cubeCards.add(new CardIdentity("Vampire Interloper", ""));
@ -427,6 +426,7 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Warped Landscape", ""));
cubeCards.add(new CardIdentity("Warren Pilferers", ""));
cubeCards.add(new CardIdentity("Wasteland Scorpion", ""));
cubeCards.add(new CardIdentity("Waterknot", ""));
cubeCards.add(new CardIdentity("Wayfarer's Bauble", ""));
cubeCards.add(new CardIdentity("Werebear", ""));
cubeCards.add(new CardIdentity("Whitemane Lion", ""));
@ -436,13 +436,13 @@ public class AdamStyborskisPauperCube extends DraftCube {
cubeCards.add(new CardIdentity("Wildsize", ""));
cubeCards.add(new CardIdentity("Will-Forged Golem", ""));
cubeCards.add(new CardIdentity("Wind-Scarred Crag", ""));
cubeCards.add(new CardIdentity("Winds of Rebuke", ""));
cubeCards.add(new CardIdentity("Winged Coatl", ""));
cubeCards.add(new CardIdentity("Wojek Halberdiers", ""));
cubeCards.add(new CardIdentity("Woodland Stream", ""));
cubeCards.add(new CardIdentity("Wrecking Ball", ""));
cubeCards.add(new CardIdentity("Wretched Gryff", ""));
cubeCards.add(new CardIdentity("Yavimaya Elder", ""));
cubeCards.add(new CardIdentity("Yavimaya Sapherd", ""));
cubeCards.add(new CardIdentity("Yotian Soldier", ""));
}
}

View file

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

View file

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

View file

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

View file

@ -1,187 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Config.xsd">
<!--
Official guide to setup public server and NAT: https://www.slightlymagic.net/forum/viewtopic.php?f=70&t=15898
serverAddress - ip or domain of the XMage server. Set it to "0.0.0.0" for local host or to the IP the server should use
Public server should be accessable to all clients by it's name (example: xmage.mydomain.com)
port - the port the primary server socket is bound to
secondaryBindPort - the port to which the secondary server socket is to be bound. if "-1" is set , an arbitrary port is selected.
backlogSize - the preferred number of unaccepted incoming connections allowed at a given time. The actual number may be greater
than the specified backlog. When the queue is full, further connection requests are rejected. The JBoss default value is 200
numAcceptThreads - the number of threads listening on the ServerSocket. The JBoss default value is 1
maxPoolSize - the maximum number of ServerThreads that can exist at any given time. The JBoss default value is 300
leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria.
The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds.
The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method
socketWriteTimeout - All write operations will time out if they do not complete within the configured period.
maxGameThreads - Number of games that can be started simultanously on the server
maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time
minUserNameLength - minmal allowed length of a user name to connect to the server
maxUserNameLength - maximal allowed length of a user name to connect to the server
userNamePattern - pattern for user name validity check
maxAiOpponents - number of allowed AI opponents on the server
saveGameActivated - allow game save and replay options (not working correctly yet)
authenticationActivated - "true" = user have to register to signon "false" = user need not to register
* mail configs only needed if authentication is activated:
* if mailUser = "" mailgun is used otherwise nativ mail server on the system
googleAccount - not supported currently
mailgunApiKey - key from the mailgun domain e.g. = "key-12121111..."
mailgunDomain - domain for the mailgun message sending
mailSmtpHost - hostname to send the mail
mailSmtpPort - port to send the mail
mailUser - username used to send the mail
mailPassword - passworf of the used user to send the mail
mailFromAddress - sender address
-->
<server serverAddress="0.0.0.0"
serverName="mage-server"
port="17171"
secondaryBindPort="17179"
backlogSize="200"
numAcceptThreads="2"
maxPoolSize="300"
leasePeriod="5000"
socketWriteTimeout="10000"
maxGameThreads="10"
maxSecondsIdle="300"
minUserNameLength="3"
maxUserNameLength="14"
invalidUserNamePattern="[^a-z0-9_]"
minPasswordLength="8"
maxPasswordLength="100"
maxAiOpponents="15"
saveGameActivated="false"
authenticationActivated="false"
googleAccount=""
mailgunApiKey="key-d93e81f19a9c9ed243ebb7cc9381385c"
mailgunDomain="sandbox401a433f30d445309a5e86b6c53f7812.mailgun.org"
mailSmtpHost="smtp.1und1.de"
mailSmtpPort="465"
mailUser="xmageserver@online.de"
mailPassword="24wrsfxv"
mailFromAddress="xmageserver@online.de"
/>
<playerTypes>
<playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/>
<!--<playerType name="Computer - minimax" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>-->
<playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer7"/>
<!--<playerType name="Computer - monte carlo" jar="mage-player-aimcts.jar" className="mage.player.ai.ComputerPlayerMCTS"/>-->
<playerType name="Computer - draftbot" jar="mage-player-ai-draft-bot.jar" className="mage.player.ai.ComputerDraftPlayer"/>
</playerTypes>
<gameTypes>
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
<gameType name="Commander Two Player Duel" jar="mage-game-commanderduel.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/>
<gameType name="Commander Free For All" jar="mage-game-commanderfreeforall.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/>
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
<gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/>
<gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>
<gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/>
<gameType name="Momir Basic Two Player Duel" jar="mage-game-momirduel.jar" className="mage.game.MomirDuelMatch" typeName="mage.game.MomirDuelType"/>
<gameType name="Momir Basic Free For All" jar="mage-game-momir.jar" className="mage.game.MomirFreeForAllMatch" typeName="mage.game.MomirFreeForAllType"/>
</gameTypes>
<tournamentTypes>
<tournamentType name="Constructed Elimination" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/>
<tournamentType name="Constructed Swiss" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/>
<tournamentType name="Booster Draft Elimination" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
<tournamentType name="Sealed Swiss (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissCubeTournamentType"/>
</tournamentTypes>
<draftCubes>
<draftCube name="Adam Styborski's Pauper Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.AdamStyborskisPauperCube"/>
<draftCube name="Ben's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.BensCube"/>
<draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/>
<draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor720"/>
<draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/>
<draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/>
<draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JimDavisCube"/>
<draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/>
<draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MonoBlueCube"/>
<draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.SamBlacksCube"/>
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/>
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/>
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/>
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2016"/>
<draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2016"/>
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/>
</draftCubes>
<deckTypes>
<deckType name="Constructed - Standard" jar="mage-deck-constructed.jar" className="mage.deck.Standard"/>
<deckType name="Constructed - Extended" jar="mage-deck-constructed.jar" className="mage.deck.Extended"/>
<deckType name="Constructed - Frontier" jar="mage-deck-constructed.jar" className="mage.deck.Frontier"/>
<deckType name="Constructed - Modern" jar="mage-deck-constructed.jar" className="mage.deck.Modern"/>
<deckType name="Constructed - Modern - No Banned List" jar="mage-deck-constructed.jar" className="mage.deck.ModernNoBannedList"/>
<deckType name="Constructed - Eternal" jar="mage-deck-constructed.jar" className="mage.deck.Eternal"/>
<deckType name="Constructed - Legacy" jar="mage-deck-constructed.jar" className="mage.deck.Legacy"/>
<deckType name="Constructed - Vintage" jar="mage-deck-constructed.jar" className="mage.deck.Vintage"/>
<deckType name="Constructed - Pauper" jar="mage-deck-constructed.jar" className="mage.deck.Pauper"/>
<deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed.jar" className="mage.deck.HistoricalType2"/>
<deckType name="Constructed - Super Type 2" jar="mage-deck-constructed.jar" className="mage.deck.SuperType2"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/>
<deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394"/>
<deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394Italian"/>
<deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/>
<deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/>
<deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/>
<deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.AusHighlander"/>
<deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.CanadianHighlander"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/>
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/>
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/>
<deckType name="Variant Magic - MTGO 1v1 Commander" jar="mage-deck-constructed.jar" className="mage.deck.MTGO1v1Commander"/>
<deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed.jar" className="mage.deck.TinyLeaders"/>
<deckType name="Variant Magic - Momir Basic" jar="mage-deck-constructed.jar" className="mage.deck.Momir"/>
<deckType name="Variant Magic - Penny Dreadful Commander" jar="mage-deck-constructed.jar" className="mage.deck.PennyDreadfulCommander"/>
<deckType name="Variant Magic - Freeform Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformCommander"/>
<deckType name="Variant Magic - Brawl" jar="mage-deck-constructed.jar" className="mage.deck.Brawl"/>
<deckType name="Block Constructed - Amonkhet" jar="mage-deck-constructed.jar" className="mage.deck.AmonkhetBlock"/>
<deckType name="Block Constructed - Battle for Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.BattleForZendikarBlock"/>
<deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.InnistradBlock"/>
<deckType name="Block Constructed - Ixalan" jar="mage-deck-constructed.jar" className="mage.deck.IxalanBlock"/>
<deckType name="Block Constructed - Kaladesh" jar="mage-deck-constructed.jar" className="mage.deck.KaladeshBlock"/>
<deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed.jar" className="mage.deck.KamigawaBlock"/>
<deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed.jar" className="mage.deck.KhansOfTarkirBlock"/>
<deckType name="Block Constructed - Lorwyn" jar="mage-deck-constructed.jar" className="mage.deck.LorwynBlock"/>
<deckType name="Block Constructed - Return to Ravnica" jar="mage-deck-constructed.jar" className="mage.deck.ReturnToRavnicaBlock"/>
<deckType name="Block Constructed - Scars of Mirrodin" jar="mage-deck-constructed.jar" className="mage.deck.ScarsOfMirrodinBlock"/>
<deckType name="Block Constructed - Shadowmoor" jar="mage-deck-constructed.jar" className="mage.deck.ShadowmoorBlock"/>
<deckType name="Block Constructed - Shadows over Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.ShadowsOverInnistradBlock"/>
<deckType name="Block Constructed - Shards of Alara" jar="mage-deck-constructed.jar" className="mage.deck.ShardsOfAlaraBlock"/>
<deckType name="Block Constructed - Theros" jar="mage-deck-constructed.jar" className="mage.deck.TherosBlock"/>
<deckType name="Block Constructed - Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.ZendikarBlock"/>
<deckType name="Block Constructed Custom - Star Wars" jar="mage-deck-constructed.jar" className="mage.deck.StarWarsBlock"/>
<deckType name="Limited" jar="mage-deck-limited.jar" className="mage.deck.Limited"/>
</deckTypes>
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Config.xsd">
<!--
Official guide to setup public server and NAT: https://www.slightlymagic.net/forum/viewtopic.php?f=70&t=15898
serverAddress - ip or domain of the XMage server. Set it to "0.0.0.0" for local host or to the IP the server should use
Public server should be accessable to all clients by it's name (example: xmage.mydomain.com)
port - the port the primary server socket is bound to
secondaryBindPort - the port to which the secondary server socket is to be bound. if "-1" is set , an arbitrary port is selected.
backlogSize - the preferred number of unaccepted incoming connections allowed at a given time. The actual number may be greater
than the specified backlog. When the queue is full, further connection requests are rejected. The JBoss default value is 200
numAcceptThreads - the number of threads listening on the ServerSocket. The JBoss default value is 1
maxPoolSize - the maximum number of ServerThreads that can exist at any given time. The JBoss default value is 300
leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria.
The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds.
The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method
socketWriteTimeout - All write operations will time out if they do not complete within the configured period.
maxGameThreads - Number of games that can be started simultanously on the server
maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time
minUserNameLength - minmal allowed length of a user name to connect to the server
maxUserNameLength - maximal allowed length of a user name to connect to the server
userNamePattern - pattern for user name validity check
maxAiOpponents - number of allowed AI opponents on the server
saveGameActivated - allow game save and replay options (not working correctly yet)
authenticationActivated - "true" = user have to register to signon "false" = user need not to register
* mail configs only needed if authentication is activated:
* if mailUser = "" mailgun is used otherwise nativ mail server on the system
googleAccount - not supported currently
mailgunApiKey - key from the mailgun domain e.g. = "key-12121111..."
mailgunDomain - domain for the mailgun message sending
mailSmtpHost - hostname to send the mail
mailSmtpPort - port to send the mail
mailUser - username used to send the mail
mailPassword - passworf of the used user to send the mail
mailFromAddress - sender address
-->
<server serverAddress="0.0.0.0"
serverName="mage-server"
port="17171"
secondaryBindPort="17179"
backlogSize="200"
numAcceptThreads="2"
maxPoolSize="300"
leasePeriod="5000"
socketWriteTimeout="10000"
maxGameThreads="10"
maxSecondsIdle="300"
minUserNameLength="3"
maxUserNameLength="14"
invalidUserNamePattern="[^a-z0-9_]"
minPasswordLength="8"
maxPasswordLength="100"
maxAiOpponents="15"
saveGameActivated="false"
authenticationActivated="false"
googleAccount=""
mailgunApiKey="key-d93e81f19a9c9ed243ebb7cc9381385c"
mailgunDomain="sandbox401a433f30d445309a5e86b6c53f7812.mailgun.org"
mailSmtpHost="smtp.1und1.de"
mailSmtpPort="465"
mailUser="xmageserver@online.de"
mailPassword="24wrsfxv"
mailFromAddress="xmageserver@online.de"
/>
<playerTypes>
<playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/>
<!--<playerType name="Computer - minimax" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>-->
<playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer7"/>
<!--<playerType name="Computer - monte carlo" jar="mage-player-aimcts.jar" className="mage.player.ai.ComputerPlayerMCTS"/>-->
<playerType name="Computer - draftbot" jar="mage-player-ai-draft-bot.jar" className="mage.player.ai.ComputerDraftPlayer"/>
</playerTypes>
<gameTypes>
<gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/>
<gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
<gameType name="Commander Two Player Duel" jar="mage-game-commanderduel.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/>
<gameType name="Commander Free For All" jar="mage-game-commanderfreeforall.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/>
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
<gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/>
<gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>
<gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/>
<gameType name="Momir Basic Two Player Duel" jar="mage-game-momirduel.jar" className="mage.game.MomirDuelMatch" typeName="mage.game.MomirDuelType"/>
<gameType name="Momir Basic Free For All" jar="mage-game-momir.jar" className="mage.game.MomirFreeForAllMatch" typeName="mage.game.MomirFreeForAllType"/>
</gameTypes>
<tournamentTypes>
<tournamentType name="Constructed Elimination" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/>
<tournamentType name="Constructed Swiss" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/>
<tournamentType name="Booster Draft Elimination" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
<tournamentType name="Sealed Swiss (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissCubeTournamentType"/>
</tournamentTypes>
<draftCubes>
<draftCube name="Adam Styborski's Pauper Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.AdamStyborskisPauperCube"/>
<draftCube name="Ben's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.BensCube"/>
<draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/>
<draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor720"/>
<draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/>
<draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/>
<draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JimDavisCube"/>
<draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/>
<draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MonoBlueCube"/>
<draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.SamBlacksCube"/>
<draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/>
<draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/>
<draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/>
<draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/>
<draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
<draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
<draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
<draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
<draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/>
<draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/>
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/>
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/>
<draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2016"/>
<draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2016"/>
<draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/>
<draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/>
<draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/>
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>
<draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/>
</draftCubes>
<deckTypes>
<deckType name="Constructed - Standard" jar="mage-deck-constructed.jar" className="mage.deck.Standard"/>
<deckType name="Constructed - Extended" jar="mage-deck-constructed.jar" className="mage.deck.Extended"/>
<deckType name="Constructed - Frontier" jar="mage-deck-constructed.jar" className="mage.deck.Frontier"/>
<deckType name="Constructed - Modern" jar="mage-deck-constructed.jar" className="mage.deck.Modern"/>
<deckType name="Constructed - Modern - No Banned List" jar="mage-deck-constructed.jar" className="mage.deck.ModernNoBannedList"/>
<deckType name="Constructed - Eternal" jar="mage-deck-constructed.jar" className="mage.deck.Eternal"/>
<deckType name="Constructed - Legacy" jar="mage-deck-constructed.jar" className="mage.deck.Legacy"/>
<deckType name="Constructed - Vintage" jar="mage-deck-constructed.jar" className="mage.deck.Vintage"/>
<deckType name="Constructed - Pauper" jar="mage-deck-constructed.jar" className="mage.deck.Pauper"/>
<deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed.jar" className="mage.deck.HistoricalType2"/>
<deckType name="Constructed - Super Type 2" jar="mage-deck-constructed.jar" className="mage.deck.SuperType2"/>
<deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.AusHighlander"/>
<deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.CanadianHighlander"/>
<deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394"/>
<deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394Italian"/>
<deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/>
<deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/>
<deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/>
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/>
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/>
<deckType name="Variant Magic - MTGO 1v1 Commander" jar="mage-deck-constructed.jar" className="mage.deck.MTGO1v1Commander"/>
<deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed.jar" className="mage.deck.TinyLeaders"/>
<deckType name="Variant Magic - Momir Basic" jar="mage-deck-constructed.jar" className="mage.deck.Momir"/>
<deckType name="Variant Magic - Penny Dreadful Commander" jar="mage-deck-constructed.jar" className="mage.deck.PennyDreadfulCommander"/>
<deckType name="Variant Magic - Freeform Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformCommander"/>
<deckType name="Variant Magic - Brawl" jar="mage-deck-constructed.jar" className="mage.deck.Brawl"/>
<deckType name="Block Constructed - Amonkhet" jar="mage-deck-constructed.jar" className="mage.deck.AmonkhetBlock"/>
<deckType name="Block Constructed - Battle for Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.BattleForZendikarBlock"/>
<deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.InnistradBlock"/>
<deckType name="Block Constructed - Ixalan" jar="mage-deck-constructed.jar" className="mage.deck.IxalanBlock"/>
<deckType name="Block Constructed - Kaladesh" jar="mage-deck-constructed.jar" className="mage.deck.KaladeshBlock"/>
<deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed.jar" className="mage.deck.KamigawaBlock"/>
<deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed.jar" className="mage.deck.KhansOfTarkirBlock"/>
<deckType name="Block Constructed - Lorwyn" jar="mage-deck-constructed.jar" className="mage.deck.LorwynBlock"/>
<deckType name="Block Constructed - Return to Ravnica" jar="mage-deck-constructed.jar" className="mage.deck.ReturnToRavnicaBlock"/>
<deckType name="Block Constructed - Scars of Mirrodin" jar="mage-deck-constructed.jar" className="mage.deck.ScarsOfMirrodinBlock"/>
<deckType name="Block Constructed - Shadowmoor" jar="mage-deck-constructed.jar" className="mage.deck.ShadowmoorBlock"/>
<deckType name="Block Constructed - Shadows over Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.ShadowsOverInnistradBlock"/>
<deckType name="Block Constructed - Shards of Alara" jar="mage-deck-constructed.jar" className="mage.deck.ShardsOfAlaraBlock"/>
<deckType name="Block Constructed - Theros" jar="mage-deck-constructed.jar" className="mage.deck.TherosBlock"/>
<deckType name="Block Constructed - Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.ZendikarBlock"/>
<deckType name="Block Constructed Custom - Star Wars" jar="mage-deck-constructed.jar" className="mage.deck.StarWarsBlock"/>
<deckType name="Limited" jar="mage-deck-limited.jar" className="mage.deck.Limited"/>
</deckTypes>
</config>

View file

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

View file

@ -142,10 +142,13 @@
<deckType name="Constructed - Pauper" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Pauper"/>
<deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.HistoricalType2"/>
<deckType name="Constructed - Super Type 2" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.SuperType2"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Freeform"/>
<deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394"/>
<deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.AusHighlander"/>
<deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.CanadianHighlander"/>
<deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394"/>
<deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394Italian"/>
<deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394CFB"/>
<deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394EG"/>
<deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394EC"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Freeform"/>
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Commander"/>
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.DuelCommander"/>

View file

@ -100,7 +100,7 @@ public class TableController {
} else {
controllerName = "System";
}
table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()),
table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()),
options.getPlayerTypes(), TableRecorderImpl.instance, match, options.getBannedUsers(), options.isPlaneChase());
chatId = ChatManager.instance.createChatSession("Match Table " + table.getId());
init();
@ -120,7 +120,7 @@ public class TableController {
} else {
controllerName = "System";
}
table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()),
table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()),
options.getPlayerTypes(), TableRecorderImpl.instance, tournament, options.getMatchOptions().getBannedUsers(), options.isPlaneChase());
chatId = ChatManager.instance.createChatSession("Tourn. table " + table.getId());
}
@ -486,7 +486,11 @@ public class TableController {
if (userPlayerMap.get(userId) != null) {
return false;
}
return UserManager.instance.getUser(userId).get().ccWatchGame(match.getGame().getId());
Optional<User> _user = UserManager.instance.getUser(userId);
if (!_user.isPresent()) {
return false;
}
return _user.get().ccWatchGame(match.getGame().getId());
}
}

View file

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

View file

@ -51,7 +51,7 @@ import mage.target.TargetPlayer;
*
* @author Styxo
*/
public class AAT1 extends CardImpl {
public final class AAT1 extends CardImpl {
public AAT1(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}{U}{B}");

View file

@ -44,7 +44,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
*
* @author Styxo
*/
public class ATST extends CardImpl {
public final class ATST extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Trooper creatures");

View file

@ -49,7 +49,7 @@ import mage.game.permanent.Permanent;
*
* @author Styxo
*/
public class AWing extends CardImpl {
public final class AWing extends CardImpl {
public AWing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{R}");

View file

@ -49,7 +49,7 @@ import mage.target.common.TargetCardInHand;
*
* @author fireshoes
*/
public class AbandonHope extends CardImpl {
public final class AbandonHope extends CardImpl {
public AbandonHope(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");

View file

@ -44,7 +44,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author LevelX2
*/
public class AbandonReason extends CardImpl {
public final class AbandonReason extends CardImpl {
public AbandonReason(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");

View file

@ -43,7 +43,7 @@ import mage.constants.CardType;
* @author cbt33
*/
public class AbandonedOutpost extends CardImpl {
public final class AbandonedOutpost extends CardImpl {
public AbandonedOutpost(UUID ownerId, CardSetInfo setInfo){
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");

View file

@ -62,7 +62,7 @@ import mage.watchers.Watcher;
*
* @author jeffwadsworth
*/
public class AbandonedSarcophagus extends CardImpl {
public final class AbandonedSarcophagus extends CardImpl {
public AbandonedSarcophagus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");

View file

@ -48,7 +48,7 @@ import mage.players.Player;
*
* @author Alvin
*/
public class AbattoirGhoul extends CardImpl {
public final class AbattoirGhoul extends CardImpl {
public AbattoirGhoul(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");

View file

@ -41,7 +41,7 @@ import mage.constants.SubType;
*
* @author Sir-Speshkitty
*/
public class AbbeyGargoyles extends CardImpl {
public final class AbbeyGargoyles extends CardImpl {
public AbbeyGargoyles(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}{W}");

View file

@ -41,7 +41,7 @@ import mage.constants.SubType;
*
* @author BetaSteward_at_googlemail.com
*/
public class AbbeyGriffin extends CardImpl {
public final class AbbeyGriffin extends CardImpl {
public AbbeyGriffin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");

View file

@ -45,7 +45,7 @@ import mage.constants.Zone;
*
* @author Sir-Speshkitty
*/
public class AbbeyMatron extends CardImpl {
public final class AbbeyMatron extends CardImpl {
public AbbeyMatron(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");

View file

@ -49,7 +49,7 @@ import mage.target.targetpointer.FixedTarget;
*
* @author fireshoes
*/
public class AbbotOfKeralKeep extends CardImpl {
public final class AbbotOfKeralKeep extends CardImpl {
public AbbotOfKeralKeep(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");

View file

@ -49,7 +49,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author Quercitron
*/
public class Abduction extends CardImpl {
public final class Abduction extends CardImpl {
public Abduction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}");

View file

@ -47,7 +47,7 @@ import mage.players.Player;
*
* @author fireshoes
*/
public class AberrantResearcher extends CardImpl {
public final class AberrantResearcher extends CardImpl {
public AberrantResearcher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");

View file

@ -47,7 +47,7 @@ import mage.target.TargetPlayer;
*
* @author fireshoes
*/
public class Abeyance extends CardImpl {
public final class Abeyance extends CardImpl {
public Abeyance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");

View file

@ -50,7 +50,7 @@ import mage.game.permanent.token.Token;
*
* @author LevelX2
*/
public class AbhorrentOverlord extends CardImpl {
public final class AbhorrentOverlord extends CardImpl {
public AbhorrentOverlord(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");

View file

@ -43,7 +43,7 @@ import mage.target.common.TargetControlledPermanent;
*
* @author djbrez
*/
public class Abjure extends CardImpl {
public final class Abjure extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("a blue permanent");

View file

@ -46,7 +46,7 @@ import java.util.UUID;
*
* @author Backfir3
*/
public class Abolish extends CardImpl {
public final class Abolish extends CardImpl {
private static final FilterCard filterCost = new FilterCard("Plains card");

View file

@ -49,7 +49,7 @@ import mage.target.common.TargetOpponent;
*
* @author fireshoes
*/
public class AbolisherOfBloodlines extends CardImpl {
public final class AbolisherOfBloodlines extends CardImpl {
public AbolisherOfBloodlines(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");

View file

@ -47,7 +47,7 @@ import mage.filter.predicate.mageobject.ColorPredicate;
*
* @author jeffwadsworth
*/
public class Abomination extends CardImpl {
public final class Abomination extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("green or white creature");

View file

@ -44,7 +44,7 @@ import mage.constants.SubType;
*
* @author LevelX2
*/
public class AbominationOfGudul extends CardImpl {
public final class AbominationOfGudul extends CardImpl {
public AbominationOfGudul(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{G}{U}");

View file

@ -45,7 +45,7 @@ import mage.game.permanent.Permanent;
*
* @author Styxo
*/
public class Aboroth extends CardImpl {
public final class Aboroth extends CardImpl {
public Aboroth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");

View file

@ -54,7 +54,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
*
* @author cbt33
*/
public class AboshanCephalidEmperor extends CardImpl {
public final class AboshanCephalidEmperor extends CardImpl {
static final FilterControlledCreaturePermanent filter1 = new FilterControlledCreaturePermanent("untapped Cephalid you control");
static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures without flying");

View file

@ -47,7 +47,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author cbt33
*/
public class AboshansDesire extends CardImpl {
public final class AboshansDesire extends CardImpl {
public AboshansDesire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}");

View file

@ -39,7 +39,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author Backfir3
*/
public class AboutFace extends CardImpl {
public final class AboutFace extends CardImpl {
public AboutFace(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");

View file

@ -41,7 +41,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author fireshoes
*/
public class Abrade extends CardImpl {
public final class Abrade extends CardImpl {
public Abrade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");

View file

@ -46,7 +46,7 @@ import mage.target.common.TargetNonlandPermanent;
*
* @author LevelX2
*/
public class AbruptDecay extends CardImpl {
public final class AbruptDecay extends CardImpl {
private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent with converted mana cost 3 or less");

View file

@ -44,7 +44,7 @@ import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES;
*
* @author Backfir3
*/
public class AbsoluteGrace extends CardImpl {
public final class AbsoluteGrace extends CardImpl {
public AbsoluteGrace(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");

View file

@ -44,7 +44,7 @@ import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES;
*
* @author Backfir3
*/
public class AbsoluteLaw extends CardImpl {
public final class AbsoluteLaw extends CardImpl {
public AbsoluteLaw(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");

View file

@ -42,7 +42,7 @@ import mage.target.common.TargetEnchantmentPermanent;
*
* @author LevelX2
*/
public class AbsolverThrull extends CardImpl {
public final class AbsolverThrull extends CardImpl {
public AbsolverThrull(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");

View file

@ -39,7 +39,7 @@ import mage.target.TargetSpell;
*
* @author Loki
*/
public class Absorb extends CardImpl {
public final class Absorb extends CardImpl {
public Absorb(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}{U}{U}");

View file

@ -42,7 +42,7 @@ import mage.target.TargetPlayer;
*
* @author Loki
*/
public class AbsorbVis extends CardImpl {
public final class AbsorbVis extends CardImpl {
public AbsorbVis (UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{B}");

View file

@ -43,7 +43,7 @@ import mage.target.TargetSpell;
*
* @author fireshoes
*/
public class AbstruseInterference extends CardImpl {
public final class AbstruseInterference extends CardImpl {
public AbstruseInterference(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");

View file

@ -44,7 +44,7 @@ import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
*
* @author MarcoMarin
*/
public class AbuJafar extends CardImpl {
public final class AbuJafar extends CardImpl {
public AbuJafar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");

View file

@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author Martin Sagastume msr986@gmail.com
*/
public class AbunaAcolyte extends CardImpl {
public final class AbunaAcolyte extends CardImpl {
final static FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creature");

View file

@ -42,7 +42,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author Plopman
*/
public class AbunasChant extends CardImpl {
public final class AbunasChant extends CardImpl {
public AbunasChant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}");

View file

@ -48,7 +48,7 @@ import mage.players.Player;
*
* @author emerald000
*/
public class Abundance extends CardImpl {
public final class Abundance extends CardImpl {
public Abundance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");

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