From 6d77e0cff48e544e28db5502ad91886a62312849 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Sun, 27 Oct 2024 23:49:14 +0800 Subject: [PATCH 1/8] check snapshot update by timestamp --- .../src/main/java/forge/util/BuildInfo.java | 28 +++++++++++++++++++ .../src/main/java/forge/control/FControl.java | 11 ++++++-- .../main/java/forge/view/FTitleBarBase.java | 1 + .../main/java/forge/download/AutoUpdater.java | 12 ++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/forge-core/src/main/java/forge/util/BuildInfo.java b/forge-core/src/main/java/forge/util/BuildInfo.java index 5393a62cdd9..c3195392ad2 100644 --- a/forge-core/src/main/java/forge/util/BuildInfo.java +++ b/forge-core/src/main/java/forge/util/BuildInfo.java @@ -20,10 +20,17 @@ package forge.util; import org.apache.commons.lang3.StringUtils; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; + /** * Provides access to information about the current version and build ID. */ public class BuildInfo { + private static Date timestamp = null; // disable instantiation private BuildInfo() { } @@ -46,6 +53,27 @@ public class BuildInfo { StringUtils.containsIgnoreCase(forgeVersion, "snapshot"); } + public static Date getTimestamp() { + if (timestamp != null) + return timestamp; + try { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String b = Files.readString( + Paths.get(BuildInfo.class.getClassLoader().getResource("build.txt").toURI()), + Charset.defaultCharset()); + timestamp = simpleDateFormat.parse(b); + } catch (Exception ignored) {} + return timestamp; + } + + public static boolean verifyTimestamp(Date updateTimestamp) { + if (updateTimestamp == null) + return false; + if (getTimestamp() == null) + return false; + System.err.println("Update Timestamp: " + updateTimestamp + "\nBuild Timestamp: " + getTimestamp()); + return updateTimestamp.after(getTimestamp()); + } public static String getUserAgent() { return "Forge/" + getVersionString(); } diff --git a/forge-gui-desktop/src/main/java/forge/control/FControl.java b/forge-gui-desktop/src/main/java/forge/control/FControl.java index fbd7d496816..09d10d0fafe 100644 --- a/forge-gui-desktop/src/main/java/forge/control/FControl.java +++ b/forge-gui-desktop/src/main/java/forge/control/FControl.java @@ -27,7 +27,9 @@ import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.net.URL; +import java.text.SimpleDateFormat; import java.util.Collections; +import java.util.Date; import java.util.List; import javax.swing.ImageIcon; @@ -88,7 +90,8 @@ public enum FControl implements KeyEventDispatcher { private CloseAction closeAction; private final List currentMatches = Lists.newArrayList(); private String snapsVersion = "", currentVersion = ""; - private boolean isSnapshot; + private Date snapsTimestamp = null; + private boolean isSnapshot, hasSnapsUpdate; private Localizer localizer; public enum CloseAction { @@ -229,6 +232,10 @@ public enum FControl implements KeyEventDispatcher { if (isSnapshot && prefs.getPrefBoolean(FPref.CHECK_SNAPSHOT_AT_STARTUP)) { URL url = new URL("https://downloads.cardforge.org/dailysnapshots/version.txt"); snapsVersion = FileUtil.readFileToString(url); + url = new URL("https://downloads.cardforge.org/dailysnapshots/build.txt"); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + snapsTimestamp = simpleDateFormat.parse(FileUtil.readFileToString(url)); + hasSnapsUpdate = BuildInfo.verifyTimestamp(snapsTimestamp); } } catch (Exception ignored) {} @@ -288,7 +295,7 @@ public enum FControl implements KeyEventDispatcher { return isSnapshot; } public String getSnapshotNotification() { - if (!isSnapshot || snapsVersion.isEmpty() || currentVersion.equalsIgnoreCase(snapsVersion)) + if (!isSnapshot || !hasSnapsUpdate || snapsVersion.isEmpty() || currentVersion.equalsIgnoreCase(snapsVersion)) return ""; return getLocalizer().getMessage("lblNewSnapshotVersion", snapsVersion); } diff --git a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java index efae38f2f95..6208b78b830 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java +++ b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java @@ -455,6 +455,7 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { } private void updateVisibility() { setVisible(!isVisible()); + setEnabled(isVisible()); } } } diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index 008e8563166..ad09343f5bd 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -9,6 +9,8 @@ import java.net.Socket; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -147,6 +149,16 @@ public class AutoUpdater { return false; } // If version doesn't match, it's assummably newer. + if (buildVersion.contains("SNAPSHOT")) { + try { + URL url = new URL("https://downloads.cardforge.org/dailysnapshots/build.txt"); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date snapsTimestamp = simpleDateFormat.parse(FileUtil.readFileToString(url)); + return snapsTimestamp.after(BuildInfo.getTimestamp()); + } catch (Exception ignored) { + return false; + } + } return true; } From 420f6964ff6823d54b5d913d5e1c65dc43980f83 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 10:51:17 +0800 Subject: [PATCH 2/8] update desktop timestamp check --- .../src/main/java/forge/util/BuildInfo.java | 44 +++++++++++++------ .../src/main/java/forge/control/FControl.java | 2 +- .../main/java/forge/view/FTitleBarBase.java | 14 +++--- .../main/java/forge/download/AutoUpdater.java | 26 ++++++----- 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/forge-core/src/main/java/forge/util/BuildInfo.java b/forge-core/src/main/java/forge/util/BuildInfo.java index c3195392ad2..b20327ab343 100644 --- a/forge-core/src/main/java/forge/util/BuildInfo.java +++ b/forge-core/src/main/java/forge/util/BuildInfo.java @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program 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. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -20,9 +20,10 @@ package forge.util; import org.apache.commons.lang3.StringUtils; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.Date; @@ -31,15 +32,17 @@ import java.util.Date; */ public class BuildInfo { private static Date timestamp = null; + // disable instantiation - private BuildInfo() { } + private BuildInfo() { + } /** * Get the current version of Forge. - * + * * @return a String representing the version specifier, or "GIT" if unknown. */ - public static final String getVersionString() { + public static String getVersionString() { String version = BuildInfo.class.getPackage().getImplementationVersion(); if (StringUtils.isEmpty(version)) { return "GIT"; @@ -58,11 +61,12 @@ public class BuildInfo { return timestamp; try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String b = Files.readString( - Paths.get(BuildInfo.class.getClassLoader().getResource("build.txt").toURI()), - Charset.defaultCharset()); - timestamp = simpleDateFormat.parse(b); - } catch (Exception ignored) {} + InputStream inputStream = BuildInfo.class.getResourceAsStream("/build.txt"); + String data = readFromInputStream(inputStream); + timestamp = simpleDateFormat.parse(data); + } catch (Exception e) { + e.printStackTrace(); + } return timestamp; } @@ -71,10 +75,22 @@ public class BuildInfo { return false; if (getTimestamp() == null) return false; - System.err.println("Update Timestamp: " + updateTimestamp + "\nBuild Timestamp: " + getTimestamp()); + //System.err.println("Update Timestamp: " + updateTimestamp + "\nBuild Timestamp: " + getTimestamp()); return updateTimestamp.after(getTimestamp()); } + public static String getUserAgent() { return "Forge/" + getVersionString(); } + + private static String readFromInputStream(InputStream inputStream) throws IOException { + StringBuilder resultStringBuilder = new StringBuilder(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = br.readLine()) != null) { + resultStringBuilder.append(line).append("\n"); + } + } + return resultStringBuilder.toString(); + } } diff --git a/forge-gui-desktop/src/main/java/forge/control/FControl.java b/forge-gui-desktop/src/main/java/forge/control/FControl.java index 09d10d0fafe..e8fd72ebd80 100644 --- a/forge-gui-desktop/src/main/java/forge/control/FControl.java +++ b/forge-gui-desktop/src/main/java/forge/control/FControl.java @@ -295,7 +295,7 @@ public enum FControl implements KeyEventDispatcher { return isSnapshot; } public String getSnapshotNotification() { - if (!isSnapshot || !hasSnapsUpdate || snapsVersion.isEmpty() || currentVersion.equalsIgnoreCase(snapsVersion)) + if (!isSnapshot || !hasSnapsUpdate || snapsVersion.isEmpty()) return ""; return getLocalizer().getMessage("lblNewSnapshotVersion", snapsVersion); } diff --git a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java index 6208b78b830..26a786c8dff 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java +++ b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java @@ -433,16 +433,21 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { setPreferredSize(new Dimension(160, 25)); updateVisibility(); } + @Override protected void onClick() { - try { - new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, null, null))); - } catch (Exception e) { - e.printStackTrace(); + if (!displayText.isEmpty()) { + try { + new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, null, null))); + } catch (Exception e) { + e.printStackTrace(); + } } } @Override public void paintComponent(Graphics g) { + if (displayText.isEmpty()) + return; g.translate(-((int)((System.currentTimeMillis() / MARQUEE_SPEED_DIV) % ((getWidth() + wMod) * 2)) - (getWidth() + wMod)), 0); super.paintComponent(g); int thickness = 2; @@ -455,7 +460,6 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { } private void updateVisibility() { setVisible(!isVisible()); - setEnabled(isVisible()); } } } diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index ad09343f5bd..8741178162e 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -31,6 +31,7 @@ import forge.model.FModel; import forge.util.BuildInfo; import forge.util.FileUtil; import forge.util.Localizer; +import forge.util.TextUtil; import forge.util.WaitCallback; public class AutoUpdater { @@ -48,6 +49,8 @@ public class AutoUpdater { private String versionUrlString; private String packageUrl; private String packagePath; + private String buildDate = ""; + private String snapsBuildDate = ""; public AutoUpdater(boolean loading) { // What do I need? Preferences? Splashscreen? UI? Skins? @@ -135,7 +138,14 @@ public class AutoUpdater { private boolean compareBuildWithLatestChannelVersion() { try { retrieveVersion(); - + if (buildVersion.contains("SNAPSHOT")) { + URL url = new URL("https://downloads.cardforge.org/dailysnapshots/build.txt"); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date snapsTimestamp = simpleDateFormat.parse(FileUtil.readFileToString(url)); + snapsBuildDate = snapsTimestamp.toString(); + buildDate = BuildInfo.getTimestamp().toString(); + return BuildInfo.verifyTimestamp(snapsTimestamp); + } if (StringUtils.isEmpty(version) ) { return false; } @@ -149,16 +159,6 @@ public class AutoUpdater { return false; } // If version doesn't match, it's assummably newer. - if (buildVersion.contains("SNAPSHOT")) { - try { - URL url = new URL("https://downloads.cardforge.org/dailysnapshots/build.txt"); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date snapsTimestamp = simpleDateFormat.parse(FileUtil.readFileToString(url)); - return snapsTimestamp.after(BuildInfo.getTimestamp()); - } catch (Exception ignored) { - return false; - } - } return true; } @@ -196,7 +196,9 @@ public class AutoUpdater { return downloadFromBrowser(); } String log = cf.get(); - String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", version, buildVersion) + log; + String v = snapsBuildDate.isEmpty() ? version : version + TextUtil.enclosedParen(snapsBuildDate); + String b = buildDate.isEmpty() ? buildVersion : buildVersion + TextUtil.enclosedParen(buildDate); + String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", v, b) + log; final List options = ImmutableList.of(localizer.getMessage("lblUpdateNow"), localizer.getMessage("lblUpdateLater")); if (SOptionPane.showOptionDialog(message, localizer.getMessage("lblNewVersionAvailable"), null, options, 0) == 0) { return downloadFromForge(); From e97b77cc8fb91afc366aad7997ab89f514331004 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 11:49:08 +0800 Subject: [PATCH 3/8] missing return --- forge-gui-mobile/src/forge/assets/AssetsDownloader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java index ff736e80d99..550a9e30407 100644 --- a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java +++ b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java @@ -130,8 +130,10 @@ public class AssetsDownloader { } } } else { - if (!GuiBase.isAndroid()) + if (!GuiBase.isAndroid()) { run(runnable); + return; + } } } catch (Exception e) { e.printStackTrace(); From b807c604e3bedbde99db40a69c7c09152a87beda Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 12:07:22 +0800 Subject: [PATCH 4/8] update mobile timestamp check --- .../src/forge/assets/AssetsDownloader.java | 75 ++++++++----------- .../main/java/forge/download/AutoUpdater.java | 2 +- 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java index 550a9e30407..dfff00dc127 100644 --- a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java +++ b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java @@ -3,14 +3,12 @@ package forge.assets; import java.io.IOException; import java.net.URL; import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; import java.util.List; -import java.util.TimeZone; import com.badlogic.gdx.files.FileHandle; import forge.gui.GuiBase; -import forge.util.TextUtil; +import forge.util.BuildInfo; import org.apache.commons.lang3.StringUtils; import com.badlogic.gdx.Gdx; @@ -30,7 +28,6 @@ public class AssetsDownloader { private final static ImmutableList downloadIgnoreExit = ImmutableList.of("Download", "Ignore", "Exit"); private final static ImmutableList downloadExit = ImmutableList.of("Download", "Exit"); - //if not sharing desktop assets, check whether assets are up to date public static void checkForUpdates(boolean exited, Runnable runnable) { if (exited) return; @@ -52,7 +49,11 @@ public class AssetsDownloader { final String versionText = isSnapshots ? snapsURL + "version.txt" : releaseURL + "version.txt"; FileHandle assetsDir = Gdx.files.absolute(ForgeConstants.ASSETS_DIR); FileHandle resDir = Gdx.files.absolute(ForgeConstants.RES_DIR); + FileHandle buildTxtFileHandle = Gdx.files.classpath("build.txt"); + final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + boolean verifyUpdatable = false; boolean mandatory = false; + Date snapsTimestamp = null, buildTimeStamp; String message; boolean connectedToInternet = Forge.getDeviceAdapter().isConnectedToInternet(); @@ -74,31 +75,30 @@ public class AssetsDownloader { String snapsBZ2URL = "https://downloads.cardforge.org/dailysnapshots/"; installerURL = isSnapshots ? snapsBZ2URL : releaseBZ2URL; } - //TODO build version - /*String buildver = ""; - SimpleDateFormat DateFor = TextUtil.getSimpleDate(); - Calendar calendar = Calendar.getInstance(); - Date buildDateOriginal = null; - try { - FileHandle build = Gdx.files.classpath("build.txt"); - if (build.exists()) { - SimpleDateFormat original = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - original.setTimeZone(TimeZone.getTimeZone("UTC")); - Date buildDate = original.parse(build.readString()); - buildDateOriginal = original.parse(build.readString()); - calendar.setTime(buildDate); - DateFor.setTimeZone(TimeZone.getDefault()); - buildver = "\nForge Build: " + DateFor.format(calendar.getTime()); + String snapsBuildDate = "", buildDate = ""; + if (isSnapshots) { + URL url = new URL(snapsURL + "build.txt"); + snapsTimestamp = format.parse(FileUtil.readFileToString(url)); + snapsBuildDate = snapsTimestamp.toString(); + if (!GuiBase.isAndroid()) { + buildDate = BuildInfo.getTimestamp().toString(); + verifyUpdatable = BuildInfo.verifyTimestamp(snapsTimestamp); + } else { + if (buildTxtFileHandle.exists()) { + buildTimeStamp = format.parse(buildTxtFileHandle.readString()); + buildDate = buildTimeStamp.toString(); + verifyUpdatable = snapsTimestamp.after(buildTimeStamp); + } } - } catch (Exception e) { - e.printStackTrace(); - }*/ + } else { + verifyUpdatable = !StringUtils.isEmpty(version) && !versionString.equals(version); + } - if (!StringUtils.isEmpty(version) && !versionString.equals(version)) { + if (verifyUpdatable) { Forge.getSplashScreen().prepareForDialogs(); - message = "A new version of Forge is available (" + version + ").\n" + - "You are currently on an older version (" + versionString + ").\n\n" + + message = "A new version of Forge is available." + version + "\n" + snapsBuildDate + "\n" + + "You are currently on an older version." + versionString + "\n" + buildDate + "\n" + "Would you like to update to the new version now?"; if (!Forge.getDeviceAdapter().isConnectedToWifi()) { message += " If so, you may want to connect to wifi first. The download is around " + (GuiBase.isAndroid() ? apkSize : packageSize) + "."; @@ -183,30 +183,21 @@ public class AssetsDownloader { return; //if version matches what had been previously saved and FSkin isn't requesting assets download, no need to download assets } - FileHandle f = Gdx.files.classpath("build.txt"); - FileHandle t = resDir.child("build.txt"); - if (f.exists() && t.exists()) { - String buildString = f.readString(); - String target = t.readString(); + FileHandle resBuildDate = resDir.child("build.txt"); + if (buildTxtFileHandle.exists() && resBuildDate.exists()) { + String buildString = buildTxtFileHandle.readString(); + String target = resBuildDate.readString(); try { - Date buildDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(buildString); - Date targetDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(target); + Date buildDate = format.parse(buildString); + Date targetDate = format.parse(target); // if res folder has same build date then continue loading assets if (buildDate.equals(targetDate) && versionString.equals(FileUtil.readFileToString(versionFile.file()))) { run(runnable); return; } mandatory = true; - //format to local date - SimpleDateFormat original = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - original.setTimeZone(TimeZone.getTimeZone("UTC")); - targetDate = original.parse(target); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(targetDate); - SimpleDateFormat simpleDate = TextUtil.getSimpleDate(); - simpleDate.setTimeZone(TimeZone.getDefault()); - build += "Installed resources date: " + simpleDate.format(calendar.getTime()) + "\n\n"; - log = Forge.getDeviceAdapter().getLatestChanges(GITHUB_COMMITS_URL_ATOM, null, null); + build += "Installed resources date: " + target + "\n\n"; + log = Forge.getDeviceAdapter().getLatestChanges(GITHUB_COMMITS_URL_ATOM, buildDate, snapsTimestamp); } catch (Exception e) { e.printStackTrace(); } diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index 8741178162e..66f59a4fed8 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -155,7 +155,7 @@ public class AutoUpdater { } } catch (Exception e) { - e.printStackTrace(); + SOptionPane.showOptionDialog(e.getMessage(), localizer.getMessage("lblError"), null, ImmutableList.of("Ok")); return false; } // If version doesn't match, it's assummably newer. From 20db37477fa55fdc6ac85e1831f9d77236f1a32e Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 12:12:17 +0800 Subject: [PATCH 5/8] missing space --- forge-gui-mobile/src/forge/assets/AssetsDownloader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java index dfff00dc127..89e8ede4f13 100644 --- a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java +++ b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java @@ -97,8 +97,8 @@ public class AssetsDownloader { if (verifyUpdatable) { Forge.getSplashScreen().prepareForDialogs(); - message = "A new version of Forge is available." + version + "\n" + snapsBuildDate + "\n" + - "You are currently on an older version." + versionString + "\n" + buildDate + "\n" + + message = "A new version of Forge is available. " + version + "\n" + snapsBuildDate + "\n" + + "You are currently on an older version. " + versionString + "\n" + buildDate + "\n" + "Would you like to update to the new version now?"; if (!Forge.getDeviceAdapter().isConnectedToWifi()) { message += " If so, you may want to connect to wifi first. The download is around " + (GuiBase.isAndroid() ? apkSize : packageSize) + "."; From 0bac8ea04d0ebb11ff4a1fd89a46cad27a12c93c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 12:19:50 +0800 Subject: [PATCH 6/8] format message --- forge-gui-mobile/src/forge/assets/AssetsDownloader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java index 89e8ede4f13..6bed654c79c 100644 --- a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java +++ b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java @@ -97,8 +97,8 @@ public class AssetsDownloader { if (verifyUpdatable) { Forge.getSplashScreen().prepareForDialogs(); - message = "A new version of Forge is available. " + version + "\n" + snapsBuildDate + "\n" + - "You are currently on an older version. " + versionString + "\n" + buildDate + "\n" + + message = "A new version of Forge is available. - v." + version + "\n" + snapsBuildDate + "\n" + + "You are currently on an older version. - v." + versionString + "\n" + buildDate + "\n" + "Would you like to update to the new version now?"; if (!Forge.getDeviceAdapter().isConnectedToWifi()) { message += " If so, you may want to connect to wifi first. The download is around " + (GuiBase.isAndroid() ? apkSize : packageSize) + "."; @@ -196,7 +196,7 @@ public class AssetsDownloader { return; } mandatory = true; - build += "Installed resources date: " + target + "\n\n"; + build += "\nInstalled resources date:\n" + target + "\n"; log = Forge.getDeviceAdapter().getLatestChanges(GITHUB_COMMITS_URL_ATOM, buildDate, snapsTimestamp); } catch (Exception e) { e.printStackTrace(); From 750d41a2d38d7f2bdd28e0b7bfb87e5177b5ee0a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 12:34:48 +0800 Subject: [PATCH 7/8] filter commit messages --- .../src/main/java/forge/control/FControl.java | 123 +++++++++++------- .../home/settings/CSubmenuDownloaders.java | 3 +- .../main/java/forge/view/FTitleBarBase.java | 2 +- .../main/java/forge/download/AutoUpdater.java | 3 +- 4 files changed, 81 insertions(+), 50 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/control/FControl.java b/forge-gui-desktop/src/main/java/forge/control/FControl.java index e8fd72ebd80..d0aea495254 100644 --- a/forge-gui-desktop/src/main/java/forge/control/FControl.java +++ b/forge-gui-desktop/src/main/java/forge/control/FControl.java @@ -90,7 +90,7 @@ public enum FControl implements KeyEventDispatcher { private CloseAction closeAction; private final List currentMatches = Lists.newArrayList(); private String snapsVersion = "", currentVersion = ""; - private Date snapsTimestamp = null; + private Date snapsTimestamp = null, buildTimeStamp = null; private boolean isSnapshot, hasSnapsUpdate; private Localizer localizer; @@ -142,31 +142,33 @@ public enum FControl implements KeyEventDispatcher { @Override public void windowClosing(final WindowEvent e) { switch (closeAction) { - case NONE: //prompt user for close action if not previously specified - final List options = ImmutableList.of(getLocalizer().getMessage("lblCloseScreen"), getLocalizer().getMessage("lblExitForge"), getLocalizer().getMessage("lblCancel")); - final int reply = FOptionPane.showOptionDialog( - getLocalizer().getMessage("txCloseAction1") + "\n\n" + getLocalizer().getMessage("txCloseAction2"), - getLocalizer().getMessage("titCloseAction"), - FOptionPane.INFORMATION_ICON, - options, - 2); - switch (reply) { - case 0: //Close Screen - setCloseAction(CloseAction.CLOSE_SCREEN); - windowClosing(e); //call again to apply chosen close action - return; - case 1: //Exit Forge - setCloseAction(CloseAction.EXIT_FORGE); - windowClosing(e); //call again to apply chosen close action - return; - } - break; - case CLOSE_SCREEN: - Singletons.getView().getNavigationBar().closeSelectedTab(); - break; - case EXIT_FORGE: - if (exitForge()) { return; } - break; + case NONE: //prompt user for close action if not previously specified + final List options = ImmutableList.of(getLocalizer().getMessage("lblCloseScreen"), getLocalizer().getMessage("lblExitForge"), getLocalizer().getMessage("lblCancel")); + final int reply = FOptionPane.showOptionDialog( + getLocalizer().getMessage("txCloseAction1") + "\n\n" + getLocalizer().getMessage("txCloseAction2"), + getLocalizer().getMessage("titCloseAction"), + FOptionPane.INFORMATION_ICON, + options, + 2); + switch (reply) { + case 0: //Close Screen + setCloseAction(CloseAction.CLOSE_SCREEN); + windowClosing(e); //call again to apply chosen close action + return; + case 1: //Exit Forge + setCloseAction(CloseAction.EXIT_FORGE); + windowClosing(e); //call again to apply chosen close action + return; + } + break; + case CLOSE_SCREEN: + Singletons.getView().getNavigationBar().closeSelectedTab(); + break; + case EXIT_FORGE: + if (exitForge()) { + return; + } + break; } //prevent closing Forge if we reached this point Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); @@ -174,12 +176,22 @@ public enum FControl implements KeyEventDispatcher { }); } + public Date getBuildTimeStamp() { + return buildTimeStamp; + } + + public Date getSnapsTimestamp() { + return snapsTimestamp; + } + public CloseAction getCloseAction() { return closeAction; } public void setCloseAction(final CloseAction closeAction0) { - if (closeAction == closeAction0) { return; } + if (closeAction == closeAction0) { + return; + } closeAction = closeAction0; Singletons.getView().getNavigationBar().updateBtnCloseTooltip(); @@ -190,7 +202,7 @@ public enum FControl implements KeyEventDispatcher { public boolean canExitForge(final boolean forRestart) { final String action = (forRestart ? getLocalizer().getMessage("lblRestart") : getLocalizer().getMessage("lblExit")); - String userPrompt =(forRestart ? getLocalizer().getMessage("lblAreYouSureYouWishRestartForge") : getLocalizer().getMessage("lblAreYouSureYouWishExitForge")); + String userPrompt = (forRestart ? getLocalizer().getMessage("lblAreYouSureYouWishRestartForge") : getLocalizer().getMessage("lblAreYouSureYouWishExitForge")); final boolean hasCurrentMatches = hasCurrentMatches(); if (hasCurrentMatches) { userPrompt = getLocalizer().getMessage("lblOneOrMoreGamesActive") + ". " + userPrompt; @@ -222,7 +234,9 @@ public enum FControl implements KeyEventDispatcher { return true; } - /** After view and model have been initialized, control can start.*/ + /** + * After view and model have been initialized, control can start. + */ public void initialize() { final ForgePreferences prefs = FModel.getPreferences(); currentVersion = BuildInfo.getVersionString(); @@ -235,10 +249,12 @@ public enum FControl implements KeyEventDispatcher { url = new URL("https://downloads.cardforge.org/dailysnapshots/build.txt"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); snapsTimestamp = simpleDateFormat.parse(FileUtil.readFileToString(url)); + buildTimeStamp = BuildInfo.getTimestamp(); hasSnapsUpdate = BuildInfo.verifyTimestamp(snapsTimestamp); } - } catch (Exception ignored) {} + } catch (Exception ignored) { + } // Preloads skin components (using progress bar). FSkin.loadFull(true); @@ -258,15 +274,16 @@ public enum FControl implements KeyEventDispatcher { if (data.exists()) { try { FModel.getQuest().load(QuestDataIO.loadData(data)); - } catch(IOException ex) { + } catch (IOException ex) { ex.printStackTrace(); System.err.printf("Error loading quest data (%s).. skipping for now..%n", questname); } } // format release notes upon loading try { - TextUtil.getFormattedChangelog(new File(FileUtil.pathCombine(System.getProperty("user.dir"), ForgeConstants.CHANGES_FILE_NO_RELEASE)),""); - } catch (Exception e){} + TextUtil.getFormattedChangelog(new File(FileUtil.pathCombine(System.getProperty("user.dir"), ForgeConstants.CHANGES_FILE_NO_RELEASE)), ""); + } catch (Exception e) { + } // Handles resizing in null layouts of layers in JLayeredPane as well as saving window layout final FFrame window = Singletons.getView().getFrame(); window.addComponentListener(new ComponentAdapter() { @@ -291,9 +308,11 @@ public enum FControl implements KeyEventDispatcher { FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(getLocalizer().getMessage("lblOpeningMainWindow")); SwingUtilities.invokeLater(() -> Singletons.getView().initialize()); } + public boolean isSnapshot() { return isSnapshot; } + public String getSnapshotNotification() { if (!isSnapshot || !hasSnapsUpdate || snapsVersion.isEmpty()) return ""; @@ -322,6 +341,7 @@ public enum FControl implements KeyEventDispatcher { public boolean setCurrentScreen(final FScreen screen) { return setCurrentScreen(screen, false); } + public boolean setCurrentScreen(final FScreen screen, final boolean previousScreenClosed) { //TODO: Uncomment the line below if this function stops being used to refresh //the current screen in some places (such as Continue and Restart in the match screen) @@ -370,11 +390,11 @@ public enum FControl implements KeyEventDispatcher { FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkinProp.BG_NIGHT), true); } } else { - FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage((Image)null); + FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage((Image) null); } //SOverlayUtils.showTargetingOverlay(); } else { - FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage((Image)null); + FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage((Image) null); } Singletons.getView().getNavigationBar().updateSelectedTab(); @@ -386,12 +406,16 @@ public enum FControl implements KeyEventDispatcher { } public boolean ensureScreenActive(final FScreen screen) { - if (currentScreen == screen) { return true; } + if (currentScreen == screen) { + return true; + } return setCurrentScreen(screen); } - /** Remove all children from a specified layer. */ + /** + * Remove all children from a specified layer. + */ private void clearChildren(final int layer0) { final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument().getComponentsInLayer(layer0); @@ -400,16 +424,24 @@ public enum FControl implements KeyEventDispatcher { } } - /** Sizes children of JLayeredPane to fully fit their layers. */ + /** + * Sizes children of JLayeredPane to fully fit their layers. + */ private void sizeChildren() { Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER); - if (children.length != 0) { children[0].setSize(display.getSize()); } + if (children.length != 0) { + children[0].setSize(display.getSize()); + } children = display.getComponentsInLayer(FView.TARGETING_LAYER); - if (children.length != 0) { children[0].setSize(display.getSize()); } + if (children.length != 0) { + children[0].setSize(display.getSize()); + } children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER); - if (children.length != 0) { children[0].setSize(display.getSize()); } + if (children.length != 0) { + children[0].setSize(display.getSize()); + } } public Dimension getDisplaySize() { @@ -428,18 +460,15 @@ public enum FControl implements KeyEventDispatcher { forgeMenu.show(true); return true; } - } - else if (e.getID() == KeyEvent.KEY_PRESSED && e.getModifiersEx() == InputEvent.ALT_DOWN_MASK) { + } else if (e.getID() == KeyEvent.KEY_PRESSED && e.getModifiersEx() == InputEvent.ALT_DOWN_MASK) { altKeyLastDown = true; } - } - else { + } else { altKeyLastDown = false; if (e.getID() == KeyEvent.KEY_PRESSED) { //give Forge menu the chance to handle the key event return forgeMenu.handleKeyEvent(e); - } - else if (e.getID() == KeyEvent.KEY_RELEASED) { + } else if (e.getID() == KeyEvent.KEY_RELEASED) { if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { forgeMenu.show(); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java index cff8d450da9..62edd9c1b0f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java @@ -2,6 +2,7 @@ package forge.screens.home.settings; import javax.swing.SwingUtilities; +import forge.control.FControl; import forge.download.AutoUpdater; import forge.download.GuiDownloader; import forge.gui.ImportDialog; @@ -32,7 +33,7 @@ public enum CSubmenuDownloaders implements ICDoc { SINGLETON_INSTANCE; private final UiCommand cmdLicensing = VSubmenuDownloaders.SINGLETON_INSTANCE::showLicensing; - private final UiCommand cmdCheckForUpdates = () -> new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, null, null))); + private final UiCommand cmdCheckForUpdates = () -> new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, FControl.instance.getBuildTimeStamp(), FControl.instance.getSnapsTimestamp()))); private final UiCommand cmdPicDownload = () -> new GuiDownloader(new GuiDownloadPicturesLQ()).show(); private final UiCommand cmdPicDownloadHQ = () -> new GuiDownloader(new GuiDownloadPicturesHQ()).show(); diff --git a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java index 26a786c8dff..60ed4bc7c47 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java +++ b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java @@ -438,7 +438,7 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { protected void onClick() { if (!displayText.isEmpty()) { try { - new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, null, null))); + new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(GITHUB_COMMITS_URL_ATOM, FControl.instance.getBuildTimeStamp(), FControl.instance.getSnapsTimestamp()))); } catch (Exception e) { e.printStackTrace(); } diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index 66f59a4fed8..7067d3d55e9 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -198,7 +198,8 @@ public class AutoUpdater { String log = cf.get(); String v = snapsBuildDate.isEmpty() ? version : version + TextUtil.enclosedParen(snapsBuildDate); String b = buildDate.isEmpty() ? buildVersion : buildVersion + TextUtil.enclosedParen(buildDate); - String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", v, b) + log; + String info = snapsBuildDate.isEmpty() ? "" : log; + String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", v, b) + info; final List options = ImmutableList.of(localizer.getMessage("lblUpdateNow"), localizer.getMessage("lblUpdateLater")); if (SOptionPane.showOptionDialog(message, localizer.getMessage("lblNewVersionAvailable"), null, options, 0) == 0) { return downloadFromForge(); From 0b5c3c54bdedec5267c38cee2c13848226669248 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 28 Oct 2024 12:38:06 +0800 Subject: [PATCH 8/8] don't process logs if snapsBuildDate is empty --- forge-gui/src/main/java/forge/download/AutoUpdater.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index 7067d3d55e9..a37443bd436 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -195,11 +195,10 @@ public class AutoUpdater { // splashScreen.prepareForDialogs(); return downloadFromBrowser(); } - String log = cf.get(); + String logs = snapsBuildDate.isEmpty() ? "" : cf.get(); String v = snapsBuildDate.isEmpty() ? version : version + TextUtil.enclosedParen(snapsBuildDate); String b = buildDate.isEmpty() ? buildVersion : buildVersion + TextUtil.enclosedParen(buildDate); - String info = snapsBuildDate.isEmpty() ? "" : log; - String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", v, b) + info; + String message = localizer.getMessage("lblNewVersionForgeAvailableUpdateConfirm", v, b) + logs; final List options = ImmutableList.of(localizer.getMessage("lblUpdateNow"), localizer.getMessage("lblUpdateLater")); if (SOptionPane.showOptionDialog(message, localizer.getMessage("lblNewVersionAvailable"), null, options, 0) == 0) { return downloadFromForge();