diff --git a/clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java index 32ad0b8c7b..a7a42cd72a 100644 --- a/clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java @@ -105,7 +105,7 @@ public void onClose(int code, String reason, boolean remote) { @Override public void onError(Exception ex) { lastError = "WebSocket error: " + ex.toString() + "\n"; - log.error("S " + lastError); + log.error("S " + lastError, ex); // onClose will be called after this method } }; @@ -147,7 +147,7 @@ public void onDataChannelOpened(WebRTCConnection connection) { try { fireClientConnect(connection); } catch (Exception e) { - log.error(e); + log.error("Unexpected error while handling new data channel", e); } } diff --git a/src/main/java/net/rptools/maptool/client/MapTool.java b/src/main/java/net/rptools/maptool/client/MapTool.java index 68e3cd98f3..de37477fde 100644 --- a/src/main/java/net/rptools/maptool/client/MapTool.java +++ b/src/main/java/net/rptools/maptool/client/MapTool.java @@ -182,7 +182,7 @@ public class MapTool { try { var connections = DirectConnection.create("local"); var playerDB = new PersonalServerPlayerDatabase(new LocalPlayer()); - var campaign = CampaignFactory.createBasicCampaign(); + var campaign = CampaignFactory.createEmptyCampaign(); var policy = new ServerPolicy(); server = new MapToolServer("", new Campaign(campaign), null, false, policy, playerDB); diff --git a/src/main/java/net/rptools/maptool/client/swing/ResourceLoader.java b/src/main/java/net/rptools/maptool/client/swing/ResourceLoader.java deleted file mode 100644 index 33f9590afa..0000000000 --- a/src/main/java/net/rptools/maptool/client/swing/ResourceLoader.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.swing; - -import java.awt.Rectangle; -import java.util.StringTokenizer; - -// This should really be in rplib -public class ResourceLoader { - - /** - * Rectangles are in the form x, y, width, height - * - * @throws IllegalArgumentException if rectString can't be parsed - * @param rectString string describing the rectangle - * @return a {@link Rectangle} for x, y, width, height - */ - public static Rectangle loadRectangle(String rectString) { - - StringTokenizer strtok = new StringTokenizer(rectString, ","); - if (strtok.countTokens() != 4) { - throw new IllegalArgumentException( - "Could not load rectangle: '" + rectString + "', must be in the form x, y, w, h"); - } - - int x = Integer.parseInt(strtok.nextToken().trim()); - int y = Integer.parseInt(strtok.nextToken().trim()); - int w = Integer.parseInt(strtok.nextToken().trim()); - int h = Integer.parseInt(strtok.nextToken().trim()); - - return new Rectangle(x, y, w, h); - } -} diff --git a/src/main/java/net/rptools/maptool/client/ui/SysInfoDialog.java b/src/main/java/net/rptools/maptool/client/ui/SysInfoDialog.java index 235ffd18d4..ea98fc0d90 100644 --- a/src/main/java/net/rptools/maptool/client/ui/SysInfoDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/SysInfoDialog.java @@ -47,7 +47,7 @@ private Container createContentPane() { infoTextArea.setWrapStyleWord(true); infoTextArea.setFont(new Font("Monospaced", Font.PLAIN, 13)); infoTextArea.setText(I18N.getText("action.gatherDebugInfoWait")); - EventQueue.invokeLater(new InfoTextSwingWorker()); + new InfoTextSwingWorker().execute(); JScrollPane scrollPane = new JScrollPane(infoTextArea); scrollPane.setHorizontalScrollBarPolicy(31); diff --git a/src/main/java/net/rptools/maptool/model/CampaignFactory.java b/src/main/java/net/rptools/maptool/model/CampaignFactory.java index 59decf9156..ef5523806c 100644 --- a/src/main/java/net/rptools/maptool/model/CampaignFactory.java +++ b/src/main/java/net/rptools/maptool/model/CampaignFactory.java @@ -15,6 +15,13 @@ package net.rptools.maptool.model; public class CampaignFactory { + /** + * @return A new campaign with no zones or properties. + */ + public static Campaign createEmptyCampaign() { + return new Campaign(); + } + public static Campaign createBasicCampaign() { Campaign campaign = new Campaign(); campaign.initDefault(); diff --git a/src/main/java/net/rptools/maptool/model/ZoneFactory.java b/src/main/java/net/rptools/maptool/model/ZoneFactory.java index 7a18412c0f..04e4e913e0 100644 --- a/src/main/java/net/rptools/maptool/model/ZoneFactory.java +++ b/src/main/java/net/rptools/maptool/model/ZoneFactory.java @@ -17,44 +17,67 @@ import java.awt.Color; import java.io.File; import java.io.IOException; +import javax.annotation.Nullable; import net.rptools.lib.MD5Key; import net.rptools.maptool.client.AppPreferences; import net.rptools.maptool.client.AppUtil; import net.rptools.maptool.model.drawing.DrawableColorPaint; +import net.rptools.maptool.model.drawing.DrawablePaint; import net.rptools.maptool.model.drawing.DrawableTexturePaint; import net.rptools.maptool.util.ImageManager; import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ZoneFactory { + private static final Logger log = LogManager.getLogger(ZoneFactory.class); public static final String DEFAULT_MAP_NAME = "Grasslands"; - public static MD5Key defaultImageId; + private static final DrawableColorPaint fallbackBackgroundPaint = + new DrawableColorPaint(Color.LIGHT_GRAY); + private static @Nullable MD5Key defaultImageId; + + private static DrawablePaint getDefaultBackgroundPaint() { + if (defaultImageId != null) { + return new DrawableTexturePaint(defaultImageId); + } - static { // TODO: I really don't like this being hard wired this way, need to make it a preference or - // something + // something File grassImage = new File(AppUtil.getAppHome("resource/Default/Textures").getAbsolutePath() + "/Grass.png"); - if (grassImage.exists()) { - try { - Asset asset = - Asset.createImageAsset(DEFAULT_MAP_NAME, FileUtils.readFileToByteArray(grassImage)); - defaultImageId = asset.getMD5Key(); + if (!grassImage.exists()) { + log.warn( + "Unable to load the default background texture: file {} does not exist", + grassImage.getPath()); + return fallbackBackgroundPaint; + } + + MD5Key imageId; + try { + Asset asset = + Asset.createImageAsset(DEFAULT_MAP_NAME, FileUtils.readFileToByteArray(grassImage)); + imageId = asset.getMD5Key(); - // Make sure the image is loaded to avoid a flash screen when it becomes visible - ImageManager.getImageAndWait(asset.getMD5Key()); - } catch (IOException ioe) { - ioe.printStackTrace(); - } + // Make sure the image is loaded to avoid a flash screen when it becomes visible + ImageManager.getImageAndWait(asset.getMD5Key()); + } catch (IOException ioe) { + log.error("Error reading default background image", ioe); + return fallbackBackgroundPaint; } + + defaultImageId = imageId; + return new DrawableTexturePaint(defaultImageId); } public static Zone createZone() { - Zone zone = new Zone(); zone.setName(DEFAULT_MAP_NAME); - zone.setBackgroundPaint(new DrawableTexturePaint(defaultImageId)); + + var backgroundPaint = getDefaultBackgroundPaint(); + zone.setBackgroundPaint(backgroundPaint); + zone.setFogPaint(new DrawableColorPaint(Color.black)); zone.setVisible(AppPreferences.newMapsVisible.get()); diff --git a/src/main/java/net/rptools/maptool/server/ServerHandshake.java b/src/main/java/net/rptools/maptool/server/ServerHandshake.java index 919339615a..eed28a7c44 100644 --- a/src/main/java/net/rptools/maptool/server/ServerHandshake.java +++ b/src/main/java/net/rptools/maptool/server/ServerHandshake.java @@ -523,18 +523,19 @@ private void sendAsymmetricKeyAuthType() } else { sendErrorResponseAndNotify(HandshakeResponseCodeMsg.INVALID_PUBLIC_KEY); } + } else { + CipherUtil.Key publicKey = playerDatabase.getPublicKey(player, playerPublicKeyMD5).get(); + String password = new PasswordGenerator().getPassword(); + handshakeChallenges[0] = + HandshakeChallenge.createAsymmetricChallenge(player.getName(), password, publicKey); + + var authTypeMsg = + UseAuthTypeMsg.newBuilder() + .setAuthType(AuthTypeEnum.ASYMMETRIC_KEY) + .addChallenge(ByteString.copyFrom(handshakeChallenges[0].getChallenge())); + var handshakeMsg = HandshakeMsg.newBuilder().setUseAuthTypeMsg(authTypeMsg).build(); + sendMessage(State.AwaitingClientPublicKeyAuth, handshakeMsg); } - CipherUtil.Key publicKey = playerDatabase.getPublicKey(player, playerPublicKeyMD5).get(); - String password = new PasswordGenerator().getPassword(); - handshakeChallenges[0] = - HandshakeChallenge.createAsymmetricChallenge(player.getName(), password, publicKey); - - var authTypeMsg = - UseAuthTypeMsg.newBuilder() - .setAuthType(AuthTypeEnum.ASYMMETRIC_KEY) - .addChallenge(ByteString.copyFrom(handshakeChallenges[0].getChallenge())); - var handshakeMsg = HandshakeMsg.newBuilder().setUseAuthTypeMsg(authTypeMsg).build(); - sendMessage(State.AwaitingClientPublicKeyAuth, handshakeMsg); } @Override