From f223bdab3172c1ebccfed1420972a5a538eda908 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 18 Jan 2019 13:32:37 +0400 Subject: [PATCH] Added new client-server incompatible checks: * added strict mode (client and server versions must be same, see MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME); * you must enable string mode after github code changes in serializeable classes (see #4459); * added client-side version checks; * added error message on wrong version disconnects. --- .../src/main/java/mage/client/MageFrame.java | 2 +- .../main/java/mage/client/SessionHandler.java | 18 ++++++++++--- .../mage/client/dialog/ConnectDialog.java | 7 ++++-- .../main/java/mage/remote/SessionImpl.java | 25 ++++++++++++++++--- .../java/mage/remote/interfaces/Connect.java | 5 ++-- .../src/main/java/mage/utils/MageVersion.java | 8 ++++-- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 1fa1ee81a2..fef0dfef0b 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -767,7 +767,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { prepareAndShowTablesPane(); return true; } else { - showMessage("Unable connect to server"); + showMessage("Unable connect to server: " + SessionHandler.getLastConnectError()); } } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); diff --git a/Mage.Client/src/main/java/mage/client/SessionHandler.java b/Mage.Client/src/main/java/mage/client/SessionHandler.java index 8524b125da..02962d9489 100644 --- a/Mage.Client/src/main/java/mage/client/SessionHandler.java +++ b/Mage.Client/src/main/java/mage/client/SessionHandler.java @@ -1,6 +1,5 @@ package mage.client; -import java.util.*; import mage.cards.decks.DeckCardLists; import mage.client.chat.LocalCommands; import mage.client.dialog.PreferencesDialog; @@ -16,19 +15,22 @@ import mage.remote.Session; import mage.remote.SessionImpl; import mage.view.*; +import java.util.*; + /** * Created by IGOUDT on 15-9-2016. */ public final class SessionHandler { private static Session session; + private static String lastConnectError = ""; public static void startSession(MageFrame mageFrame) { session = new SessionImpl(mageFrame); session.setJsonLogActive("true".equals(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_LOG_AUTO_SAVE, "true"))); } - + public static void ping() { session.ping(); } @@ -46,7 +48,17 @@ public final class SessionHandler { } public static boolean connect(Connection connection) { - return session.connect(connection); + lastConnectError = ""; + if (session.connect(connection)) { + return true; + } else { + lastConnectError = session.getLastError(); + return false; + } + } + + public static String getLastConnectError() { + return lastConnectError; } public static boolean stopConnecting() { diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index 7d932d99e5..a0ee45ce2b 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -10,6 +10,7 @@ import mage.cards.repository.ExpansionRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.client.MageFrame; +import mage.client.SessionHandler; import mage.client.preference.MagePreferences; import mage.client.util.Config; import mage.client.util.gui.countryBox.CountryItemEditor; @@ -513,7 +514,7 @@ public class ConnectDialog extends MageDialog { connection.setForceDBComparison(this.chkForceUpdateDB.isSelected() || redownloadDatabase); String allMAC = ""; try { - allMAC = connection.getMAC(); + allMAC = Connection.getMAC(); } catch (SocketException ex) { } connection.setUserIdStr(System.getProperty("user.name") + ":" + System.getProperty("os.name") + ":" + MagePreferences.getUserNames() + ":" + allMAC); @@ -535,6 +536,7 @@ public class ConnectDialog extends MageDialog { private class ConnectTask extends SwingWorker { private boolean result = false; + private String lastConnectError = ""; private static final int CONNECTION_TIMEOUT_MS = 2100; @@ -543,6 +545,7 @@ public class ConnectDialog extends MageDialog { lblStatus.setText("Connecting..."); btnConnect.setEnabled(false); result = MageFrame.connect(connection); + lastConnectError = SessionHandler.getLastConnectError(); return result; } @@ -556,7 +559,7 @@ public class ConnectDialog extends MageDialog { connected(); MageFrame.getInstance().prepareAndShowTablesPane(); } else { - lblStatus.setText("Could not connect"); + lblStatus.setText("Could not connect: " + lastConnectError); } } catch (InterruptedException ex) { logger.fatal("Update Players Task error", ex); diff --git a/Mage.Common/src/main/java/mage/remote/SessionImpl.java b/Mage.Common/src/main/java/mage/remote/SessionImpl.java index 45f0b0c5be..38439c01a5 100644 --- a/Mage.Common/src/main/java/mage/remote/SessionImpl.java +++ b/Mage.Common/src/main/java/mage/remote/SessionImpl.java @@ -61,6 +61,7 @@ public class SessionImpl implements Session { private boolean canceled = false; private boolean jsonLogActive = false; + private String lastError = ""; static { debugMode = System.getProperty("debug.mage") != null; @@ -195,20 +196,29 @@ public class SessionImpl implements Session { && handleRemotingTaskExceptions(new RemotingTask() { @Override public boolean run() throws Throwable { + setLastError(""); logger.info("Trying to log-in as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort()); boolean registerResult; if (connection.getAdminPassword() == null) { // for backward compatibility. don't remove twice call - first one does nothing but for version checking registerResult = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr()); - if (registerResult) { - server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr()); - } } else { registerResult = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion()); } if (registerResult) { serverState = server.getServerState(); + + // client side check for incompatible versions + if (client.getVersion().compareTo(serverState.getVersion()) != 0) { + String err = "Client and server versions are incompatible."; + setLastError(err); + logger.info(err); + disconnect(false); + return false; + } + if (!connection.getUsername().equals("Admin")) { + server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr()); updateDatabase(connection.isForceDBComparison(), serverState); } logger.info("Logged-in as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort()); @@ -1621,6 +1631,15 @@ public class SessionImpl implements Session { this.jsonLogActive = jsonLogActive; } + private void setLastError(String error) { + lastError = error; + } + + @Override + public String getLastError() { + return lastError; + } + } class MageAuthenticator extends Authenticator { diff --git a/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java b/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java index 747f5e63c5..4795578ffc 100644 --- a/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java +++ b/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java @@ -1,4 +1,3 @@ - package mage.remote.interfaces; import mage.remote.Connection; @@ -37,10 +36,12 @@ public interface Connect { boolean muteUserChat(String userName, long durationMinute); boolean setActivation(String userName, boolean active); - + boolean toggleActivation(String userName); boolean lockUser(String userName, long durationMinute); String getSessionId(); + + String getLastError(); } diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 284ea65ef1..2ad341ebc7 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -16,7 +16,9 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 33; public final static String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0 - public final static String MAGE_VERSION_MINOR_PATCH = "V0"; + public final static String MAGE_VERSION_MINOR_PATCH = "V1"; // default V0 + // strict mode + private final static boolean MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME = true; // set true on uncompatible github changes, set false after new major release (after MAGE_VERSION_PATCH changes) private final int major; private final int minor; @@ -74,7 +76,9 @@ public class MageVersion implements Serializable, Comparable { if (patch != o.patch) { return patch - o.patch; } + if (MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME && !minorPatch.equals(o.minorPatch)) { + return minorPatch.compareTo(o.minorPatch); + } return editionInfo.compareTo(o.editionInfo); } - }