Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d7d6ca4
Retain serviceIdentifier in MapToolServer objects
fishface60 Jan 19, 2025
08ca39b
Factor connect impl out of CONNECT_TO_SERVER action
fishface60 Nov 25, 2024
6f0be64
Remove role from ConnectToServerDialogPreferences
fishface60 Nov 25, 2024
48b641b
Add role-less LocalPlayer constructor
fishface60 Nov 25, 2024
723d95e
Don't reuse ServerConfig for client connections
fishface60 Nov 25, 2024
628c5f4
Use stricter types for RemoteServerConfig
fishface60 Nov 25, 2024
2a37ed2
Make connectToServer callers create RemoteServerConfig
fishface60 Nov 25, 2024
f6eb81d
Add misc nullibility annotations
fishface60 Dec 8, 2024
2e844c2
Fix typo Sever -> Server
fishface60 Nov 24, 2024
51b39c7
Replace ServerConnectionDetails with RemoteServerConfig
fishface60 Nov 26, 2024
8cb3176
Add MapToolServiceFinder abstraction
fishface60 Dec 2, 2024
c75643b
Add click redirector to MapToolRegistry
fishface60 Jan 19, 2025
ee87773
Add ServerAddress abstraction
fishface60 Jan 14, 2025
c2e1258
Handle rptools-maptool URI in positional arguments
fishface60 Nov 26, 2024
9376e76
Override desktop entry on Linux to add URI handler
fishface60 Nov 29, 2024
7624fa0
Fix connection information showing only ipv6
fishface60 Dec 3, 2024
22c3c9f
Make MapToolRegistry.getAddress return InetAddress
fishface60 Dec 3, 2024
9472e7d
Make MapToolRegistry.getAddressAsync return CompletableFuture
fishface60 Dec 3, 2024
d5714e0
Move cached external addr getter out of UI
fishface60 Dec 3, 2024
7b0471e
Run concurrent external IP fetches with invokeAny
fishface60 Dec 4, 2024
93d2da7
Implement missing reachability check
fishface60 Dec 6, 2024
0443325
Sort addresses by reachability and pick the most
fishface60 Dec 6, 2024
109544c
Move getLocalAddresses to NetUtil
fishface60 Dec 8, 2024
3626d66
Remove Abeille guide and unused XML
fishface60 Jan 12, 2025
6696c85
Add LAN ID and connect link buttons to ConnectionInfoDialog
fishface60 Jan 14, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ out/
# Automatically Generated
################################################################################
package/windows/MapTool.iss
package/linux/MapTool*.desktop


# IDEs
Expand Down
20 changes: 20 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,26 @@ classes.configure {
dependsOn instrumentForms
}


if (osdetector.os.is('linux')) {
def generateDesktop = tasks.register('generateDesktop', Copy) {
from 'package/linux/launcher.desktop'
into 'package/linux/'
expand(
description: project.description,
projectName: project.name,
developerRelease: developerRelease
)
filteringCharset = 'UTF-8'
rename { fileName ->
project.name + developerRelease + '.desktop'
}
}

tasks.jpackageImage.dependsOn generateDesktop
tasks.spotlessMisc.dependsOn generateDesktop
}

// Workaround the runtime plugin's hardcoded dependencies on the shadow plugin. It sneakily
// (dynamically) adds dependencies when shadow is detected, but we don't want it to do that since we
// only use shadow for a completely separate build artifact.
Expand Down
13 changes: 2 additions & 11 deletions doc/How_To_Setup_UI_Tools.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
How To Setup User Interface (UI) Tools for MapTool
==================================================

You thought you were done? Sorry, there are two extra things you may wish to consider and both are related to managing UI elements within Maptool. The current edition of the tool uses **Abeille** to manage **Swing** elements within the design. Abeille is a WYSIWYG form designer for Swing objects and if you plan on modifying any of the UI elements you should definitely install the Abeille Designer.
You thought you were done? Sorry, there are two extra things you may wish to consider and both are related to managing UI elements within Maptool. The current edition of the tool uses **IntelliJ** to manage **Swing** elements within the design. Just open the `.form` files and install the plugin when prompted.

As Swing is now deprecated within Java the plan is to move those elements over to **JavaFX**, although this work is further down the line at the moment. If you want to get to grips with JavaFX, you should probably install the Eclipse Plugin **e(fx)clipse** and the **JavaFX Scene Builder**. Scene Builder is also a WYSIWYG form designer, but this time for JavaFX Objects.

Install Abeille
----------------

