diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 8502d43a83a..83a272131c8 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -733,7 +733,8 @@ public class MageFrame extends javax.swing.JFrame implements Client { private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed if (session.getState() == SessionState.CONNECTED) { if (JOptionPane.showConfirmDialog(this, "Are you sure you want to disconnect?", "Confirm disconnect", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { - session.disconnect(true); + session.disconnect(false); + showMessage("You have disconnected"); } } else { connectDialog.showDialog(); @@ -747,7 +748,7 @@ public class MageFrame extends javax.swing.JFrame implements Client { }//GEN-LAST:event_btnAboutActionPerformed public void exitApp() { - session.disconnect(true); + session.disconnect(false); Plugins.getInstance().shutdown(); dispose(); System.exit(0); @@ -915,12 +916,12 @@ public class MageFrame extends javax.swing.JFrame implements Client { @Override public void showMessage(String message) { - JOptionPane.showMessageDialog(desktopPane, message); + JOptionPane.showMessageDialog(this, message); } @Override public void showError(String message) { - JOptionPane.showMessageDialog(desktopPane, message, "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE); } @Override diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanel.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanel.java index 6347ba71818..d9f74827da0 100644 --- a/Mage.Client/src/main/java/mage/client/chat/ChatPanel.java +++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanel.java @@ -80,7 +80,8 @@ public class ChatPanel extends javax.swing.JPanel { } public void disconnect() { - session.leaveChat(chatId); + if (session != null) + session.leaveChat(chatId); } public void receiveMessage(String message, MessageColor color) { diff --git a/Mage.Common/src/mage/interfaces/callback/CallbackClientDaemon.java b/Mage.Common/src/mage/interfaces/callback/CallbackClientDaemon.java index ff0e2b6a2c8..ed75f8cccc2 100644 --- a/Mage.Common/src/mage/interfaces/callback/CallbackClientDaemon.java +++ b/Mage.Common/src/mage/interfaces/callback/CallbackClientDaemon.java @@ -44,7 +44,7 @@ public class CallbackClientDaemon extends Thread { private final static Logger logger = Logger.getLogger(CallbackClientDaemon.class); - private static ExecutorService callbackExecutor = Executors.newCachedThreadPool(); + private ExecutorService callbackExecutor = Executors.newFixedThreadPool(1); private final CallbackClient client; private final Connection connection; private final UUID id; @@ -67,19 +67,22 @@ public class CallbackClientDaemon extends Thread { final ClientCallback callback = callbackMethod.makeDirectCall(); Ack ackMethod = new Ack(connection, id, callback.getMessageId()); ackMethod.makeCall(); - callbackExecutor.submit( - new Runnable() { - @Override - public void run() { - try { - client.processCallback(callback); - } - catch (Exception ex) { - logger.fatal("CallbackClientDaemon error ", ex); + if (callbackExecutor.isShutdown()) + logger.fatal("Attempt to submit callback to shutdown executor"); + else + callbackExecutor.submit( + new Runnable() { + @Override + public void run() { + try { + client.processCallback(callback); + } + catch (Exception ex) { + logger.fatal("CallbackClientDaemon error ", ex); + } } } - } - ); + ); } catch (CallbackException ex) { logger.fatal("Callback failed ", ex); } diff --git a/Mage.Common/src/mage/remote/RemoteMethodCall.java b/Mage.Common/src/mage/remote/RemoteMethodCall.java index 16537b89d04..e8c124a2b23 100644 --- a/Mage.Common/src/mage/remote/RemoteMethodCall.java +++ b/Mage.Common/src/mage/remote/RemoteMethodCall.java @@ -63,6 +63,7 @@ public abstract class RemoteMethodCall extends AbstractRemoteMethodCall { @Override public T makeCall() { returnVal = null; + logger.debug("Calling: " + name); try { returnVal = super.makeCall(); } @@ -81,6 +82,7 @@ public abstract class RemoteMethodCall extends AbstractRemoteMethodCall { public T makeDirectCall() throws ServerUnavailable, MageException { T returnValue = null; + logger.debug("Calling direct: " + name); try { returnValue = super.makeCall(); } diff --git a/Mage.Common/src/mage/remote/Session.java b/Mage.Common/src/mage/remote/Session.java index 3a5911c7df3..ecd4d284e16 100644 --- a/Mage.Common/src/mage/remote/Session.java +++ b/Mage.Common/src/mage/remote/Session.java @@ -85,9 +85,7 @@ public class Session { } public synchronized boolean connect(Connection connection) { - if (this.connection != null && sessionState == SessionState.DISCONNECTED) { - disconnect(true); - } + cleanupSession(); this.connection = connection; return connect(); } @@ -128,33 +126,30 @@ public class Session { return true; } catch (Exception ex) { logger.fatal("", ex); - if (sessionState == SessionState.CONNECTING) { - disconnect(false); - client.showMessage("Unable to connect to server. " + ex.getMessage()); - } sessionState = SessionState.SERVER_UNAVAILABLE; + disconnect(false); + client.showMessage("Unable to connect to server. " + ex.getMessage()); } return false; } - public synchronized void disconnect(boolean voluntary) { - sessionState = SessionState.DISCONNECTING; + public synchronized void disconnect(boolean showMessage) { + if (sessionState == SessionState.CONNECTED) + sessionState = SessionState.DISCONNECTING; + cleanupSession(); if (connection == null) return; - if (future != null && !future.isDone()) - future.cancel(true); - try { - if (callbackDaemon != null) - callbackDaemon.stopDaemon(); - deregisterClient(); - } catch (MageException ex) { - logger.fatal("Error disconnecting ...", ex); + if (sessionState == SessionState.CONNECTED) { + try { + deregisterClient(); + } catch (Exception ex) { + logger.fatal("Error disconnecting ...", ex); + } } ServerCache.removeServerFromCache(connection); client.disconnected(); logger.info("Disconnected ... "); - if (!voluntary) { - sessionState = SessionState.SERVER_UNAVAILABLE; + if (sessionState == SessionState.SERVER_UNAVAILABLE && showMessage) { client.showError("Server error. You have been disconnected"); } else { @@ -162,6 +157,14 @@ public class Session { } } + private void cleanupSession() { + q.clear(); + if (future != null && !future.isDone()) + future.cancel(true); + if (callbackDaemon != null) + callbackDaemon.stopDaemon(); + } + private boolean handleCall(RemoteMethodCall method) { try { if (sessionState == method.getAllowedState()) { @@ -188,15 +191,16 @@ public class Session { } private UUID registerClient(String userName, UUID clientId, MageVersion version) throws MageException, ServerUnavailable { - RegisterClient method = new RegisterClient(connection, userName, clientId, version); - if (handleCall(method)) - return method.getReturnVal(); + if (sessionState == SessionState.CONNECTING) { + RegisterClient method = new RegisterClient(connection, userName, clientId, version); + return method.makeDirectCall(); + } return null; } - private void deregisterClient() throws MageException { + private void deregisterClient() throws MageException, ServerUnavailable { DeregisterClient method = new DeregisterClient(connection, sessionId); - handleCall(method); + method.makeDirectCall(); } private ServerState getServerState() { @@ -480,8 +484,9 @@ public class Session { } private void handleServerUnavailable(ServerUnavailable ex) { + sessionState = SessionState.SERVER_UNAVAILABLE; logger.fatal("server unavailable - ", ex); - disconnect(false); + disconnect(true); } private void handleGameException(GameException ex) {