package games.strategy.engine.lobby.client.login; import java.awt.Window; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import javax.swing.JOptionPane; import games.strategy.engine.ClientFileSystemHelper; import games.strategy.engine.lobby.client.LobbyClient; import games.strategy.engine.lobby.server.LobbyServer; import games.strategy.engine.lobby.server.login.LobbyLoginValidator; import games.strategy.net.ClientMessenger; import games.strategy.net.CouldNotLogInException; import games.strategy.net.IConnectionLogin; import games.strategy.net.MacFinder; import games.strategy.triplea.UrlConstants; import games.strategy.util.MD5Crypt; public class LobbyLogin { private final Window m_parent; private final LobbyServerProperties m_serverProperties; public LobbyLogin(final Window parent, final LobbyServerProperties properties) { m_parent = parent; m_serverProperties = properties; } /** * Attempt to login to the LobbyServer * * <p> * If we could not login, return null. * </p> */ public LobbyClient login() { if (!m_serverProperties.isServerAvailable()) { JOptionPane.showMessageDialog(m_parent, m_serverProperties.serverErrorMessage, "Could not connect to server", JOptionPane.ERROR_MESSAGE); return null; } if (m_serverProperties.port == -1) { if (ClientFileSystemHelper.areWeOldExtraJar()) { JOptionPane.showMessageDialog(m_parent, "<html>Could not find lobby server for this version of TripleA, <br>" + "Please make sure you are using the latest version: " + UrlConstants.LATEST_GAME_DOWNLOAD_WEBSITE + "<br /><br />This is because you are using an old engine that is kept for backwards compatibility. " + "<br /><b>In order to load your Old savegames in the New lobby, you must First join the lobby with " + "the latest engine, Then host a game, Then load the old savegame!</b></html>", "Could not connect to server", JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(m_parent, "<html>Could not find lobby server for this version of TripleA, <br>" + "Please make sure you are using the latest version: " + UrlConstants.LATEST_GAME_DOWNLOAD_WEBSITE + "</html>", "Could not connect to server", JOptionPane.ERROR_MESSAGE); } return null; } return loginToServer(); } private LobbyClient loginToServer() { final LoginPanel panel = new LoginPanel(); final LoginPanel.ReturnValue value = panel.show(m_parent); if (value == LoginPanel.ReturnValue.LOGON) { return login(panel); } else if (value == LoginPanel.ReturnValue.CANCEL) { return null; } else if (value == LoginPanel.ReturnValue.CREATE_ACCOUNT) { return createAccount(); } else { throw new IllegalStateException("??"); } } private LobbyClient login(final LoginPanel panel) { try { final String mac = MacFinder.getHashedMacAddress(); final ClientMessenger messenger = new ClientMessenger(m_serverProperties.host, m_serverProperties.port, panel.getUserName(), mac, new IConnectionLogin() { private final AtomicReference<String> m_internalError = new AtomicReference<>(); @Override public void notifyFailedLogin(String message) { if (m_internalError.get() != null) { message = m_internalError.get(); } JOptionPane.showMessageDialog(m_parent, message, "Login Failed", JOptionPane.ERROR_MESSAGE); } @Override public Map<String, String> getProperties(final Map<String, String> challengProperties) { final Map<String, String> props = new HashMap<>(); if (panel.isAnonymous()) { props.put(LobbyLoginValidator.ANONYMOUS_LOGIN, Boolean.TRUE.toString()); } else { String salt = challengProperties.get(LobbyLoginValidator.SALT_KEY); if (salt == null) { // the server does not have a salt value // so there is no user with our name, // continue as before m_internalError.set("No account with that name exists"); salt = "none"; } final String hashedPassword = MD5Crypt.crypt(panel.getPassword(), salt); props.put(LobbyLoginValidator.HASHED_PASSWORD_KEY, hashedPassword); } props.put(LobbyLoginValidator.LOBBY_VERSION, LobbyServer.LOBBY_VERSION.toString()); return props; } }); // sucess, store prefs LoginPanel.storePrefs(panel.getUserName(), panel.isAnonymous()); return new LobbyClient(messenger, panel.isAnonymous()); } catch (final CouldNotLogInException clne) { // this has already been dealt with return loginToServer(); } catch (final IOException ioe) { JOptionPane.showMessageDialog(m_parent, "Could Not Connect to Lobby : " + ioe.getMessage(), "Could not connect", JOptionPane.ERROR_MESSAGE); return null; } } private LobbyClient createAccount() { final CreateUpdateAccountPanel createAccount = CreateUpdateAccountPanel.newCreatePanel(); final CreateUpdateAccountPanel.ReturnValue value = createAccount.show(m_parent); if (value == CreateUpdateAccountPanel.ReturnValue.OK) { return createAccount(createAccount); } else { return null; } } private LobbyClient createAccount(final CreateUpdateAccountPanel createAccount) { try { final String mac = MacFinder.getHashedMacAddress(); final ClientMessenger messenger = new ClientMessenger(m_serverProperties.host, m_serverProperties.port, createAccount.getUserName(), mac, new IConnectionLogin() { @Override public void notifyFailedLogin(final String message) { JOptionPane.showMessageDialog(m_parent, message, "Login Failed", JOptionPane.ERROR_MESSAGE); } @Override public Map<String, String> getProperties(final Map<String, String> challengProperties) { final Map<String, String> props = new HashMap<>(); props.put(LobbyLoginValidator.REGISTER_NEW_USER_KEY, Boolean.TRUE.toString()); props.put(LobbyLoginValidator.EMAIL_KEY, createAccount.getEmail()); props.put(LobbyLoginValidator.HASHED_PASSWORD_KEY, MD5Crypt.crypt(createAccount.getPassword())); props.put(LobbyLoginValidator.LOBBY_VERSION, LobbyServer.LOBBY_VERSION.toString()); return props; } }); // default LoginPanel.storePrefs(createAccount.getUserName(), false); return new LobbyClient(messenger, false); } catch (final CouldNotLogInException clne) { // this has already been dealt with return createAccount(); } catch (final IOException ioe) { JOptionPane.showMessageDialog(m_parent, ioe.getMessage(), "Account creation failed", JOptionPane.ERROR_MESSAGE); return null; } } }