1. Go to the [Abeille Downloads page](https://java.net/projects/abeille/downloads/directory/Abeille%20Form%20Designer%202.1.0%20M3) and download the latest binaries. This is a closed project so they are quite old. The binaries are jar files so you can simply unzip the folder to anywhere on your PC, such as `C:\Program Files (x86)\abeille-2.1.0_M3`
* As the Abeille downloads are now offline the last version has been attached here: [abeille-2.1.0_M3.zip](https://github.com/RPTools/maptool/files/6554805/abeille-2.1.0_M3.zip)
2. Launch the Designer by running the `designer.jar` file in the `abeille-2.1.0_M3` directory. If you have installed Java as described elsewhere, you can just right click the file and select **Open**
3. Once the Designer is running, you need to create a new project for the MapTool forms. Call this file `maptool.jfpr` and save it anywhere you like, BUT NOT in the Eclipse MapTool project directory, as you do not want this file to become part of the MapTool project and is only used by you locally.
4. Add the MapTool resource directory as a Source path for your Abeille Project. On the Abeille Project Settings screen you should see a button in the Source Tab to **Add Path**. Click this and navigate to the resource directory. For example, if your Eclipse workspace directory was `C:\Workspace` and your top level MapTool project was called `C:\Workspace\maptool` you should add the path `C:\Workspace\maptool\maptool\src\main\resources`. This is very important, otherwise the Albeille Designer will save the local path names into the designer files rather than the relative paths that are needed for proper distribution.

Install e(fx)clipse Plugin
--------------------------

Expand All @@ -29,4 +20,4 @@ Install JavaFX Scene Builder

The JavaFX Scene Builder application has been handed over to the open source community and as a consequence it can be hard to find the Scene Builder install. The latest version as of this writing is SceneBuilder 10.0.0 and is available from [GluonHQ.com](https://gluonhq.com/products/scene-builder/)

Download and install SceneBuilder. It can now be used to open **.fxml** files which are the JavaFX equivalent to Abeille files (above).
Download and install SceneBuilder. It can now be used to open **.fxml** files which are the JavaFX equivalent to `.form` files (above).
9 changes: 9 additions & 0 deletions package/linux/launcher.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Desktop Entry]
Name=${projectName}
Comment=${description}
Exec=/opt/maptool/bin/${projectName}${developerRelease} %u
Icon=/opt/maptool/lib/${projectName}${developerRelease}.png
Terminal=false
Type=Application
Categories=Game
MimeType=application/maptool;x-scheme-handler/rptools-maptool+registry;x-scheme-handler/rptools-maptool+lan;x-scheme-handler/rptools-maptool+tcp
33 changes: 19 additions & 14 deletions src/main/java/net/rptools/clientserver/ConnectionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package net.rptools.clientserver;

import java.awt.EventQueue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.rptools.clientserver.simple.connection.Connection;
import net.rptools.clientserver.simple.connection.SocketConnection;
Expand All @@ -24,6 +25,7 @@
import net.rptools.clientserver.simple.server.SocketServer;
import net.rptools.clientserver.simple.server.WebRTCServer;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.client.RemoteServerConfig;
import net.rptools.maptool.server.ServerConfig;

public class ConnectionFactory {
Expand All @@ -33,22 +35,25 @@ public static ConnectionFactory getInstance() {
return instance;
}

public Connection createConnection(String id, ServerConfig config) {
if (!config.getUseWebRTC()) {
return new SocketConnection(id, config.getHostName(), config.getPort());
}

return new WebRTCConnection(
id,
config.getServerName(),
new WebRTCConnection.Listener() {
@Override
public void onLoginError() {
MapTool.showError("Handshake.msg.playerAlreadyConnected");
}
});
@Nonnull
public Connection createConnection(@Nonnull String id, @Nonnull RemoteServerConfig config) {
return switch (config) {
case RemoteServerConfig.Socket(String hostName, int port) ->
new SocketConnection(id, hostName, port);
case RemoteServerConfig.WebRTC(String serverName) ->
new WebRTCConnection(
id,
serverName,
new WebRTCConnection.Listener() {
@Override
public void onLoginError() {
MapTool.showError("Handshake.msg.playerAlreadyConnected");
}
});
};
}

@Nonnull
public Server createServer(@Nullable ServerConfig config) {
if (config == null) {
return new NilServer();
Expand Down
147 changes: 68 additions & 79 deletions src/main/java/net/rptools/maptool/client/AppActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.Nonnull;
import javax.crypto.NoSuchPaddingException;
import javax.swing.*;
import javax.swing.text.BadLocationException;
Expand Down Expand Up @@ -2349,6 +2350,66 @@ protected void executeAction() {
}
};

public static void connectToServer(
@Nonnull String username, @Nonnull String password, @Nonnull RemoteServerConfig config) {
LOAD_MAP.setSeenWarning(false);

MapTool.disconnect();
MapTool.stopServer();

// Install a temporary gimped campaign until we get the one from the server
final Campaign oldCampaign = MapTool.getCampaign();
MapTool.setCampaign(new Campaign(), null);

// connecting
MapTool.getFrame().getConnectionStatusPanel().setStatus(ConnectionStatusPanel.Status.connected);

// Show the user something interesting while we're connecting. Look below for the corresponding
// hideGlassPane
StaticMessageDialog progressDialog =
new StaticMessageDialog(I18N.getText("msg.info.connecting"));
MapTool.getFrame().showFilledGlassPane(progressDialog);

boolean failed = false;
try {
MapTool.connectToRemoteServer(
config,
new LocalPlayer(username, password),
(success) -> {
EventQueue.invokeLater(
() -> {
MapTool.getFrame().hideGlassPane();
if (success) {
// Show the user something interesting until we've got the campaign
// Look in ClientMethodHandler.setCampaign() for the corresponding
// hideGlassPane
MapTool.getFrame()
.showFilledGlassPane(
new StaticMessageDialog(I18N.getText("msg.info.campaignLoading")));
}
});
});

} catch (UnknownHostException e1) {
MapTool.showError("msg.error.unknownHost", e1);
failed = true;
} catch (IOException e1) {
MapTool.showError("msg.error.failedLoadCampaign", e1);
failed = true;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e1) {
MapTool.showError("msg.error.initializeCrypto", e1);
failed = true;
}
if (failed) {
MapTool.getFrame().hideGlassPane();
try {
MapTool.startPersonalServer(oldCampaign);
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
MapTool.showError("msg.error.failedStartPersonalServer", e);
}
}
}

public static final Action CONNECT_TO_SERVER =
new ClientAction() {
{
Expand All @@ -2366,89 +2427,17 @@ protected void executeAction() {

final ConnectToServerDialog dialog = new ConnectToServerDialog();
dialog.showDialog();
if (!dialog.accepted()) {
var config = dialog.getResult();
if (config == null) {
return;
}
ConnectToServerDialogPreferences prefs = new ConnectToServerDialogPreferences();

LOAD_MAP.setSeenWarning(false);

MapTool.disconnect();
MapTool.stopServer();

// Install a temporary gimped campaign until we get the one from the
// server
final Campaign oldCampaign = MapTool.getCampaign();
MapTool.setCampaign(new Campaign(), null);
var username = prefs.getUsername();
var password =
prefs.getUsePublicKey() ? new PasswordGenerator().getPassword() : prefs.getPassword();

// connecting
MapTool.getFrame()
.getConnectionStatusPanel()
.setStatus(ConnectionStatusPanel.Status.connected);

// Show the user something interesting while we're connecting. Look below for the
// corresponding hideGlassPane
StaticMessageDialog progressDialog =
new StaticMessageDialog(I18N.getText("msg.info.connecting"));
MapTool.getFrame().showFilledGlassPane(progressDialog);

runBackground(
() -> {
boolean failed = false;
try {
ConnectToServerDialogPreferences prefs = new ConnectToServerDialogPreferences();
ServerConfig config =
new ServerConfig(
prefs.getUsername(),
"",
"",
dialog.getPort(),
prefs.getServerName(),
dialog.getServer(),
false,
dialog.getUseWebRTC());

String password =
prefs.getUsePublicKey()
? new PasswordGenerator().getPassword()
: prefs.getPassword();
MapTool.connectToRemoteServer(
config,
new LocalPlayer(prefs.getUsername(), prefs.getRole(), password),
(success) -> {
EventQueue.invokeLater(
() -> {
MapTool.getFrame().hideGlassPane();
if (success) {
// Show the user something interesting until we've got the campaign
// Look in ClientMethodHandler.setCampaign() for the corresponding
// hideGlassPane
MapTool.getFrame()
.showFilledGlassPane(
new StaticMessageDialog(
I18N.getText("msg.info.campaignLoading")));
}
});
});

} catch (UnknownHostException e1) {
MapTool.showError("msg.error.unknownHost", e1);
failed = true;
} catch (IOException e1) {
MapTool.showError("msg.error.failedLoadCampaign", e1);
failed = true;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e1) {
MapTool.showError("msg.error.initializeCrypto", e1);
failed = true;
}
if (failed) {
MapTool.getFrame().hideGlassPane();
try {
MapTool.startPersonalServer(oldCampaign);
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
MapTool.showError("msg.error.failedStartPersonalServer", e);
}
}
});
runBackground(() -> connectToServer(username, password, config));
}
};

Expand Down
Loading
Loading