Package games.stendhal.client.gui.login

Source Code of games.stendhal.client.gui.login.LoginDialog$SaveProfileStateCB

/* $Id: LoginDialog.java,v 1.31 2011/04/07 20:50:40 kiheru Exp $ */
/***************************************************************************
*                      (C) Copyright 2003 - Marauroa                      *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.client.gui.login;

import games.stendhal.client.StendhalClient;
import games.stendhal.client.stendhal;
import games.stendhal.client.gui.ProgressBar;
import games.stendhal.client.gui.layout.SBoxLayout;
import games.stendhal.client.update.ClientGameConfiguration;

import java.awt.Component;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import marauroa.client.BannedAddressException;
import marauroa.client.LoginFailedException;
import marauroa.client.TimeoutException;
import marauroa.common.io.Persistence;
import marauroa.common.net.InvalidVersionException;
import marauroa.common.net.message.MessageS2CLoginNACK;

import org.apache.log4j.Logger;

/**
* Server login dialog.
*
*/
public class LoginDialog extends JDialog {
 
  private static final long serialVersionUID = -1182930046629241075L;

  protected ProfileList profiles;
 
  private JComboBox profilesComboBox;

  private JCheckBox saveLoginBox;

  private JCheckBox savePasswordBox;

  private JTextField usernameField;

  private JPasswordField passwordField;

  private JTextField serverField;

  private JTextField serverPortField;

  private JButton loginButton;

  private JButton removeButton;

  private JPanel contentPane;

  // End of variables declaration
  private final StendhalClient client;

  private final Frame owner;

  private ProgressBar progressBar;

  public LoginDialog(final Frame owner, final StendhalClient client) {
    super(owner, true);
    this.client = client;
    this.owner = owner;
    initializeComponent();
  }

