diff --git a/.gitignore b/.gitignore index 305f110..1e38492 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ out/ #Other config.pref +updateCache.pref diff --git a/cmd-instructions.md b/cmd-instructions.md index 4dd0852..a59e8ce 100644 --- a/cmd-instructions.md +++ b/cmd-instructions.md @@ -54,3 +54,8 @@ There exists commands you can use, these are explained here: - Will do a Key-Search in `C:\my rpg mv game\` and shows the Key if found, if not found it will ask if you want to generate it out of encrypted images - Example 2: `java -jar "RPG Maker MV Decrypter.jar" key "C:\my rpg mv game\" false` - Same as Example 1, just don't ask if search on images, it will always do automatically +- __update__ - Updates the Program (Help: `java -jar "RPG Maker MV Decrypter.jar" update help`) + - This Script updates the Program + - Syntax: `java -jar "RPG Maker MV Decrypter.jar" update [(Optional) Sub-Command]` + - Program Update Command: `java -jar "RPG Maker MV Decrypter.jar" update` + - Open "What's new" in your Default-Browser: `java -jar "RPG Maker MV Decrypter.jar" update whatsnew` diff --git a/src/org/petschko/lib/Const.java b/src/org/petschko/lib/Const.java index 70fe4c9..7ea663e 100644 --- a/src/org/petschko/lib/Const.java +++ b/src/org/petschko/lib/Const.java @@ -13,6 +13,7 @@ public class Const { public static final String creator = "Petschko"; public static final String creatorURL = "https://petschko.org/"; + public static final String creatorDonationUrl = "https://www.paypal.me/petschko"; // System Constance's public static final String ds = System.getProperty("file.separator"); diff --git a/src/org/petschko/lib/gui/JOptionPane.java b/src/org/petschko/lib/gui/JOptionPane.java new file mode 100644 index 0000000..84256f7 --- /dev/null +++ b/src/org/petschko/lib/gui/JOptionPane.java @@ -0,0 +1,30 @@ +package org.petschko.lib.gui; + +/** + * Author: Peter Dragicevic + * Authors-Website: https://petschko.org/ + * Date: 20.02.2021 + * Time: 18:17 + *

