* Reworked DB comparison between client and server.

This commit is contained in:
LevelX2 2015-01-25 19:21:50 +01:00
parent 05a4a99ec6
commit 6ef8b4f976
12 changed files with 346 additions and 177 deletions

View file

@ -1,9 +1,8 @@
package mage.client.deckeditor.collection.viewer;
import mage.client.plugins.impl.Plugins;
import javax.swing.*;
import javax.swing.JFrame;
import mage.cards.repository.CardScanner;
import mage.client.plugins.impl.Plugins;
import org.mage.card.arcane.ManaSymbols;
/**

View file

@ -2,7 +2,7 @@
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="title" type="java.lang.String" value="Connect"/>
<Property name="title" type="java.lang.String" value="Connect to server"/>
<Property name="normalBounds" type="java.awt.Rectangle" editor="org.netbeans.beaninfo.editors.RectangleEditor">
<Rectangle value="[100, 100, 410, 307]"/>
</Property>
@ -28,7 +28,13 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="btnConnect" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblPort" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lblServer" min="-2" max="-2" attributes="0"/>
@ -36,23 +42,25 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtUserName" alignment="0" pref="382" max="32767" attributes="0"/>
<Component id="chkAutoConnect" alignment="0" pref="382" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="txtServer" pref="311" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
<Component id="lblStatus" alignment="1" max="32767" attributes="0"/>
<Component id="chkForceUpdateDB" max="32767" attributes="0"/>
<Component id="chkAutoConnect" pref="362" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="164" pref="237" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="txtServer" pref="286" max="32767" attributes="0"/>
<Component id="txtPort" alignment="0" min="-2" pref="71" max="-2" attributes="0"/>
<Component id="jProxySettingsButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="txtUserName" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="btnConnect" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
<Component id="btnFind" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Component id="lblStatus" alignment="0" min="-2" pref="195" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -65,7 +73,7 @@
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblServer" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtServer" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jButton1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnFind" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
@ -79,20 +87,16 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkAutoConnect" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkForceUpdateDB" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jProxySettingsButton" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace pref="24" max="32767" attributes="0"/>
<EmptySpace pref="20" max="32767" attributes="0"/>
<Component id="lblStatus" min="-2" pref="24" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnConnect" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="lblStatus" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -100,8 +104,6 @@
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="txtServer">
</Component>
<Component class="javax.swing.JLabel" name="lblServer">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
@ -110,6 +112,18 @@
<Property name="text" type="java.lang.String" value="Server:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtServer">
</Component>
<Component class="javax.swing.JButton" name="btnFind">
<Properties>
<Property name="text" type="java.lang.String" value="Find..."/>
<Property name="toolTipText" type="java.lang.String" value="Shows the list of public servers"/>
<Property name="name" type="java.lang.String" value="findServerBtn" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPublicServerActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblPort">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
@ -123,8 +137,6 @@
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="keyTyped"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="txtUserName">
</Component>
<Component class="javax.swing.JLabel" name="lblUserName">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
@ -133,6 +145,34 @@
<Property name="text" type="java.lang.String" value="User Name:"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="txtUserName">
</Component>
<Component class="javax.swing.JCheckBox" name="chkAutoConnect">
<Properties>
<Property name="text" type="java.lang.String" value="Automatically connect to this server next time"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;If active this connect dialog will not be shown if you choose to connect.&lt;br&gt;&#xa;Instead XMage tries to connect to the last server you were connected to."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkAutoConnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="chkForceUpdateDB">
<Properties>
<Property name="text" type="java.lang.String" value="Force update of card database"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;If active the comparison of the server cards database to the client database will be enforced.&lt;br&gt;If not, the comparison will only done if the database version of the client is lower than the version of the server."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkForceUpdateDBActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="jProxySettingsButton">
<Properties>
<Property name="text" type="java.lang.String" value="Proxy Settings..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jProxySettingsButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnConnect">
<Properties>
<Property name="text" type="java.lang.String" value="Connect"/>
@ -149,32 +189,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="chkAutoConnect">
<Properties>
<Property name="text" type="java.lang.String" value="Automatically connect to this server next time"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chkAutoConnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="jButton1">
<Properties>
<Property name="text" type="java.lang.String" value="Find..."/>
<Property name="toolTipText" type="java.lang.String" value="Find public server"/>
<Property name="name" type="java.lang.String" value="findServerBtn" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPublicServerActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="jProxySettingsButton">
<Properties>
<Property name="text" type="java.lang.String" value="Proxy Settings..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jProxySettingsButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblStatus">
</Component>
</SubComponents>

View file

@ -96,6 +96,7 @@ public class ConnectDialog extends MageDialog {
this.txtPort.setText(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port)));
this.txtUserName.setText(MageFrame.getPreferences().get("userName", ""));
this.chkAutoConnect.setSelected(Boolean.parseBoolean(MageFrame.getPreferences().get("autoConnect", "false")));
this.chkForceUpdateDB.setSelected(false); // has always to be set manually to force comparison
this.setModal(true);
this.setLocation(50, 50);
this.setVisible(true);
@ -118,25 +119,35 @@ public class ConnectDialog extends MageDialog {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
txtServer = new javax.swing.JTextField();
lblServer = new javax.swing.JLabel();
txtServer = new javax.swing.JTextField();
btnFind = new javax.swing.JButton();
lblPort = new javax.swing.JLabel();
txtPort = new javax.swing.JTextField();
txtUserName = new javax.swing.JTextField();
lblUserName = new javax.swing.JLabel();
txtUserName = new javax.swing.JTextField();
chkAutoConnect = new javax.swing.JCheckBox();
chkForceUpdateDB = new javax.swing.JCheckBox();
jProxySettingsButton = new javax.swing.JButton();
btnConnect = new javax.swing.JButton();
btnCancel = new javax.swing.JButton();
chkAutoConnect = new javax.swing.JCheckBox();
jButton1 = new javax.swing.JButton();
jProxySettingsButton = new javax.swing.JButton();
lblStatus = new javax.swing.JLabel();
setTitle("Connect");
setTitle("Connect to server");
setNormalBounds(new java.awt.Rectangle(100, 100, 410, 307));
lblServer.setLabelFor(txtServer);
lblServer.setText("Server:");
btnFind.setText("Find...");
btnFind.setToolTipText("Shows the list of public servers");
btnFind.setName("findServerBtn"); // NOI18N
btnFind.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
findPublicServerActionPerformed(evt);
}
});
lblPort.setLabelFor(txtPort);
lblPort.setText("Port:");
@ -149,6 +160,29 @@ public class ConnectDialog extends MageDialog {
lblUserName.setLabelFor(txtUserName);
lblUserName.setText("User Name:");
chkAutoConnect.setText("Automatically connect to this server next time");
chkAutoConnect.setToolTipText("<HTML>If active this connect dialog will not be shown if you choose to connect.<br>\nInstead XMage tries to connect to the last server you were connected to.");
chkAutoConnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkAutoConnectActionPerformed(evt);
}
});
chkForceUpdateDB.setText("Force update of card database");
chkForceUpdateDB.setToolTipText("<HTML>If active the comparison of the server cards database to the client database will be enforced.<br>If not, the comparison will only done if the database version of the client is lower than the version of the server.");
chkForceUpdateDB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkForceUpdateDBActionPerformed(evt);
}
});
jProxySettingsButton.setText("Proxy Settings...");
jProxySettingsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jProxySettingsButtonActionPerformed(evt);
}
});
btnConnect.setText("Connect");
btnConnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -163,29 +197,6 @@ public class ConnectDialog extends MageDialog {
}
});
chkAutoConnect.setText("Automatically connect to this server next time");
chkAutoConnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkAutoConnectActionPerformed(evt);
}
});
jButton1.setText("Find...");
jButton1.setToolTipText("Find public server");
jButton1.setName("findServerBtn"); // NOI18N
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
findPublicServerActionPerformed(evt);
}
});
jProxySettingsButton.setText("Proxy Settings...");
jProxySettingsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jProxySettingsButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@ -193,6 +204,11 @@ public class ConnectDialog extends MageDialog {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(btnConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblPort)
@ -200,21 +216,20 @@ public class ConnectDialog extends MageDialog {
.addComponent(lblUserName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblStatus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(131, 131, 131))
.addComponent(txtUserName, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
.addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(txtServer, javax.swing.GroupLayout.DEFAULT_SIZE, 311, Short.MAX_VALUE)
.addComponent(jProxySettingsButton)
.addGap(164, 237, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(txtServer, javax.swing.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
.addComponent(txtPort, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(txtUserName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton1))
.addComponent(jProxySettingsButton)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(btnConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel))
.addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 195, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(btnFind)
.addGap(0, 0, Short.MAX_VALUE)))))
.addContainerGap())
);
layout.setVerticalGroup(
@ -224,7 +239,7 @@ public class ConnectDialog extends MageDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblServer)
.addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton1))
.addComponent(btnFind))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@ -235,19 +250,17 @@ public class ConnectDialog extends MageDialog {
.addComponent(lblUserName))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkAutoConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkForceUpdateDB)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jProxySettingsButton)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 24, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
.addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnCancel)
.addComponent(btnConnect))
.addComponent(btnConnect)
.addComponent(btnCancel))
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGap(8, 8, 8)
.addComponent(lblStatus)
.addContainerGap())))
);
pack();
@ -289,6 +302,8 @@ public class ConnectDialog extends MageDialog {
connection.setHost(this.txtServer.getText().trim());
connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim());
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected());
ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None"));
@ -497,12 +512,17 @@ public class ConnectDialog extends MageDialog {
PreferencesDialog.main(new String[]{PreferencesDialog.OPEN_CONNECTION_TAB});
}//GEN-LAST:event_jProxySettingsButtonActionPerformed
private void chkForceUpdateDBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkForceUpdateDBActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_chkForceUpdateDBActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
private javax.swing.JButton btnConnect;
private javax.swing.JButton btnFind;
private javax.swing.JCheckBox chkAutoConnect;
private javax.swing.JButton jButton1;
private javax.swing.JCheckBox chkForceUpdateDB;
private javax.swing.JButton jProxySettingsButton;
private javax.swing.JLabel lblPort;
private javax.swing.JLabel lblServer;

View file

@ -48,8 +48,12 @@ public class ServerState implements Serializable {
private final String[] draftCubes;
private final boolean testMode;
private final MageVersion version;
private final long cardsContentVersion;
private final long expansionsContentVersion;
public ServerState(List<GameTypeView> gameTypes, List<TournamentTypeView> tournamentTypes, String[] playerTypes, String[] deckTypes, String[] draftCubes, boolean testMode, MageVersion version) {
public ServerState(List<GameTypeView> gameTypes, List<TournamentTypeView> tournamentTypes,
String[] playerTypes, String[] deckTypes, String[] draftCubes, boolean testMode,
MageVersion version, long cardsContentVersion, long expansionsContentVersion) {
this.gameTypes = gameTypes;
this.tournamentTypes = tournamentTypes;
this.playerTypes = playerTypes;
@ -57,6 +61,9 @@ public class ServerState implements Serializable {
this.draftCubes = draftCubes;
this.testMode = testMode;
this.version = version;
this.cardsContentVersion = cardsContentVersion;
this.expansionsContentVersion = expansionsContentVersion;
}
public List<GameTypeView> getGameTypes() {
@ -96,4 +103,13 @@ public class ServerState implements Serializable {
public MageVersion getVersion() {
return version;
}
public long getCardsContentVersion() {
return cardsContentVersion;
}
public long getExpansionsContentVersion() {
return expansionsContentVersion;
}
}

View file

@ -51,6 +51,8 @@ public class Connection {
private int proxyPort;
private String proxyUsername;
private String proxyPassword;
private int clientCardDatabaseVersion;
private boolean forceDBComparison;
private int avatarId;
private boolean showAbilityPickerForced;
@ -202,8 +204,9 @@ public class Connection {
public static InetAddress getLocalAddress() throws SocketException {
for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements(); ) {
NetworkInterface iface = interfaces.nextElement( );
if (iface.isLoopback())
if (iface.isLoopback()) {
continue;
}
for (InterfaceAddress addr: iface.getInterfaceAddresses()) {
if (addr != null) {
InetAddress iaddr = addr.getAddress();
@ -247,4 +250,12 @@ public class Connection {
this.userSkipPrioritySteps = userSkipPrioritySteps;
}
public boolean isForceDBComparison() {
return forceDBComparison;
}
public void setForceDBComparison(boolean forceDBComparison) {
this.forceDBComparison = forceDBComparison;
}
}

View file

@ -49,6 +49,7 @@ import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.cards.repository.RepositoryUtil;
import mage.constants.Constants.SessionState;
import mage.constants.ManaType;
import mage.constants.PlayerAction;
@ -287,7 +288,7 @@ public class SessionImpl implements Session {
sessionState = SessionState.CONNECTED;
serverState = server.getServerState();
if (!connection.getUsername().equals("Admin")) {
updateDatabase();
updateDatabase(connection.isForceDBComparison(), serverState);
}
logger.info("Connected as " + (this.getUserName() == null ? "":this.getUserName()) + " to MAGE server at " + connection.getHost() + ":" + connection.getPort());
client.connected(this.getUserName() == null ? "":this.getUserName() +"@" + connection.getHost() + ":" + connection.getPort() +" ");
@ -322,16 +323,28 @@ public class SessionImpl implements Session {
return false;
}
private void updateDatabase() {
private void updateDatabase(boolean forceDBComparison, ServerState serverState) {
long cardDBVersion = CardRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
List<String> classNames = CardRepository.instance.getClassNames();
List<CardInfo> cards = server.getMissingCardsData(classNames);
CardRepository.instance.addCards(cards);
CardRepository.instance.setContentVersion(serverState.getCardsContentVersion());
logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size() +
" content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion);
}
long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getExpansionsContentVersion() > expansionDBVersion) {
List<String> setCodes = ExpansionRepository.instance.getSetCodes();
List<ExpansionInfo> expansions = server.getMissingExpansionData(setCodes);
for (ExpansionInfo expansion : expansions) {
ExpansionRepository.instance.add(expansion);
}
ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion());
logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size()+
" content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion);
}
}
private void handleCannotConnectException(CannotConnectException ex) {
@ -366,10 +379,10 @@ public class SessionImpl implements Session {
/**
*
* @param errorCall - was connection lost because of error - ask user if he want to try to reconnect
* @param askForReconnect - true = connection was lost because of error and ask the user if he want to try to reconnect
*/
@Override
public synchronized void disconnect(boolean errorCall) {
public synchronized void disconnect(boolean askForReconnect) {
if (isConnected()) {
logger.info("DISCONNECT (still connected)");
sessionState = SessionState.DISCONNECTING;
@ -389,10 +402,10 @@ public class SessionImpl implements Session {
if (sessionState == SessionState.DISCONNECTING || sessionState == SessionState.CONNECTING) {
sessionState = SessionState.DISCONNECTED;
logger.info("Disconnected ... ");
if (errorCall) {
if (askForReconnect) {
client.showError("Network error. You have been disconnected");
}
client.disconnected(errorCall); // MageFrame with check to reconnect
client.disconnected(askForReconnect); // MageFrame with check to reconnect
pingTime.clear();
}
}

View file

@ -889,7 +889,10 @@ public class MageServerImpl implements MageServer {
DeckValidatorFactory.getInstance().getDeckTypes().toArray(new String[DeckValidatorFactory.getInstance().getDeckTypes().size()]),
CubeFactory.getInstance().getDraftCubes().toArray(new String[CubeFactory.getInstance().getDraftCubes().size()]),
testMode,
Main.getVersion());
Main.getVersion(),
CardRepository.instance.getContentVersionConstant(),
ExpansionRepository.instance.getContentVersionConstant()
);
}
catch (Exception ex) {
handleException(ex);

View file

@ -63,7 +63,6 @@ import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import static mage.server.Session.getBasicCause;
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;

View file

@ -38,7 +38,6 @@ import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.table.TableUtils;
import java.io.File;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@ -58,7 +57,10 @@ public enum CardRepository {
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "card";
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 36;
// raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 1;
private final Random random = new Random();
private Dao<CardInfo, Object> cardDao;
@ -277,6 +279,29 @@ public enum CardRepository {
return new ArrayList<>();
}
public long getContentVersionFromDB() {
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME + "Content");
} catch (SQLException ex) {
ex.printStackTrace();
}
return 0;
}
public void setContentVersion(long version) {
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
RepositoryUtil.updateVersion(connectionSource, VERSION_ENTITY_NAME + "Content", version);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public long getContentVersionConstant() {
return CARD_CONTENT_VERSION;
}
public void closeDB() {
try {
DatabaseConnection conn = cardDao.getConnectionSource().getReadWriteConnection();

View file

@ -25,14 +25,21 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.repository;
import mage.cards.*;
import mage.util.ClassScanner;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
import mage.cards.SplitCard;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.util.ClassScanner;
import org.apache.log4j.Logger;
/**
*
@ -57,6 +64,7 @@ public class CardScanner {
packages.add(set.getPackageName());
ExpansionRepository.instance.add(new ExpansionInfo(set));
}
ExpansionRepository.instance.setContentVersion(CardRepository.instance.getContentVersionConstant());
for (Class c : ClassScanner.findClasses(packages, CardImpl.class)) {
if (!CardRepository.instance.cardExists(c.getCanonicalName())) {
@ -75,6 +83,7 @@ public class CardScanner {
logger.info("Cards need storing in DB: " + cardsToAdd.size());
CardRepository.instance.addCards(cardsToAdd);
}
CardRepository.instance.setContentVersion(CardRepository.instance.getContentVersionConstant());
}
}

View file

@ -24,6 +24,7 @@ public enum ExpansionRepository {
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "expansion";
private static final long EXPANSION_DB_VERSION = 3;
private static final long EXPANSION_CONTENT_VERSION = 1;
private Dao<ExpansionInfo, Object> expansionDao;
@ -34,7 +35,7 @@ public enum ExpansionRepository {
}
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, EXPANSION_DB_VERSION);
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, 0);
if (obsolete) {
TableUtils.dropTable(connectionSource, ExpansionInfo.class, true);
@ -55,7 +56,7 @@ public enum ExpansionRepository {
}
public List<String> getSetCodes() {
List<String> setCodes = new ArrayList<String>();
List<String> setCodes = new ArrayList<>();
try {
List<ExpansionInfo> expansions = expansionDao.queryForAll();
for (ExpansionInfo expansion : expansions) {
@ -80,7 +81,7 @@ public enum ExpansionRepository {
}
public List<ExpansionInfo> getSetsWithBasicLandsByReleaseDate() {
List<ExpansionInfo> sets = new LinkedList<ExpansionInfo>();
List<ExpansionInfo> sets = new LinkedList<>();
try {
QueryBuilder<ExpansionInfo, Object> qb = expansionDao.queryBuilder();
qb.orderBy("releaseDate", false);
@ -122,6 +123,29 @@ public enum ExpansionRepository {
return expansionDao.queryForAll();
} catch (SQLException ex) {
}
return new ArrayList<ExpansionInfo>();
return new ArrayList<>();
}
public long getContentVersionFromDB() {
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME + "Content");
} catch (SQLException ex) {
ex.printStackTrace();
}
return 0;
}
public void setContentVersion(long version) {
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
RepositoryUtil.updateVersion(connectionSource, VERSION_ENTITY_NAME + "Content", version);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public long getContentVersionConstant() {
return EXPANSION_CONTENT_VERSION;
}
}

View file

@ -2,8 +2,10 @@ package mage.cards.repository;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import java.sql.SQLException;
@ -31,4 +33,38 @@ public class RepositoryUtil {
}
return dbVersions.isEmpty();
}
public static void updateVersion(ConnectionSource connectionSource, String entityName, long version) throws SQLException {
TableUtils.createTableIfNotExists(connectionSource, DatabaseVersion.class);
Dao<DatabaseVersion, Object> dbVersionDao = DaoManager.createDao(connectionSource, DatabaseVersion.class);
QueryBuilder<DatabaseVersion, Object> queryBuilder = dbVersionDao.queryBuilder();
queryBuilder.where().eq("entity", new SelectArg(entityName));
List<DatabaseVersion> dbVersions = dbVersionDao.query(queryBuilder.prepare());
if (!dbVersions.isEmpty()) {
DeleteBuilder<DatabaseVersion, Object> deleteBuilder = dbVersionDao.deleteBuilder();
deleteBuilder.where().eq("entity", new SelectArg(entityName));
deleteBuilder.delete();
}
DatabaseVersion databaseVersion = new DatabaseVersion();
databaseVersion.setEntity(entityName);
databaseVersion.setVersion(version);
dbVersionDao.create(databaseVersion);
}
public static long getDatabaseVersion(ConnectionSource connectionSource, String entityName) throws SQLException {
Dao<DatabaseVersion, Object> dbVersionDao = DaoManager.createDao(connectionSource, DatabaseVersion.class);
QueryBuilder<DatabaseVersion, Object> queryBuilder = dbVersionDao.queryBuilder();
queryBuilder.where().eq("entity", new SelectArg(entityName));
List<DatabaseVersion> dbVersions = dbVersionDao.query(queryBuilder.prepare());
if (dbVersions.isEmpty()) {
return 0;
} else {
return dbVersions.get(0). getVersion();
}
}
}