  private void initializeComponent() {
    this.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        if (owner == null) {
          System.exit(0);
        }
        owner.setEnabled(true);
        dispose();
      }
    });

    JLabel l;

    this.setTitle("Login to Server");
    this.setResizable(false);

    //
    // contentPane
    //
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(new GridBagLayout());
    final int pad = SBoxLayout.COMMON_PADDING;
    contentPane.setBorder(BorderFactory.createEmptyBorder(pad, pad, pad, pad));

    final GridBagConstraints c = new GridBagConstraints();
    c.anchor = GridBagConstraints.LINE_START;

    /*
     * Profiles
     */
    l = new JLabel("Account profiles");

    c.insets = new Insets(4, 4, 15, 4);
    // column
    c.gridx = 0;
     // row
    c.gridy = 0;
    contentPane.add(l, c);

    profilesComboBox = new JComboBox();
    profilesComboBox.addActionListener(new ProfilesCB());
   
    /*
     * Remove profile button
     */
    removeButton = createRemoveButton();
   
    // Container for the profiles list and the remove button
    JComponent box = SBoxLayout.createContainer(SBoxLayout.HORIZONTAL, pad);
    profilesComboBox.setAlignmentY(Component.CENTER_ALIGNMENT);
    box.add(profilesComboBox);
    box.add(removeButton);

    c.gridx = 1;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;
    contentPane.add(box, c);

    /*
     * Server Host
     */
    l = new JLabel("Server name");
    c.insets = new Insets(4, 4, 4, 4);
    // column
    c.gridx = 0;
     // row
    c.gridy = 1;
    contentPane.add(l, c);

    serverField = new JTextField(
        ClientGameConfiguration.get("DEFAULT_SERVER"));
    c.gridx = 1;
    c.gridy = 1;
    c.fill = GridBagConstraints.BOTH;
    contentPane.add(serverField, c);

    /*
     * Server Port
     */
    l = new JLabel("Server port");
    c.insets = new Insets(4, 4, 4, 4);
    c.gridx = 0;
    c.gridy = 2;
    contentPane.add(l, c);

    serverPortField = new JTextField(
        ClientGameConfiguration.get("DEFAULT_PORT"));
    c.gridx = 1;
    c.gridy = 2;
    c.insets = new Insets(4, 4, 4, 4);
    c.fill = GridBagConstraints.BOTH;
    contentPane.add(serverPortField, c);

    /*
     * Username
     */
    l = new JLabel("Type your username");
    c.insets = new Insets(4, 4, 4, 4);
    c.gridx = 0;
    c.gridy = 3;
    contentPane.add(l, c);

    usernameField = new JTextField();
 
    c.gridx = 1;
    c.gridy = 3;
    c.fill = GridBagConstraints.BOTH;
    contentPane.add(usernameField, c);

    /*
     * Password
     */
    l = new JLabel("Type your password");

    c.gridx = 0;
    c.gridy = 4;
    c.fill = GridBagConstraints.NONE;
    contentPane.add(l, c);

    passwordField = new JPasswordField();

    c.gridx = 1;
    c.gridy = 4;
    c.fill = GridBagConstraints.BOTH;
    contentPane.add(passwordField, c);

    /*
     * Save Profile/Login
     */
    saveLoginBox = new JCheckBox("Save login profile locally");
    saveLoginBox.setSelected(false);

    c.gridx = 0;
    c.gridy = 5;
    c.fill = GridBagConstraints.NONE;
    contentPane.add(saveLoginBox, c);

    /*
     * Save Profile Password
     */
    savePasswordBox = new JCheckBox("Save password");
    savePasswordBox.setSelected(true);
    savePasswordBox.setEnabled(false);

    c.gridx = 0;
    c.gridy = 6;
    c.fill = GridBagConstraints.NONE;
    c.insets = new Insets(0, 20, 0, 0);
    contentPane.add(savePasswordBox, c);

    loginButton = new JButton();
    loginButton.setText("Login to Server");
    loginButton.setMnemonic(KeyEvent.VK_L);
    this.rootPane.setDefaultButton(loginButton);

    loginButton.addActionListener(new ActionListener() {

      public void actionPerformed(final ActionEvent e) {
        loginButton_actionPerformed(e);
      }
    });

    c.gridx = 1;
    c.gridy = 5;
    c.gridheight = 2;
    c.anchor = GridBagConstraints.CENTER;
    c.insets = new Insets(15, 4, 4, 4);
    contentPane.add(loginButton, c);

    /*
     * Load saved profiles
     */
    profiles = loadProfiles();
    populateProfiles(profiles);

    /*
     * Add this callback after everything is initialized
     */
    saveLoginBox.addChangeListener(new SaveProfileStateCB());

    //
    // Dialog
    //

    this.pack();
    usernameField.requestFocusInWindow();
    if (owner != null) {
      owner.setEnabled(false);
      this.setLocationRelativeTo(owner);
    }
  }
 
  /**
   * Create the remove character button.
   *
   * @return JButton
   */
  private JButton createRemoveButton() {
    final URL url = getClass().getClassLoader().getResource("data/gui/trash.png");
    ImageIcon icon = new ImageIcon(url);
    JButton button = new JButton(icon);
    // Clear the margins that buttons normally add
    button.setMargin(new Insets(0, 0, 0, 0));
    button.setToolTipText("Remove the selected account from the list");

    button.addActionListener(new ActionListener() {

      public void actionPerformed(final ActionEvent e) {
        removeButton_actionPerformed(e);
      }
    });
   
    return button;
  }

  private void loginButton_actionPerformed(final ActionEvent e) {
    // If this window isn't enabled, we shouldn't act.
    if (!isEnabled()) {
      return;
    }
    setEnabled(false);

    Profile profile;
    profile = new Profile();

    profile.setHost((serverField.getText()).trim());

    try {
      profile.setPort(Integer.parseInt(serverPortField.getText().trim()));

      // Support for saving port number. Only save when input is a number
      // intensifly@gmx.com

    } catch (final NumberFormatException ex) {
      JOptionPane.showMessageDialog(this,
          "That is not a valid port number. Please try again.",
          "Invalid port", JOptionPane.WARNING_MESSAGE);
      return;
    }

    profile.setUser(usernameField.getText().trim());
    profile.setPassword(new String(passwordField.getPassword()));

    /*
     * Save profile?
     */
    if (saveLoginBox.isSelected()) {
      profiles.add(profile);
      populateProfiles(profiles);

      if (savePasswordBox.isSelected()) {
        saveProfiles(profiles);
      } else {
        final String pw = profile.getPassword();
        profile.setPassword("");
        saveProfiles(profiles);
        profile.setPassword(pw);
      }

    }

    /*
     * Run the connection procces in separate thread. added by TheGeneral
     */
    final Thread t = new Thread(new ConnectRunnable(profile));
    t.start();
  }

  private void removeButton_actionPerformed(final ActionEvent e) {
    // If this window isn't enabled, we shouldn't act.
    if (!isEnabled() || (profiles.profiles.size() == 0)) {
      return;
    }
    setEnabled(false);

    Profile profile;

    profile = (Profile) profilesComboBox.getSelectedItem();
    Object[] options = { "Remove", "Cancel" };

    Integer confirmRemoveProfile = (Integer)JOptionPane.showOptionDialog(this,
      "This will permanently remove a user profile from your local list of accounts.\n"
      + "It will not delete an account on any servers.\n"
      + "Are you sure you want to remove \'" + profile.getUser() + "@" + profile.getHost() + "\' profile?",
      "Remove user profile from local list of accounts",
      JOptionPane.OK_CANCEL_OPTION,
      JOptionPane.QUESTION_MESSAGE,
      null,
      options,
      options[1]);

    if ( confirmRemoveProfile == 0 ) {
      profiles.remove(profile);
      saveProfiles(profiles);
      profiles = loadProfiles();
      populateProfiles(profiles);
    }

    setEnabled(true);
  }

  @Override
  public void setEnabled(final boolean b) {
    super.setEnabled(b);
    loginButton.setEnabled(b);
    removeButton.setEnabled(b);
  }
  /**
   * Connect to a server using a given profile.
   * @param profile
   */
  public void connect(final Profile profile) {
    // We are not in EDT
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        progressBar = new ProgressBar(LoginDialog.this);
        progressBar.start();
        // disable this screen when attempting to connect
        setEnabled(false);
      }
    });

    try {
      client.connect(profile.getHost(), profile.getPort());

      // for each major connection milestone call step(). progressBar is
      // created in EDT, so it is not guaranteed non null in the main
      // thread.
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          progressBar.step();
        }
      });
    } catch (final Exception ex) {
      // if something goes horribly just cancel the progressbar
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          progressBar.cancel();
          setEnabled(true);
        }
      });
      String message = "unable to connect to server";
     
      if (profile != null) {
        message = message + " " + profile.getHost() + ":" + profile.getPort();
      } else {
        message = message + ", because profile was null";
      }
      Logger.getLogger(LoginDialog.class).error(message, ex);
      handleError("Unable to connect to server. Did you misspell the server name?", "Connection failed");
      return;
    }

    try {
      client.setAccountUsername(profile.getUser());
      client.setCharacter(profile.getCharacter());
      client.login(profile.getUser(), profile.getPassword(), profile.getSeed());

      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          progressBar.step();
          progressBar.finish();
          setVisible(false);
        }
      });
    } catch (final InvalidVersionException e) {
      handleError("You are running an incompatible version of Stendhal. Please update",
          "Invalid version");
    } catch (final TimeoutException e) {
      handleError("Server is not available right now.\nThe server may be down or, if you are using a custom server,\nyou may have entered its name and port number incorrectly.",
          "Error Logging In");
    } catch (final LoginFailedException e) {
      handleError(e.getMessage(), "Login failed");
      if (e.getReason() == MessageS2CLoginNACK.Reasons.SEED_WRONG) {
        System.exit(1);
      }
    } catch (final BannedAddressException e) {
      handleError("Your IP is banned. If you think this is not right, please send a Support Request to http://sourceforge.net/tracker/?func=add&group_id=1111&atid=201111",
          "IP Banned");
    }
  }

  /**
   * Displays the error message, removes the progress bar and
   * either enabled the login dialog in interactive mode or exits
   * the client in non interactive mode.
   *
   * @param errorMessage error message
   * @param errorTitle   title of error dialog box
   */
  private void handleError(final String errorMessage, final String errorTitle) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        progressBar.cancel();
        JOptionPane.showMessageDialog(
            LoginDialog.this, errorMessage, errorTitle, JOptionPane.ERROR_MESSAGE);

        if (isVisible()) {
          setEnabled(true);
        } else {
          // Hack for non interactive login
          System.exit(1);
        }
      }
    });
  }

  /**
   * Load saves profiles.
   * @return ProfileList
   */
  private ProfileList loadProfiles() {
    final ProfileList tmpProfiles = new ProfileList();

    try {
      final InputStream is = Persistence.get().getInputStream(false, stendhal.getGameFolder(),
          "user.dat");

      try {
        tmpProfiles.load(is);
      } finally {
        is.close();
      }
    } catch (final FileNotFoundException fnfe) {
      // Ignore
    } catch (final IOException ioex) {
      JOptionPane.showMessageDialog(this,
          "An error occurred while loading your login information",
          "Error Loading Login Information",
          JOptionPane.WARNING_MESSAGE);
    }

    return tmpProfiles;
  }

  /**
   * Populate the profiles combobox and select the default.
   * @param profiles
   */
  protected void populateProfiles(final ProfileList profiles) {
    profilesComboBox.removeAllItems();

    final Iterator< ? > iter = profiles.iterator();

    while (iter.hasNext()) {
      profilesComboBox.addItem(iter.next());
    }

    /*
     * The last profile (if any) is the default.
     */
    final int count = profilesComboBox.getItemCount();
    if (count != 0) {
      profilesComboBox.setSelectedIndex(count - 1);
    }
  }

  /**
   * Called when a profile selection is changed.
   */
  protected void profilesCB() {
    Profile profile;
    String host;

    profile = (Profile) profilesComboBox.getSelectedItem();

    if (profile != null) {
      host = profile.getHost();
      serverField.setText(host);

      serverPortField.setText(String.valueOf(profile.getPort()));

      usernameField.setText(profile.getUser());
      passwordField.setText(profile.getPassword());
    } else {

      serverPortField.setText(String.valueOf(Profile.DEFAULT_SERVER_PORT));

      usernameField.setText("");
      passwordField.setText("");
    }
  }

  /*
   * Author: Da_MusH Description: Methods for saving and loading login
   * information to disk. These should probably make a separate class in the
   * future, but it will work for now. comment: Thegeneral has added encoding
   * for password and username. Changed for multiple profiles.
   */
  private void saveProfiles(final ProfileList profiles) {
    try {
      final OutputStream os = Persistence.get().getOutputStream(false,
          stendhal.getGameFolder(), "user.dat");

      try {
        profiles.save(os);
      } finally {
        os.close();
      }
    } catch (final IOException ioex) {
      JOptionPane.showMessageDialog(this,
          "An error occurred while saving your login information",
          "Error Saving Login Information",
          JOptionPane.WARNING_MESSAGE);
    }
  }

  /**
   * Called when save profile selection change.
   */
  protected void saveProfileStateCB() {
    savePasswordBox.setEnabled(saveLoginBox.isSelected());
  }

  /**
   * Server connect thread runnable.
   */
  protected class ConnectRunnable implements Runnable {

    protected Profile profile;

    public ConnectRunnable(final Profile profile) {
      this.profile = profile;
    }

    public void run() {
      connect(profile);
    }
  }

  /**
   * Profiles combobox selection change listener.
   */
  protected class ProfilesCB implements ActionListener {

    public void actionPerformed(final ActionEvent e) {
      profilesCB();
    }
  }

  /**
   * Save profile selection change.
   */
  protected class SaveProfileStateCB implements ChangeListener {

    public void stateChanged(final ChangeEvent ev) {
      saveProfileStateCB();
    }
  }
}
TOP

Related Classes of games.stendhal.client.gui.login.LoginDialog$SaveProfileStateCB

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.