+ * Notes: - + */ +public class JOptionPane extends javax.swing.JOptionPane { + /** + * Popups a yes/no question popup + * + * @param msg Message to display + * @param title Title of the Popup Window + * @param type Message type (Error, Warning etc) + * @param defaultYes true/false true means that "yes" is preselected + * @return JOptionPane dialog result + */ + public static int yesNoPopupQuestion(String msg, String title, int type, boolean defaultYes) { + String def; + if(defaultYes) + def = "Yes"; + else + def = "No"; + + return JOptionPane.showOptionDialog(null, msg, title, JOptionPane.YES_NO_OPTION, type, null, new String[] {"Yes", "No"}, def); + } +} diff --git a/src/org/petschko/lib/gui/notification/NotificationWindow.java b/src/org/petschko/lib/gui/notification/NotificationWindow.java index 7c243b8..af6d5c3 100644 --- a/src/org/petschko/lib/gui/notification/NotificationWindow.java +++ b/src/org/petschko/lib/gui/notification/NotificationWindow.java @@ -211,14 +211,12 @@ protected void setDefaultTitle() { */ protected int getJOptionType() { switch(this.errorLevel) { - case ERROR_LEVEL_NOTICE: - return JOptionPane.INFORMATION_MESSAGE; case ERROR_LEVEL_WARNING: return JOptionPane.WARNING_MESSAGE; case ERROR_LEVEL_ERROR: - return JOptionPane.ERROR_MESSAGE; case ERROR_LEVEL_FATAL: return JOptionPane.ERROR_MESSAGE; + case ERROR_LEVEL_NOTICE: case ERROR_LEVEL_INFO: default: return JOptionPane.INFORMATION_MESSAGE; diff --git a/src/org/petschko/lib/update/Update.java b/src/org/petschko/lib/update/Update.java new file mode 100644 index 0000000..ce91dab --- /dev/null +++ b/src/org/petschko/lib/update/Update.java @@ -0,0 +1,282 @@ +package org.petschko.lib.update; + +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Author: Peter Dragicevic [peter@petschko.org] + * Authors-Website: http://petschko.org/ + * Date: 05.10.2017 + * Time: 14:37 + * Update: - + * Version: 0.0.1 + * + * Notes: Update Class + */ +public class Update { + private UpdateCache updateCache; + private URL checkVersionUrl; + private URL whatsNewUrl = null; + private URL downloadURL = null; + private Version currentVersion; + private Version newestVersion = null; + private boolean hasNewVersion = false; + private boolean ignoreCache = false; + + /** + * Update Constructor + * + * @param checkVersionUrl - URL to get the newest Version-Number + * @param currentVersion - Current Version + * @throws IOException - IO-Exception + */ + public Update(String checkVersionUrl, String currentVersion) throws IOException { + this.updateCache = new UpdateCache(); + this.checkVersionUrl = new URL(checkVersionUrl); + this.currentVersion = new Version(currentVersion); + + this.init(); + } + + /** + * Update Constructor + * + * @param checkVersionUrl - URL to get the newest Version-Number + * @param currentVersion - Current Version + * @param cacheTime - Cache-Time in Sec + * @throws IOException - IO-Exception + */ + public Update(String checkVersionUrl, String currentVersion, long cacheTime) throws IOException { + this.updateCache = new UpdateCache(cacheTime); + this.checkVersionUrl = new URL(checkVersionUrl); + this.currentVersion = new Version(currentVersion); + + this.init(); + } + + /** + * Update Constructor + * + * @param checkVersionUrl - URL to get the newest Version-Number + * @param currentVersion - Current Version + * @param ignoreCache - Should the Cache be ignored? + * @throws IOException - IO-Exception + */ + public Update(String checkVersionUrl, String currentVersion, boolean ignoreCache) throws IOException { + this.updateCache = new UpdateCache(); + this.checkVersionUrl = new URL(checkVersionUrl); + this.currentVersion = new Version(currentVersion); + this.ignoreCache = ignoreCache; + + this.init(); + } + + /** + * Gets the Whats-New URL + * + * @return - Whats-New URL + */ + public URL getWhatsNewUrl() { + return whatsNewUrl; + } + + /** + * Initiates this instance (may loads cache) + */ + private void init() throws IOException { + if(this.ignoreCache) { + this.getUpdateInfo(); + } else { + if(this.updateCache.loadCache()) { + this.newestVersion = this.updateCache.newestVersionCache; + this.downloadURL = this.updateCache.cachedDownloadUrl; + this.whatsNewUrl = this.updateCache.cachedWhatsNewUrl; + } else { + this.getUpdateInfo(); + } + } + + this.checkVersion(); + } + + /** + * Get all information from the File for the Update process + */ + private void getUpdateInfo() throws IOException { + // Read the Update-URL + InputStream content = this.checkVersionUrl.openStream(); + + + // Convert the read Content to Strings + int c; + int currentString = 0; + StringBuilder version = new StringBuilder(); + StringBuilder downloadUrl = new StringBuilder(); + StringBuilder whatsNewUrl = new StringBuilder(); + + while(true) { + try { + c = content.read(); + + // Exit loop if file reaches end + if(c == -1) + break; + + if(c == (int) ';') + currentString++; + else { + switch(currentString) { + case 0: + version.append((char) c); + break; + case 1: + downloadUrl.append((char) c); + break; + case 2: + whatsNewUrl.append((char) c); + break; + default: + } + } + } catch(IOException e) { + e.printStackTrace(); + break; + } + } + + this.newestVersion = new Version(version.toString().trim()); + + try { + this.downloadURL = new URL(downloadUrl.toString().trim()); + this.whatsNewUrl = new URL(whatsNewUrl.toString().trim()); + } catch(MalformedURLException e) { + e.printStackTrace(); + } + + this.savesCache(); + } + + /** + * Saves new Data to the Cache + */ + private void savesCache() { + this.updateCache.newestVersionCache = this.newestVersion; + this.updateCache.cachedDownloadUrl = this.downloadURL; + this.updateCache.cachedWhatsNewUrl = this.whatsNewUrl; + + this.updateCache.saveCache(); + } + + /** + * Checks if the Version is the newest + */ + private void checkVersion() { + if(this.newestVersion == null) + return; + + if(! this.currentVersion.versionsEqual(this.newestVersion)) + this.hasNewVersion = this.currentVersion.thisIsLowerThan(this.newestVersion); + } + + /** + * Shows if the current Version is the newest + * + * @return - Is newest Version + */ + public boolean isHasNewVersion() { + return this.hasNewVersion; + } + + /** + * Get the newest Version-Number + * + * @return - Newest Version-Number or null if could not read Update-URL + */ + public String getNewestVersion() { + return newestVersion.getVersion(); + } + + /** + * Get the current Version + * + * @return - Current Version + */ + public String getCurrentVersion() { + return currentVersion.getVersion(); + } + + /** + * Starts the updater but not relaunch after update + * + * @param targetJar - Target jar which should be updated + * @param gui - Should the Updater show a GUI window + */ + public void runUpdate(String targetJar, boolean gui) throws UpdateException { + this.runUpdate(targetJar, gui, false, null); + } + + + /** + * Starts the updater + * + * @param targetJar - Target jar which should be updated + * @param gui - Should the Updater show a GUI window + * @param relaunch - Relaunch this Program after Update + * @param relaunchArgs - Args for relaunch, can be null if none + */ + public void runUpdate(String targetJar, boolean gui, boolean relaunch, @Nullable String[] relaunchArgs) throws UpdateException { + File updaterFile = new File("update.jar"); + File targetJarFile = new File(targetJar); + + if(this.newestVersion == null) + throw new UpdateException("Newest Version is not set!", this.currentVersion); + + if(this.newestVersion.versionsEqual(new Version(""))) + throw new UpdateException("Newest Version is empty...", this.currentVersion); + + if(this.newestVersion.versionsEqual(this.currentVersion)) + throw new UpdateException("This Program is already up to date!", this.currentVersion, this.newestVersion); + + if(! targetJarFile.exists() || targetJarFile.isDirectory()) + throw new UpdateException("Can not find the Target-Jar", this.currentVersion); + + if(! updaterFile.exists() || updaterFile.isDirectory()) + throw new UpdateException("Updater not found!", this.currentVersion); + + String[] run = { + "java", + "-jar", + "update.jar", + "\"" + targetJar + "\"", + "\"" + this.downloadURL.toString() + "\"", + gui ? "true" : "false", + relaunch ? "true" : "false" + }; + + // Add args + if(relaunchArgs != null) { + String[] tmp = new String[run.length + relaunchArgs.length]; + int i; + for(i = 0; i < run.length; i++) + tmp[i] = run[i]; + + int n = i; + for(; i < tmp.length; i++) + tmp[i] = relaunchArgs[i - n]; + + run = tmp; + } + + try { + Runtime.getRuntime().exec(run); + } catch (Exception e) { + throw new UpdateException(e.getMessage(), this.currentVersion, e); + } + System.exit(0); + } +} diff --git a/src/org/petschko/lib/update/UpdateCache.java b/src/org/petschko/lib/update/UpdateCache.java new file mode 100644 index 0000000..9ca97d1 --- /dev/null +++ b/src/org/petschko/lib/update/UpdateCache.java @@ -0,0 +1,149 @@ +package org.petschko.lib.update; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.Timestamp; +import java.util.Properties; + +/** + * Author: Peter Dragicevic + * Authors-Website: https://petschko.org/ + * Date: 25.02.2021 + * Time: 16:57 + * + * Notes: - + */ +class UpdateCache { + private static final String PROP_NEWEST_VERSION_CACHE = "newestVersionCache"; + private static final String PROP_CACHED_DOWNLOAD_URL = "cachedDownloadUrl"; + private static final String PROP_WHATS_NEW_URL = "cachedWhatsNewUrl"; + private static final String PROP_LAST_CHECK = "lastCheck"; + private static final String FILE_PATH = "updateCache.pref"; + + private File propertyFile = null; + private Properties properties = null; + private long currentTime; + private long checkAgainAfterSec = 86400; // Default 1 Day + private long lastCheck = 0; + Version newestVersionCache = null; + URL cachedDownloadUrl = null; + URL cachedWhatsNewUrl = null; + + /** + * UpdateCache constructor + */ + UpdateCache() { + this.setTime(); + } + + /** + * UpdateCache constructor + * + * @param checkAgainAfterSec - Checks again after secs from last check, this overwrites default value + */ + UpdateCache(long checkAgainAfterSec) { + this.setTime(); + this.checkAgainAfterSec = checkAgainAfterSec; + } + + /** + * Sets current time + */ + private void setTime() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + this.currentTime = timestamp.getTime() / 1000; + } + + /** + * Loads the cache from a File + * + * @return - true if cache was loaded successfully else false if either not all data provided or need new check + */ + boolean loadCache() { + this.propertyFile = new File(FILE_PATH); + if(! this.propertyFile.exists() || this.propertyFile.isDirectory()) { + this.propertyFile = null; + return false; + } + + this.properties = new Properties(); + Reader reader; + try { + reader = new FileReader(this.propertyFile); + this.properties.load(reader); + } catch(Exception e) { + return false; + } + + // Set the values + this.lastCheck = Long.parseLong(this.properties.getProperty(PROP_LAST_CHECK, "0")); + String cachedVersion = this.properties.getProperty(PROP_NEWEST_VERSION_CACHE, ""); + this.newestVersionCache = cachedVersion.equals("") ? null : new Version(cachedVersion); + try { + this.cachedDownloadUrl = new URL(this.properties.getProperty(PROP_CACHED_DOWNLOAD_URL, "")); + } catch(MalformedURLException e) { + this.cachedDownloadUrl = null; + } + try { + this.cachedWhatsNewUrl = new URL(this.properties.getProperty(PROP_WHATS_NEW_URL, "")); + } catch(MalformedURLException e) { + this.cachedWhatsNewUrl = null; + } + + if(this.cacheToOld()) + return false; + + return this.newestVersionCache != null && this.cachedDownloadUrl != null && this.cachedWhatsNewUrl != null; + } + + /** + * Saves the cache to a File + */ + void saveCache() { + this.lastCheck = this.currentTime; + + if(this.propertyFile == null) + this.propertyFile = new File(FILE_PATH); + + // Create missing file + if(! this.propertyFile.exists()) { + try { + new FileWriter(this.propertyFile).close(); + } catch(IOException e) { + e.printStackTrace(); + + return; + } + + if(! this.propertyFile.exists()) + return; + } + + if(this.properties == null) + this.properties = new Properties(); + + // Set the new values + this.properties.setProperty(PROP_LAST_CHECK, String.valueOf(this.lastCheck)); + this.properties.setProperty(PROP_NEWEST_VERSION_CACHE, this.newestVersionCache.getVersion()); + this.properties.setProperty(PROP_CACHED_DOWNLOAD_URL, this.cachedDownloadUrl.toString()); + this.properties.setProperty(PROP_WHATS_NEW_URL, this.cachedWhatsNewUrl.toString()); + + try { + FileWriter fileWriter = new FileWriter(FILE_PATH); + this.properties.store(fileWriter, "Update Cache File"); + } catch(IOException e) { + e.printStackTrace(); + } + } + + /** + * Shows if the cache is to old + * + * @return - Cache is to Old + */ + private boolean cacheToOld() { + return this.currentTime > this.lastCheck + this.checkAgainAfterSec; + } +} diff --git a/src/org/petschko/lib/update/UpdateException.java b/src/org/petschko/lib/update/UpdateException.java new file mode 100644 index 0000000..2d49760 --- /dev/null +++ b/src/org/petschko/lib/update/UpdateException.java @@ -0,0 +1,254 @@ +package org.petschko.lib.update; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.security.PrivilegedActionException; + +/** + * Author: Peter Dragicevic [peter@petschko.org] + * Authors-Website: https://petschko.org/ + * Date: 05.05.2019 + * Time: 17:02 + * Update: - + * Version: 0.0.1 + * + * Notes: Contains the UpdateException Class + */ +public class UpdateException extends Exception { + private Version currentVersion; + private Version newestVersion = null; + + /** + * Constructs a new exception with {@code null} as its detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param currentVersion - Current Version + */ + public UpdateException(@NotNull Version currentVersion) { + super(); + this.setCurrentVersion(currentVersion); + } + + /** + * Constructs a new exception with {@code null} as its detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param currentVersion - Current Version + * @param newestVersion - Newest Version or null for none + */ + public UpdateException(@NotNull Version currentVersion, @Nullable Version newestVersion) { + super(); + this.setCurrentVersion(currentVersion); + this.setNewestVersion(newestVersion); + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + * @param currentVersion - Current Version + */ + public UpdateException(String message, @NotNull Version currentVersion) { + super(message); + this.setCurrentVersion(currentVersion); + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + * @param currentVersion - Current Version + * @param newestVersion - Newest Version or null for none + */ + public UpdateException(String message, @NotNull Version currentVersion, @Nullable Version newestVersion) { + super(message); + this.setCurrentVersion(currentVersion); + this.setNewestVersion(newestVersion); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param currentVersion - Current Version + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public UpdateException(String message, @NotNull Version currentVersion, Throwable cause) { + super(message, cause); + this.setCurrentVersion(currentVersion); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param currentVersion - Current Version + * @param newestVersion - Newest Version or null for none + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public UpdateException(String message, @NotNull Version currentVersion, @Nullable Version newestVersion, Throwable cause) { + super(message, cause); + this.setCurrentVersion(currentVersion); + this.setNewestVersion(newestVersion); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * PrivilegedActionException}). + * + * @param currentVersion - Current Version + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public UpdateException(@NotNull Version currentVersion, Throwable cause) { + super(cause); + this.setCurrentVersion(currentVersion); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * PrivilegedActionException}). + * + * @param currentVersion - Current Version + * @param newestVersion - Newest Version or null for none + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public UpdateException(@NotNull Version currentVersion, @Nullable Version newestVersion, Throwable cause) { + super(cause); + this.setCurrentVersion(currentVersion); + this.setNewestVersion(newestVersion); + } + + /** + * Constructs a new exception with the specified detail message, + * cause, suppression enabled or disabled, and writable stack + * trace enabled or disabled. + * + * @param message the detail message. + * @param currentVersion - Current Version + * @param cause the cause. (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled + * or disabled + * @param writableStackTrace whether or not the stack trace should + * be writable + */ + protected UpdateException(String message, @NotNull Version currentVersion, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + this.setCurrentVersion(currentVersion); + } + + /** + * Constructs a new exception with the specified detail message, + * cause, suppression enabled or disabled, and writable stack + * trace enabled or disabled. + * + * @param message the detail message. + * @param currentVersion - Current Version + * @param newestVersion - Newest Version or null for none + * @param cause the cause. (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled + * or disabled + * @param writableStackTrace whether or not the stack trace should + * be writable + */ + protected UpdateException(String message, @NotNull Version currentVersion, @Nullable Version newestVersion, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + this.setCurrentVersion(currentVersion); + this.setNewestVersion(newestVersion); + } + + /** + * Get the current Version + * + * @return - Current Version + */ + public @NotNull Version getCurrentVersion() { + return currentVersion; + } + + /** + * Get the current Version as String + * + * @return - Current Version as String + */ + public String getCurrentVersionAsString() { + return currentVersion.getVersion(); + } + + /** + * Set the current Version + * + * @param currentVersion - Current Version + */ + private void setCurrentVersion(@NotNull Version currentVersion) { + this.currentVersion = currentVersion; + } + + /** + * Get the newest Version + * + * @return - Newest Version or null + */ + public @Nullable Version getNewestVersion() { + return newestVersion; + } + + /** + * Get the newest Version as String + * + * @return - Newest Version as String + */ + public String getNewestVersionAsString() { + if(this.newestVersion == null) + return ""; + + return newestVersion.getVersion(); + } + + /** + * Set the newest Version + * + * @param newestVersion - Newest Version or null + */ + private void setNewestVersion(@Nullable Version newestVersion) { + this.newestVersion = newestVersion; + } +} diff --git a/src/org/petschko/lib/update/Version.java b/src/org/petschko/lib/update/Version.java new file mode 100644 index 0000000..dd58036 --- /dev/null +++ b/src/org/petschko/lib/update/Version.java @@ -0,0 +1,92 @@ +package org.petschko.lib.update; + +import org.jetbrains.annotations.NotNull; + +/** + * Author: Peter Dragicevic [peter@petschko.org] + * Authors-Website: https://petschko.org/ + * Date: 05.05.2019 + * Time: 17:16 + * Update: - + * Version: 0.0.1 + * + * Notes: Version Class + */ +public class Version { + private String version; + + /** + * Version constructor + * + * @param version - Version + */ + public Version(@NotNull String version) { + this.version = version; + } + + /** + * Get the Version + * + * @return - Version + */ + public String getVersion() { + return version; + } + + /** + * Compares 2 Versions + * + * @param version - Version to compare + * @return - Versions are equal + */ + public boolean versionsEqual(Version version) { + return this.version.equals(version.getVersion()); + } + + /** + * Checks if this Version is lower than the other Version + * + * @param version - Version to compare + * @return - This Version is lower than the other + */ + public boolean thisIsLowerThan(Version version) { + String[] thisVersion = this.version.split("\\."); + String[] otherVersion = version.version.split("\\."); + + // Ensure same length arrays + if(thisVersion.length > otherVersion.length) { + String[] tmp = new String[thisVersion.length]; + + for(int i = 0; i < tmp.length; i++) { + if(i < otherVersion.length) + tmp[i] = otherVersion[i]; + else + tmp[i] = "0"; + } + + otherVersion = tmp; + } else if(otherVersion.length > thisVersion.length) { + String[] tmp = new String[otherVersion.length]; + + for(int i = 0; i < tmp.length; i++) { + if(i < thisVersion.length) + tmp[i] = thisVersion[i]; + else + tmp[i] = "0"; + } + + thisVersion = tmp; + } + + // Compare Versions + for(int n = 0; n < thisVersion.length; n++) { + int thisNumber = Integer.parseInt(thisVersion[n]); + int otherNumber = Integer.parseInt(otherVersion[n]); + + if(thisNumber < otherNumber) + return true; + } + + return false; + } +} diff --git a/src/org/petschko/rpgmakermv/decrypt/App.java b/src/org/petschko/rpgmakermv/decrypt/App.java index b027839..be02b4a 100644 --- a/src/org/petschko/rpgmakermv/decrypt/App.java +++ b/src/org/petschko/rpgmakermv/decrypt/App.java @@ -1,6 +1,5 @@ package org.petschko.rpgmakermv.decrypt; -import org.petschko.lib.Const; import org.petschko.lib.gui.notification.ErrorWindow; /** diff --git a/src/org/petschko/rpgmakermv/decrypt/CMD.java b/src/org/petschko/rpgmakermv/decrypt/CMD.java index e7b7813..86ea2f8 100644 --- a/src/org/petschko/rpgmakermv/decrypt/CMD.java +++ b/src/org/petschko/rpgmakermv/decrypt/CMD.java @@ -16,6 +16,7 @@ class CMD { static final int STATUS_WARNING = 1; static final int STATUS_ERROR = -1; static final String HELP_INDENT = " "; + static final String LINE_CMD = "------------------------------------------------------------------------------"; private static final String CMD_HELP = "help"; private static final String CMD_HELP_2 = "-help"; private static final String CMD_HELP_3 = "--help"; @@ -30,6 +31,7 @@ class CMD { private static final String CMD_GET_KEY_3 = "getkey"; private static final String CMD_GET_KEY_4 = "detectkey"; private static final String CMD_GET_KEY_5 = "keydetect"; + private static final String UPDATE = "update"; private final String[] args; @@ -47,9 +49,11 @@ class CMD { */ void runCMD() { // Show Welcome-Message - System.out.println("------------------------------------------------------------------------------"); + System.out.println(LINE_CMD); System.out.println(Config.programName + " - " + Config.version + " by " + Const.creator + " | Command-Line Version"); - System.out.println("------------------------------------------------------------------------------"); + System.out.println(LINE_CMD); + + CMD_Update.checkForUpdates(); sanitizeArgs(); processArgs(); @@ -66,7 +70,8 @@ private void sanitizeArgs() { args[0] = args[0].replaceAll("/", ""); if(args.length >= 2) { - if(isHelpCmd(args[1].toLowerCase().trim())) + // Lowercase everything for help & update + if(isHelpCmd(args[0].toLowerCase().trim()) || isHelpCmd(args[1].toLowerCase().trim()) || args[0].toLowerCase().equals(UPDATE)) args[1] = args[1].toLowerCase().trim(); } } @@ -108,6 +113,9 @@ private void processArgs() { case CMD_GET_KEY_5: cmdHandler = new CMD_DetectKey(); break; + case UPDATE: + cmdHandler = new CMD_Update(); + break; default: boolean invalidCommand = false; if(! isHelpCmd(args[0])) diff --git a/src/org/petschko/rpgmakermv/decrypt/CMD_Help.java b/src/org/petschko/rpgmakermv/decrypt/CMD_Help.java index 5c28cac..989f23d 100644 --- a/src/org/petschko/rpgmakermv/decrypt/CMD_Help.java +++ b/src/org/petschko/rpgmakermv/decrypt/CMD_Help.java @@ -38,6 +38,7 @@ public void printHelp() { //App.showMessage(CMD.HELP_INDENT + " restoreproject - Restores a RPG-MV/MZ Project (Makes it editable again)"); App.showMessage(CMD.HELP_INDENT + " key - Detects the Key and Displays it"); //App.showMessage(CMD.HELP_INDENT + " open - Opens an encrypted Image"); + App.showMessage(CMD.HELP_INDENT + " update - Updates this Program"); App.showMessage(""); App.showMessage(CMD.HELP_INDENT + "Display detailed help for each command:"); App.showMessage(CMD.HELP_INDENT + " java -jar \"RPG Maker MV Decrypter.jar\" [command] help"); diff --git a/src/org/petschko/rpgmakermv/decrypt/CMD_Open.java b/src/org/petschko/rpgmakermv/decrypt/CMD_Open.java index 9560d13..456e884 100644 --- a/src/org/petschko/rpgmakermv/decrypt/CMD_Open.java +++ b/src/org/petschko/rpgmakermv/decrypt/CMD_Open.java @@ -2,7 +2,6 @@ import java.awt.Desktop; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/org/petschko/rpgmakermv/decrypt/CMD_Update.java b/src/org/petschko/rpgmakermv/decrypt/CMD_Update.java new file mode 100644 index 0000000..f670ec4 --- /dev/null +++ b/src/org/petschko/rpgmakermv/decrypt/CMD_Update.java @@ -0,0 +1,158 @@ +package org.petschko.rpgmakermv.decrypt; + +import org.petschko.lib.update.Update; +import org.petschko.lib.update.UpdateException; + +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Author: Peter Dragicevic + * Authors-Website: https://petschko.org/ + * Date: 22.02.2021 + * Time: 22:38 + * + * Notes: - + */ +public class CMD_Update implements CMD_Command { + private static final String SUB_CMD_WHATS_NEW = "whatsnew"; + + private Update update = null; + + /** + * Runs the Command + * + * @param args - Command-Line commands + */ + @Override + public void run(String[] args) { + this.update = checkForUpdates(false, true); + + if(this.update != null) { + if(args.length >= 2) { + String subCmd = args[1]; + + // Handle sub CMDs + if(subCmd.equals(SUB_CMD_WHATS_NEW)) { + this.showWhatsNew(); + } else { + App.showMessage("Sub-Command \"" + subCmd + "\" doesnt exists! See help", CMD.STATUS_WARNING); + App.showMessage(""); + this.printHelp(); + CMD.exitCMD(CMD.STATUS_WARNING); + } + return; + } + + this.runUpdate(); + } + } + + /** + * Runs the Update + */ + private void runUpdate() { + if(! this.update.isHasNewVersion()) { + System.out.println("You are already using the newest Version!"); + System.out.println(CMD.LINE_CMD); + return; + } + + App.showMessage("Starting update..."); + try { + update.runUpdate(Config.jarFileUpdate, false); + } catch(UpdateException e) { + App.showMessage("Update Failed... Cause: " + e.getMessage()); + } + } + + /** + * Opens the Link in whats new + */ + private void showWhatsNew() { + if(! this.update.isHasNewVersion()) { + System.out.println("You are already using the newest Version!"); + System.out.println(CMD.LINE_CMD); + } else if(Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + + if(desktop.isSupported(Desktop.Action.BROWSE)) { + try { + URI uri = new URI(this.update.getWhatsNewUrl().toString()); + desktop.browse(uri); + } catch(IOException | URISyntaxException e) { + App.showMessage("Can't open \"What's new...\"", CMD.STATUS_ERROR); + CMD.exitCMD(CMD.STATUS_ERROR); + return; + } + } + } else { + App.showMessage("Can't open \"What's new...\"...", CMD.STATUS_ERROR); + App.showMessage("This operation isnt supported by your OS!", CMD.STATUS_ERROR); + CMD.exitCMD(CMD.STATUS_ERROR); + return; + } + + CMD.exitCMD(CMD.STATUS_OK); + } + + /** + * Prints help for the command + */ + @Override + public void printHelp() { + App.showMessage("Usage: java -jar \"RPG Maker MV Decrypter.jar\" update [(optional) Sub Command]"); + App.showMessage(""); + App.showMessage(CMD.HELP_INDENT + "Sub-Commands:"); + App.showMessage(CMD.HELP_INDENT + " " + SUB_CMD_WHATS_NEW + " - Opens \"Whats new\" in your Browser"); + App.showMessage(""); + App.showMessage(CMD.HELP_INDENT + "Updates the Program:"); + App.showMessage(CMD.HELP_INDENT + " java -jar \"RPG Maker MV Decrypter.jar\" update"); + App.showMessage(""); + App.showMessage(CMD.HELP_INDENT + "Show whats new in your Browser:"); + App.showMessage(CMD.HELP_INDENT + " java -jar \"RPG Maker MV Decrypter.jar\" update " + SUB_CMD_WHATS_NEW); + App.showMessage(""); + } + + /** + * Check if there is an update and displays it + */ + static void checkForUpdates() { + checkForUpdates(true, false); + } + + /** + * Check if there is an update and may displays it + * + * @param output - Shows console output + * @param ignoreUpdateCache - Ignored the Update-Cache + * @return - Update Object + */ + private static Update checkForUpdates(boolean output, boolean ignoreUpdateCache) { + Update update = null; + + try { + if(ignoreUpdateCache) + update = new Update(Config.updateUrl, Config.versionNumber, true); + else + update = new Update(Config.updateUrl, Config.versionNumber, Config.updateCheckEverySecs); + } catch(IOException e) { + System.out.println("Update: Can't check for Updates..."); + System.out.println(CMD.LINE_CMD); + } + + if(update != null) { + if(update.isHasNewVersion() && output) { + System.out.println("Update: There is a new Version available! New Version: " + update.getNewestVersion()); + System.out.println(); + System.out.println("For update run: java -jar \"RPG Maker MV Decrypter.jar\" update"); + System.out.println("To see whats new (Opens Browser): java -jar \"RPG Maker MV Decrypter.jar\" update "+ SUB_CMD_WHATS_NEW); + System.out.println(CMD.LINE_CMD); + } + } + + return update; + } +} diff --git a/src/org/petschko/rpgmakermv/decrypt/Config.java b/src/org/petschko/rpgmakermv/decrypt/Config.java index 840b962..7c21810 100644 --- a/src/org/petschko/rpgmakermv/decrypt/Config.java +++ b/src/org/petschko/rpgmakermv/decrypt/Config.java @@ -12,18 +12,23 @@ */ class Config { // Program Info - static final String versionNumber = "0.2.0"; + static final String versionNumber = "0.3.0"; static final String version = "v" + versionNumber + " Alpha"; static final String programName = "RPG-Maker MV/MZ Decrypter"; static final String projectPageURL = "https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter"; static final String projectBugReportURL = "https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter/issues"; static final String projectLicenceURL = "https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter/blob/master/LICENCE"; static final String authorImage = "/org/petschko/icons/petschko_icon.png"; + static final String updateUrl = "https://raw.githubusercontent.com/Petschko/Java-RPG-Maker-MV-Decrypter/master/version.txt"; // File-Path-Settings static final String defaultOutputDir = "output"; static final String preferencesFile = "config.pref"; + // Misc Settings + static final long updateCheckEverySecs = 172800; + static final String jarFileUpdate = "RPG Maker MV Decrypter.jar"; + /** * Constructor */ diff --git a/src/org/petschko/rpgmakermv/decrypt/Decrypter.java b/src/org/petschko/rpgmakermv/decrypt/Decrypter.java index 605490b..3905b0d 100644 --- a/src/org/petschko/rpgmakermv/decrypt/Decrypter.java +++ b/src/org/petschko/rpgmakermv/decrypt/Decrypter.java @@ -104,6 +104,11 @@ private byte[] getRpgHeaderBytes() { return rpgHeaderBytes; } + /** + * Sets RPG-Header Bytes + * + * @param rpgHeaderBytes - RPG-Header Bytes + */ private void setRpgHeaderBytes(byte[] rpgHeaderBytes) { this.rpgHeaderBytes = rpgHeaderBytes; } @@ -354,9 +359,8 @@ boolean checkFakeHeader(byte[] content) { * @param keyName - Key-Name of the Decryption-Key * @throws JSONException - Key not Found Exception * @throws NullPointerException - System-File is null - * @throws FileSystemException - Can't load File */ - void detectEncryptionKeyFromJson(File file, String keyName) throws JSONException, NullPointerException, FileSystemException { + void detectEncryptionKeyFromJson(File file, String keyName) throws JSONException, NullPointerException { try { if(! file.load()) throw new FileSystemException(file.getFilePath(), "", "Can't load File-Content..."); diff --git a/src/org/petschko/rpgmakermv/decrypt/GUI.java b/src/org/petschko/rpgmakermv/decrypt/GUI.java index 5fb77b5..34b4511 100644 --- a/src/org/petschko/rpgmakermv/decrypt/GUI.java +++ b/src/org/petschko/rpgmakermv/decrypt/GUI.java @@ -22,7 +22,6 @@ import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.nio.file.FileSystemException; import java.util.ArrayList; /** @@ -64,7 +63,28 @@ class GUI { // Assign Listener this.assignMainMenuListener(); this.setNewOutputDir(App.outputDir); - // todo implement + + // Add Update-Check + if(Functions.strToBool(App.preferences.getConfig(Preferences.autoCheckForUpdates, "true"))) + new GUI_Update(this, true); + } + + /** + * Returns the Main-Window + * + * @return - Main-Window + */ + JFrame getMainWindow() { + return mainWindow; + } + + /** + * Returns the Main-Menu + * + * @return - Main-Menu + */ + GUI_Menu getMainMenu() { + return mainMenu; } /** @@ -108,6 +128,10 @@ private void createMainMenu() { this.mainMenu.overwriteExistingFiles.setState(true); } else this.mainMenu.overwriteExistingFiles.setEnabled(false); + + if(Functions.strToBool(App.preferences.getConfig(Preferences.autoCheckForUpdates, "true"))) + this.mainMenu.checkForUpdates.setState(true); + this.mainMenu.enableOnRPGProject(false); } @@ -193,9 +217,13 @@ private void assignMainMenuListener() { e -> this.mainMenu.overwriteExistingFiles.setEnabled(! this.mainMenu.overwriteExistingFiles.isEnabled()) ); this.mainMenu.overwriteExistingFiles.addActionListener(GUI_ActionListener.switchSetting(Preferences.overwriteFiles)); + this.mainMenu.checkForUpdates.addActionListener(GUI_ActionListener.switchSetting(Preferences.autoCheckForUpdates)); // -- Decrypt // -- Tools // -- Info + this.mainMenu.updateProgram.addActionListener( + e -> new GUI_Update(this) + ); this.mainMenu.reportABug.addActionListener(GUI_ActionListener.openWebsite(Config.projectBugReportURL)); this.mainMenu.about.addActionListener( e -> this.guiAbout.showWindow() @@ -281,11 +309,9 @@ private class GUI_Decryption extends SwingWorker implements ActionLi * Note: this method is executed in a background thread. * * @return the computed result - * - * @throws Exception if unable to compute a result */ @Override - protected Void doInBackground() throws Exception { + protected Void doInBackground() { // Clear Output-Dir if checked if(Functions.strToBool(App.preferences.getConfig(Preferences.clearOutputDirBeforeDecrypt, "true"))) { this.progressMonitor.setNote("Clearing Output-Directory..."); @@ -322,21 +348,6 @@ protected Void doInBackground() throws Exception { this.progressMonitor.setNote("Try to detect Encryption-Key..."); try { decrypter.detectEncryptionKeyFromJson(rpgProject.getSystem(), rpgProject.getEncryptionKeyName()); - } catch(FileSystemException fileSysEx) { - // Can't load File - fileSysEx.printStackTrace(); - ErrorWindow errorWindow = new ErrorWindow( - "Can't load/read Decryption-Key-File..." + Const.newLine + - "File: " + fileSysEx.getFile() + Const.newLine + - "See Console for more Details...", - ErrorWindow.ERROR_LEVEL_WARNING, - false - ); - - errorWindow.show(mainWindow); - - this.cancel(true); - return null; } catch(NullPointerException decryNullEx) { // File-Null-Pointer ErrorWindow errorWindow = new ErrorWindow( @@ -433,7 +444,7 @@ protected void done() { */ @Override public void actionPerformed(ActionEvent e) { - this.progressMonitor = new ProgressMonitor(mainWindow, "Decrypting...", "Preparing...", 0, this.files.size()); + this.progressMonitor = new ProgressMonitor(mainWindow, this.restoreImages ? "Restoring..." : "Decrypting...", "Preparing...", 0, this.files.size()); this.progressMonitor.setProgress(0); this.execute(); @@ -464,11 +475,9 @@ private class GUI_DirectoryClearing extends SwingWorker implements A * Note: this method is executed in a background thread. * * @return the computed result - * - * @throws Exception if unable to compute a result */ @Override - protected Void doInBackground() throws Exception { + protected Void doInBackground() { if(File.clearDirectory(this.directoryPath)) { InfoWindow infoWindow = new InfoWindow("Output-Directory cleared!"); infoWindow.show(mainWindow); @@ -561,11 +570,9 @@ private class GUI_OpenRPGDir extends SwingWorker { * Note: this method is executed in a background thread. * * @return the computed result - * - * @throws Exception if unable to compute a result */ @Override - protected Void doInBackground() throws Exception { + protected Void doInBackground() { try { rpgProject = new RPGProject( File.ensureDSonEndOfPath(this.directoryPath), diff --git a/src/org/petschko/rpgmakermv/decrypt/GUI_About.java b/src/org/petschko/rpgmakermv/decrypt/GUI_About.java index 05d0849..7c2e923 100644 --- a/src/org/petschko/rpgmakermv/decrypt/GUI_About.java +++ b/src/org/petschko/rpgmakermv/decrypt/GUI_About.java @@ -85,6 +85,8 @@ protected void constructAbout() { JLabel programmedBy = new JLabel(Const.creator + " (Programmer) - "); JLabelExtra programmedByURL = new JLabelExtra("Website"); programmedByURL.setURL(Const.creatorURL, true); + JLabelExtra programmedByDonate = new JLabelExtra("Donate"); + programmedByDonate.setURL(Const.creatorDonationUrl, true); // Set Layouts borderFrame.setLayout(new BorderLayout()); @@ -114,6 +116,8 @@ protected void constructAbout() { creditLine.add(creditHeading); creatorLine.add(programmedBy); creatorLine.add(programmedByURL); + creatorLine.add(new JLabel(" | ")); + creatorLine.add(programmedByDonate); descriptionContainer.add(versionLine); descriptionContainer.add(Box.createRigidArea(new Dimension(0, lineSpace))); diff --git a/src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java b/src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java index b4390e3..43b699d 100644 --- a/src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java +++ b/src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java @@ -35,6 +35,7 @@ class GUI_Menu extends JMenuBar { JCheckBoxMenuItem loadInvalidRPGDirs; JCheckBoxMenuItem clearOutputDir; JCheckBoxMenuItem overwriteExistingFiles; + JCheckBoxMenuItem checkForUpdates; // Decrypt-Menu-Sub JMenuItem selectedFiles; @@ -93,6 +94,7 @@ private void constructOptionsMenu() { this.loadInvalidRPGDirs = new JCheckBoxMenuItem("Load invalid RPG-MV-Dirs anyway"); this.clearOutputDir = new JCheckBoxMenuItem("Clear output Dir before Decrypt"); this.overwriteExistingFiles = new JCheckBoxMenuItem("Overwrite existing Files"); + this.checkForUpdates = new JCheckBoxMenuItem("Auto check for Updates"); } /** @@ -151,6 +153,8 @@ private void addAllMenus() { this.options.addSeparator(); this.options.add(this.clearOutputDir); this.options.add(this.overwriteExistingFiles); + this.options.addSeparator(); + this.options.add(this.checkForUpdates); this.add(this.decrypt); this.decrypt.add(this.selectedFiles); @@ -198,6 +202,6 @@ private void disableUnimplemented() { this.changeDecrypterSignature.setEnabled(false); this.restoreProject.setEnabled(false); this.help.setEnabled(false); - this.updateProgram.setEnabled(false); + //this.updateProgram.setEnabled(false); } } diff --git a/src/org/petschko/rpgmakermv/decrypt/GUI_Update.java b/src/org/petschko/rpgmakermv/decrypt/GUI_Update.java new file mode 100644 index 0000000..e63f249 --- /dev/null +++ b/src/org/petschko/rpgmakermv/decrypt/GUI_Update.java @@ -0,0 +1,150 @@ +package org.petschko.rpgmakermv.decrypt; + +import org.petschko.lib.Const; +import org.petschko.lib.gui.JOptionPane; +import org.petschko.lib.gui.notification.ErrorWindow; +import org.petschko.lib.gui.notification.InfoWindow; +import org.petschko.lib.update.Update; +import org.petschko.lib.update.UpdateException; + +import java.awt.*; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Author: Peter Dragicevic + * Authors-Website: https://petschko.org/ + * Date: 20.02.2021 + * Time: 17:29 + * + * Notes: - + */ + +class GUI_Update { + private GUI gui; + private Update update = null; + private String[] options; + private boolean autoOptionExists = false; + private boolean ranAutomatically = false; + + /** + * GUI_Update constructor + * + * @param gui - Main GUI-Object + */ + GUI_Update(GUI gui) { + this.gui = gui; + this.options = new String[] {"Update", "Show whats new", "Cancel"}; + + this.init(); + } + + /** + * GUI_Update constructor + * + * @param gui - Main GUI-Object + * @param auto - This ran automatically + */ + GUI_Update(GUI gui, boolean auto) { + this.gui = gui; + this.options = new String[] {"Update", "Show whats new", "Disable update check", "Cancel"}; + this.autoOptionExists = true; + this.ranAutomatically = auto; + + this.init(); + } + + /** + * Inits the Object + */ + private void init() { + try { + if(this.ranAutomatically) + update = new Update(Config.updateUrl, Config.versionNumber, Config.updateCheckEverySecs); + else + update = new Update(Config.updateUrl, Config.versionNumber, true); + } catch (IOException e) { + if(! this.ranAutomatically) { + ErrorWindow ew = new ErrorWindow("Can't check for Updates...", ErrorWindow.ERROR_LEVEL_WARNING, false); + ew.show(this.gui.getMainWindow()); + } + } + + this.checkIfUpdate(); + } + + /** + * Checks if an update exists + */ + private void checkIfUpdate() { + if(update != null) { + if(update.isHasNewVersion()) { + // Ask the user what to do + int response = JOptionPane.showOptionDialog( + this.gui.getMainWindow(), + "Update found!" + Const.newLine + + "Your Version: " + Config.versionNumber + Const.newLine + + "New Version: " + update.getNewestVersion() + Const.newLine + Const.newLine + + "What do you want to do?", + "Update found", + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + this.options, + this.options[0] + ); + + if(response == 0) + this.runUpdate(); + else if(response == 1) + this.showWhatsNew(); + else if(this.autoOptionExists && response == 2) { + App.preferences.switchBoolConfig(Preferences.autoCheckForUpdates); + gui.getMainMenu().checkForUpdates.setState(false); + } + } else if(! this.ranAutomatically) { + InfoWindow infoWindow = new InfoWindow("You're using the newest Version!", "No update found"); + infoWindow.show(this.gui.getMainWindow()); + } + } + } + + /** + * Runs the update + */ + private void runUpdate() { + try { + update.runUpdate(Config.jarFileUpdate, true, true, null); + } catch(UpdateException e) { + ErrorWindow errorWindow = new ErrorWindow("Update Failed!", ErrorWindow.ERROR_LEVEL_ERROR, false, e); + errorWindow.show(this.gui.getMainWindow()); + + e.printStackTrace(); + } + } + + /** + * Brings the user to the whats new url + */ + private void showWhatsNew() { + if(Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + + if(desktop.isSupported(Desktop.Action.BROWSE)) { + try { + URI uri = new URI(update.getWhatsNewUrl().toString()); + desktop.browse(uri); + } catch(IOException | URISyntaxException e) { + ErrorWindow errorWindow = new ErrorWindow("Can't open \"What's new...\"", ErrorWindow.ERROR_LEVEL_ERROR, false, e); + errorWindow.show(this.gui.getMainWindow()); + + e.printStackTrace(); + } + } + } else { + ErrorWindow errorWindow = new ErrorWindow("Can't open \"What's new...\"..." + Const.newLine + "This operation isnt supported by your OS!", ErrorWindow.ERROR_LEVEL_ERROR, false); + errorWindow.show(this.gui.getMainWindow()); + } + } +} diff --git a/src/org/petschko/rpgmakermv/decrypt/Preferences.java b/src/org/petschko/rpgmakermv/decrypt/Preferences.java index 102cdc6..e7844a8 100644 --- a/src/org/petschko/rpgmakermv/decrypt/Preferences.java +++ b/src/org/petschko/rpgmakermv/decrypt/Preferences.java @@ -27,7 +27,7 @@ class Preferences extends UserPref { static final String decrypterRemain = "decrypterRemain"; static final String decrypterSignature = "decrypterSignature"; static final String decrypterHeaderLen = "decrypterHeaderLen"; - + static final String autoCheckForUpdates = "autoCheckForUpdates"; /** * UserPrefs Constructor @@ -58,6 +58,7 @@ public boolean loadDefaults() { p.setProperty(Preferences.decrypterRemain, Decrypter.defaultRemain); p.setProperty(Preferences.decrypterSignature, Decrypter.defaultSignature); p.setProperty(Preferences.decrypterHeaderLen, Integer.toString(Decrypter.defaultHeaderLen)); + p.setProperty(Preferences.autoCheckForUpdates, "true"); this.setProperties(p); diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..743bd29 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.2.0;https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter/releases/download/v.0.2.0-alpha/RPG_Maker_MV_Decrypter_0.2.0.jar;https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter/releases/tag/v.0.2.0-alpha