Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ui for player password support #2992

Merged
merged 21 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/main/java/net/rptools/maptool/client/AppActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
import net.rptools.maptool.client.ui.io.LoadSaveImpl;
import net.rptools.maptool.client.ui.io.ProgressBarList;
import net.rptools.maptool.client.ui.io.UpdateRepoDialog;
import net.rptools.maptool.client.ui.players.PlayerDatabaseDialog;
import net.rptools.maptool.client.ui.token.TransferProgressDialog;
import net.rptools.maptool.client.ui.zone.FogUtil;
import net.rptools.maptool.client.ui.zone.ZoneRenderer;
Expand All @@ -119,6 +120,7 @@
import net.rptools.maptool.model.player.LocalPlayer;
import net.rptools.maptool.model.player.PasswordDatabaseException;
import net.rptools.maptool.model.player.PasswordFilePlayerDatabase;
import net.rptools.maptool.model.player.PersistedPlayerDatabase;
import net.rptools.maptool.model.player.Player;
import net.rptools.maptool.model.player.Player.Role;
import net.rptools.maptool.model.player.PlayerDatabase;
Expand Down Expand Up @@ -2407,9 +2409,14 @@ protected void executeAction() {
dialog.getPort(),
prefs.getServerName(),
dialog.getServer());

String password =
prefs.getUsePublicKey()
? new PasswordGenerator().getPassword()
: prefs.getPassword();
MapTool.createConnection(
config,
new LocalPlayer(prefs.getUsername(), prefs.getRole(), prefs.getPassword()),
new LocalPlayer(prefs.getUsername(), prefs.getRole(), password),
() -> {
MapTool.getFrame().hideGlassPane();
MapTool.getFrame()
Expand Down Expand Up @@ -2483,6 +2490,24 @@ public static void disconnectFromServer() {
}
}

public static final Action PLAYER_DATABASE =
new DefaultClientAction() {
{
init("action.playerDatabase");
}

@Override
public boolean isAvailable() {
return PlayerDatabaseFactory.getCurrentPlayerDatabase()
instanceof PersistedPlayerDatabase;
}

@Override
protected void executeAction() {
new PlayerDatabaseDialog().show();
}
};

public static final Action LOAD_CAMPAIGN =
new DefaultClientAction() {
{
Expand Down
11 changes: 3 additions & 8 deletions src/main/java/net/rptools/maptool/client/MapTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import java.security.spec.InvalidKeySpecException;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.imageio.spi.IIORegistry;
Expand Down Expand Up @@ -90,6 +89,7 @@
import net.rptools.maptool.model.player.Player;
import net.rptools.maptool.model.player.PlayerDatabase;
import net.rptools.maptool.model.player.PlayerDatabaseFactory;
import net.rptools.maptool.model.player.Players;
import net.rptools.maptool.protocol.syrinscape.SyrinscapeURLStreamHandler;
import net.rptools.maptool.server.MapToolServer;
import net.rptools.maptool.server.ServerCommand;
Expand Down Expand Up @@ -158,7 +158,6 @@ public enum PreferencesEvent {
private static Campaign campaign;

private static ObservableList<Player> playerList;
private static Set<Player> playerSetThreadSafe = ConcurrentHashMap.newKeySet();
private static ObservableList<TextMessage> messageList;
private static LocalPlayer player;

Expand Down Expand Up @@ -770,7 +769,7 @@ public static MapToolServer getServer() {
public static void addPlayer(Player player) {
if (!playerList.contains(player)) {
playerList.add(player);
playerSetThreadSafe.add(player);
new Players().playerSignedIn(player);

// LATER: Make this non-anonymous
playerList.sort((arg0, arg1) -> arg0.getName().compareToIgnoreCase(arg1.getName()));
Expand All @@ -797,7 +796,7 @@ public static void removePlayer(Player player) {
return;
}
playerList.remove(player);
playerSetThreadSafe.remove(player);
new Players().playerSignedOut(player);

if (MapTool.getPlayer() != null && !player.equals(MapTool.getPlayer())) {
String msg =
Expand Down Expand Up @@ -1100,10 +1099,6 @@ public static ObservableList<Player> getPlayerList() {
return playerList;
}

public static Set<Player> getPlayerSetThreadSafe() {
return playerSetThreadSafe;
}

/** Returns the list of non-gm names. */
public static List<String> getNonGMs() {
List<String> nonGMs = new ArrayList<>(playerList.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ protected JMenu createFileMenu() {
fileMenu.add(new JMenuItem(AppActions.START_SERVER));
fileMenu.add(new JMenuItem(AppActions.CONNECT_TO_SERVER));
fileMenu.add(new JMenuItem(AppActions.DISCONNECT_FROM_SERVER));
fileMenu.add(new JMenuItem(AppActions.PLAYER_DATABASE));
fileMenu.add(new JMenuItem(AppActions.SHOW_CONNECTION_INFO));
fileMenu.addSeparator();
fileMenu.add(createRecentCampaignMenu());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTabbedPane;
Expand Down Expand Up @@ -87,6 +88,15 @@ public void showDialog() {
I18N.getText("ConnectToServerDialog.msg.title"), MapTool.getFrame(), this);
bind(new ConnectToServerDialogPreferences());
getRootPane().setDefaultButton(getOKButton());
getUsePublicKeyCheckBox()
.addItemListener(
l -> {
boolean usePublicKey = getUsePublicKeyCheckBox().isSelected();
getPasswordTextField().setEnabled(!usePublicKey);
});

boolean usePublicKey = getUsePublicKeyCheckBox().isSelected();
getPasswordTextField().setEnabled(!usePublicKey);
dialog.showDialog();
}

Expand Down Expand Up @@ -251,13 +261,17 @@ public JTabbedPane getTabPane() {
return (JTabbedPane) getComponent("tabPane");
}

public JCheckBox getUsePublicKeyCheckBox() {
return (JCheckBox) getComponent("@usePublicKey");
}

private void handleOK() {
String username = getUsernameTextField().getText().trim();
if (username.length() == 0) {
MapTool.showError("ServerDialog.error.username"); // $NON-NLS-1$
return;
}
if (getPasswordTextField().getText().length() == 0) {
if (!getUsePublicKeyCheckBox().isSelected() && getPasswordTextField().getText().length() == 0) {
MapTool.showError("ServerDialog.error.noConnectPassword"); // $NON-NLS-1$
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class ConnectToServerDialogPreferences {
private static final String KEY_PASSWORD = "password";
private static final String KEY_TAB = "tab";
private static final String KEY_SERVER_NAME = "serverName";
private static final String USE_PUBLIC_KEY = "usePublicKey";

public String getUsername() {
return prefs.get(KEY_USERNAME, "");
Expand Down Expand Up @@ -87,4 +88,12 @@ public void setServerName(String host) {
public String getServerName() {
return prefs.get(KEY_SERVER_NAME, "");
}

public boolean getUsePublicKey() {
return prefs.getBoolean(USE_PUBLIC_KEY, false);
}

public void setUsePublicKey(boolean usePublicKey) {
prefs.putBoolean(USE_PUBLIC_KEY, usePublicKey);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.client.ui.javfx;

import java.io.IOException;
import java.util.ResourceBundle;
import java.util.function.BiConsumer;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javax.swing.SwingUtilities;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.language.I18N;

public class FXMLLoaderUtil {

private static final ResourceBundle RESOURCE_BUNDLE =
ResourceBundle.getBundle("net.rptools.maptool.language.i18n");

public void parentFromFXML(
String fxmlPath, BiConsumer<Parent, SwingJavaFXDialogController> callback) {
Platform.runLater(
() -> {
JFXPanel panel = new JFXPanel();
javafx.fxml.FXMLLoader loader =
new javafx.fxml.FXMLLoader(getClass().getResource(fxmlPath), RESOURCE_BUNDLE);
Parent parentControl = null;
try {
parentControl = loader.load();
SwingJavaFXDialogController controller = loader.getController();
callback.accept(parentControl, controller);
} catch (IOException e) {
MapTool.showError(I18N.getText("javafx.error.errorLoadingFXML", fxmlPath), e);
}
});
}

public void jfxPanelFromFXML(
String fxmlPath, BiConsumer<JFXPanel, SwingJavaFXDialogController> callback) {
Platform.runLater(
() -> {
JFXPanel panel = new JFXPanel();
parentFromFXML(
fxmlPath,
(parent, controller) -> {
Scene scene = new Scene(parent);
panel.setScene(scene);
SwingUtilities.invokeLater(() -> callback.accept(panel, controller));
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.client.ui.javfx;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.function.Consumer;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javax.swing.SwingUtilities;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.language.I18N;

public class SimpleSwingJavaFXDialog<T extends SwingJavaFXDialogController> {

private final String fxmlPath;
private final String title;
private SwingJavaFXDialog dialog;
private final Consumer<T> controllerCallback;

public SimpleSwingJavaFXDialog(String fxmlPath, String title, Consumer<T> callback) {
this.fxmlPath = fxmlPath;
this.title = I18N.getText(title);
this.controllerCallback = callback;
}

public SimpleSwingJavaFXDialog(String fxmlPath, String title) {
this(fxmlPath, title, c -> {} /* do nothing if no call back provided */);
}

/** Shows the dialog and its contents. This method must be called on the Swing Event thread. */
public void show() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new AssertionError(
"PlayerDatabaseDialog.show() can only be called on the Swing thread.");
}

FXMLLoaderUtil loaderUtil = new FXMLLoaderUtil();
loaderUtil.jfxPanelFromFXML(fxmlPath, this::showEDT);
}

/**
* Displays the contents of the {@link JFXPanel} in a {@link SwingJavaFXDialog}. This method must
* be called on the Swing EDT thread.
*
* @param panel the panel to display in the dialog.
* @param controller the controller class for the dialog.
*/
private void showEDT(JFXPanel panel, SwingJavaFXDialogController controller) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new AssertionError("showEDT() can only be called on the Swing thread.");
}
dialog = new SwingJavaFXDialog(I18N.getText(title), MapTool.getFrame(), panel, controller);
Platform.runLater(
() -> {
controller.registerEventHandler(this::closeDialog);
controller.init();
});
dialog.addWindowListener(
new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
controller.deregisterEventHandler(SimpleSwingJavaFXDialog.this::closeDialog);
e.getWindow().dispose();
}
});
controllerCallback.accept((T) controller);
dialog.showDialog();
}

/**
* This method closes the dialog. It is safe to call this method on any thread.
*
* @param controller the controller for the JavaFX gui.
*/
private void closeDialog(SwingJavaFXDialogController controller) {
if (SwingUtilities.isEventDispatchThread()) {
closeDialogEDT(controller);
} else {
SwingUtilities.invokeLater(() -> closeDialogEDT(controller));
}
}

/**
* This method closes the dialog It must be called only on the Swing EDT thread.
*
* @param controller the controller for the JavaFX gui.
*/
private void closeDialogEDT(SwingJavaFXDialogController controller) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new AssertionError("closeDialogEDT() can only be called on the Swing thread.");
}
dialog.closeDialog();
}

/** Closes the dialog. */
public void closeDialog() {
dialog.closeDialog();
}
}
Loading