├── .gitignore
├── LICENCE
├── README.md
├── cmd-instructions.md
├── deployment
├── start.bat
├── start.sh
└── update.jar
├── pom.xml
├── src
└── main
│ ├── java
│ └── org
│ │ └── petschko
│ │ ├── lib
│ │ ├── CellRenderer.java
│ │ ├── Const.java
│ │ ├── File.java
│ │ ├── Functions.java
│ │ ├── Image.java
│ │ ├── UserPref.java
│ │ ├── exceptions
│ │ │ └── PathException.java
│ │ ├── gui
│ │ │ ├── GUI_About.java
│ │ │ ├── JDirectoryChooser.java
│ │ │ ├── JImageLabel.java
│ │ │ ├── JLabelExtra.java
│ │ │ ├── JLabelWrap.java
│ │ │ ├── JOptionPane.java
│ │ │ ├── JPanelLine.java
│ │ │ └── notification
│ │ │ │ ├── ErrorWindow.java
│ │ │ │ ├── InfoWindow.java
│ │ │ │ └── NotificationWindow.java
│ │ └── update
│ │ │ ├── Update.java
│ │ │ ├── UpdateCache.java
│ │ │ ├── UpdateException.java
│ │ │ └── Version.java
│ │ └── rpgmakermv
│ │ └── decrypt
│ │ ├── App.java
│ │ ├── Config.java
│ │ ├── Decrypter.java
│ │ ├── Finder.java
│ │ ├── Preferences.java
│ │ ├── RPG_Project.java
│ │ ├── cmd
│ │ ├── CMD.java
│ │ ├── Decrypt.java
│ │ ├── DetectKey.java
│ │ ├── Encrypt.java
│ │ ├── Help.java
│ │ ├── I_CMD.java
│ │ ├── Open.java
│ │ ├── Restore.java
│ │ ├── RestoreProject.java
│ │ └── Update.java
│ │ └── gui
│ │ ├── About.java
│ │ ├── ActionListener.java
│ │ ├── FileInfo.java
│ │ ├── GUI.java
│ │ ├── Menu.java
│ │ ├── ProjectInfo.java
│ │ ├── Update.java
│ │ ├── WorkerDecryption.java
│ │ ├── WorkerDirectoryClearing.java
│ │ ├── WorkerEncryption.java
│ │ └── WorkerOpenRPGDir.java
│ └── resources
│ └── icons
│ └── petschko_icon.png
└── version.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | # Class Files
2 | *.class
3 |
4 | # Mobile Tools for Java (J2ME)
5 | .mtj.tmp/
6 |
7 | # Package Files #
8 | *.jar
9 | *.war
10 | *.ear
11 |
12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
13 | hs_err_pid*
14 |
15 | # IDE-Directories
16 | .idea/
17 |
18 | #Output
19 | target/
20 | output/
21 | out/
22 |
23 | #Other
24 | src/main/java/META-INF/MANIFEST.MF
25 | config.pref
26 | updateCache.pref
27 | RPG Maker MV Decrypter.iml
28 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Peter Dragicevic
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IMPORTANT: Project MOVED to [Gitlab.com](https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter)
2 |
3 | Please look there for updates/Bug-Reports - This Github Repo will be Read-Only by now
4 |
5 | https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter
6 |
7 | ----
8 |
9 | # Petschko's RPG-Maker-MV/MZ File-Decrypter (Java-Version)
10 |
11 | ## What's that?
12 | This Project is used to decrypt RPG-Maker-MV/MZ-Resource-Files that are encrypted with the Build-In-Encryption of the RPG-Maker.
13 |
14 | This Project is also able to decrypt whole RPG-Directories. It's similar to [my previous Project](https://gitlab.com/Petschko/RPG-Maker-MV-Decrypter) but more comfortable.
15 |
16 | ### Which Files can be decrypted with this Program?
17 | You can decrypt the Build-In-Encrypted Files from the RPG Maker MV or MZ. They usually have the extension `.rpgmvp`, `.rpgmvm`, `.rpgmvo`, `.png_`, `.m4a_` or `.ogg_`.
18 |
19 | ## Requirements
20 | - Java 8 or higher
21 | - Any OS (Linux, Windows, IOS etc)
22 |
23 | ## Installation
24 | - [Download this ZIP (!!Alpha!!) - Version: 0.4.2](https://petschko.org/upload/projects/java-rpg-maker-decrypter/RPG_Maker_MV_Decrypter_jar_0.4.2.zip) or Clone/Download the Project and make yourself a JAR-File
25 | - Put it where ever you want (Don't forget to extract, if you downloaded the ZIP xP)
26 |
27 | ### Dependencies (Only needed when creating yourself a JAR)
28 | - [org.json](https://github.com/douglascrockford/JSON-java)
29 |
30 | ## How to use
31 | ### (Normal) With Graphical interface
32 | - Just double-click on the JAR then the Program should start *(If not try the BAT-File - Windows only)*
33 | - Click on the Menu "File" then "Open"
34 | - Browse to the RPG-Maker MV Project which you want decrypt
35 | - Select the Main-Directory of the Project (The Folder where the Game.exe is) on click on "Choose Directory"
36 | - You can also put the Program right into your Game-Directory and select the option "Select Project from current Directory"
37 | - Wait for a short moment =)
38 | - If there are Files listed and a Decryption-Key is in the Text-Box you're ready to Decrypt
39 | - Then go into the Menu and click "Decrypt" -> "All Files"
40 | - After a short moment you're done =)
41 | - You can find the Files now within the "Output"-Directory, which is in the same Directory as this Program. *(If you not changed it already via "File" -> "Change Output-Directory...")*
42 |
43 | - (Not yet implemented) You can also Decrypt single/multiple Files - Select them in the Project-Files Tab after that you go to "Decrypter" -> "Selected Files"
44 | - You can also Re-Encrypt Files (For example if you translated text on images for the Game)
45 | - You can also check out the "Option"-Menu and check if the settings fit to you =)
46 | - (Not yet implemented) You can find this "Manual" also within the "Info"-Menu
47 |
48 | ### Run with CMD - For automation / the guys who like it :3
49 |
50 | In some case it can be useful to do stuff via the commandline. For example, you want to mod a game and make it easy for the user to mod it (like they just need to start a .bat/.sh file which does the stuff)
51 |
52 | - To see the global help (with all sub-commands) type in `java -jar "RPG Maker MV Decrypter.jar" help`
53 | - To see the detailed help of a specific command type in `java -jar "RPG Maker MV Decrypter.jar" [command] help`
54 | - Example (display decrypt help): `java -jar "RPG Maker MV Decrypter.jar" decrypt help`
55 |
56 | For details use and examples how to use it see [CMD Instructions](cmd-instructions.md)
57 |
58 | ## Motivation behind this
59 | As Art-Creator for the RPG-Maker by myself, it is sometimes hard to figure out, if somebody is using Resources from you *(and may violate the licence like giving no credit or using a Non-Commercial-Resource in a Commercial Game for example)*.
60 |
61 | I don't have time to play through all the games (even if I want^^). So I just quick look at the files, but it's only possible if the files are not encrypted...
62 |
63 | Sad for me, more People use the build in Encryption from the RPG-Maker-MV, so that's why I wrote this Program - To get a quick look at the Files without playing the whole Game =) May some other Artists will find this useful too.
64 |
65 | It can be also useful for Translators, e.g. when you want to make a Game available for different Regions. *(IMO you should ask the Creator of the Game first! - Sometimes it's not possible...)*
66 |
67 | I'm also interested in Encryption in general, so this was a good base to learn, since the MV-Encryption is very weak - But it's great that's simple, because it will not slow down weak machines! *(See below)*
68 |
69 | ### Why is the encryption of my Game useless in this case?
70 | Sometimes there is a nice Picture that you may save for yourself. You would even do with without this Decrypter by making a Screenshot (or record the Sound) >.<
71 |
72 | So you see there is no need for encryption in RPG-Maker Games... If someone wants to get the Files, he will be able to get them, this also happens to AAA Games.
73 | You can't encrypt your Files 100%, because the Game has to decrypt them by itself, to display them... (Or Play) - And since you are able to play the Game offline, you have to provide the Decryption Method and the Key.
74 |
75 | ### But somebody will steal my assets
76 | Yeah, that may happen but as said before, you can't stop them anyway (Even without Decrypter). Even if you use a more powerful Encryption - it will just slow down your Game on weak Machines.
77 | Everybody is allowed to save anything for (!)personal use **only**(!) - But you're **not allowed** to create a Game with them. Except it's a free Resource, then you have to follow the Licence of the Resource-Creator!
78 | So please DON'T steal stuff, as Artist I know how much time such stuff take, so DON'T do it!
79 |
80 | ### Why as Java-Project? | Advantages
81 | This Java-Decrypter is better for whole Directories or automated Scripts. It was easier to do it with Java, because you are very limited with JavaScript. (File-Access / Saving etc)
82 | Why Java? - Because I know this Language xP - Feel free to port it to an other language, which may doesn't require the installation of a Run-Time-Environment...
83 |
84 | **Advantages using this in comparison to my previous Project:**
85 | - Works with whole Directories
86 | - It detects Encrypted Files by itself
87 | - It Auto-Saves & Rename Decrypted-Files for you!
88 | - It keeps the Directory-Structure
89 | - You can specify an Output-Directory
90 | - It's able to Detect the Encryption File & Key by its own
91 | - Less buggy and faster than my JavaScript Version, because I'm independent of Browsers and Charset-Problems...
92 | - You can use Command-Line to if you want
93 | - You can, may use it for Modding? Idk I've heard that some do
94 | - Will add a restore Project Function in the future
95 | - You can en/disable the verification of the 16Byte Fake-Header
96 | - If you disable the verification, it will just cut away the Fake-Header aka the first 16 Bytes of the File *(Useful when Decrypter-Signature changes)*
97 | - If you enable the verification it will check if the Files-Header is correct (aka if it's a real Encrypted File)
98 |
99 | ## Be Fair!
100 | You are **not allowed** to use the Decrypted Files (**if its not allowed by the origin Resource-Licence**).
101 | Please **don't steal, reuse or share stuff in Public**! That's not the idea of this Program!
102 |
103 | You can save them for **Personal-Use only**. If the origin Licence allow use you can use them of course, but please follow the Licences!
104 |
105 | **If that's your Project** and you simply lost your Origin-Files, **you have the same rights**, to do stuff with them, **as before** =)
106 |
107 | ## Donate
108 |
109 | If you like this Project and want to thank me may consider to [Donate](https://www.paypal.me/petschko). I appreciate anything, which helps the Project (Pull-Requests, Bug Report etc), these are more worth than Donations but I'm happy for every amount as well. ^.^
110 |
111 | ## Contact
112 | - E-Mail me if you have questions (no bug reporting please): peter@petschko.org
113 | - You can also tell me you like it or not >.< Of course you can make improvement suggestions if you want
114 | - Please report Bugs here on gitlab.com use the "[Issue](https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter/-/issues)"-Section on this Project
115 |
--------------------------------------------------------------------------------
/cmd-instructions.md:
--------------------------------------------------------------------------------
1 | I put the detailed Command-Line explanation here since not many people use it and its pretty "long"
2 |
3 | Everything what's explained here is also explained in the help-commands within the Program.
4 |
5 | # Command explanation
6 |
7 | Before we start:
8 | - You only need the params which are marked as __(Req.)__. All other params are optional.
9 | - If a path contains a space use the quotations "" around: `"D:\games\Project with Space\"`
10 | - Remember that IOS & Linux not have a Drive-Letter nor using the `\ ` as Directory-Separator; use `/` instead when you're using Linux/MacOS
11 | - Important: If you just Type `java -jar "RPG Maker MV Decrypter.jar"` the Program will start with GUI
12 | - You can also use the Help-Command with `java -jar "RPG Maker MV Decrypter.jar" help`
13 | - The Script ends with "Done." Then you're done.
14 |
15 | There exists commands you can use, these are explained here:
16 | - __decrypt__ - Decrypts all Files (Help: `java -jar "RPG Maker MV Decrypter.jar" decrypt help`)
17 | - The Script will decrypt all Files in the target dir
18 | - Simple-Syntax: `java -jar "RPG Maker MV Decrypter.jar" decrypt [(Req.) target path] [output path] [verifyRpgDir (false|true)] [ignoreFakeHeader (true|false)]`
19 | - Full-Syntax: `java -jar "RPG Maker MV Decrypter.jar" decrypt [(Req.) target path] [output path] [verifyRpgDir (false|true)] [ignoreFakeHeader (true|false)] [headerLen (number)] [hsignature] [hversion] [hremain]`
20 | - Example 1: `java -jar "RPG Maker MV Decrypter.jar" decrypt D:\games\Project1\`
21 | - Decrypts the game located in `D:\games\Project1\` and saves files to the output dir of this program
22 | - Example 2: `java -jar "RPG Maker MV Decrypter.jar" decrypt D:\games\Project1\ D:\games\Project1\`
23 | - Decrypts the game located in `D:\games\Project1\` and saves files in the game dir _(preserves structure)_
24 | - Example 3: `java -jar "RPG Maker MV Decrypter.jar" decrypt D:\games\Project1\ D:\games\Project1\ false true d41d8cd98f00b204e9800998ecf8427e`
25 | - Like example 2, just using the Decryption key `d41d8cd98f00b204e9800998ecf8427e`
26 | - You can do more things with `decrypt` please use the help to see more details
27 | - __restore__ - Restores all PNG-Files without a Key (Help: `java -jar "RPG Maker MV Decrypter.jar" restore help`)
28 | - The Script will restore all Files in the target dir _(no key needed)_
29 | - Simple-Syntax: `java -jar "RPG Maker MV Decrypter.jar" restore [(Req.) target path] [output path] [verifyRpgDir (false|true)] [ignoreFakeHeader (true|false)]`
30 | - Full-Syntax: `java -jar "RPG Maker MV Decrypter.jar" restore [(Req.) target path] [output path] [verifyRpgDir (false|true)] [ignoreFakeHeader (true|false)] [headerLen (number)]`
31 | - Example 1: `java -jar "RPG Maker MV Decrypter.jar" restore "C:\my rpg mv game\"`
32 | - Restores all Images in `C:\my rpg mv game\` and saves files to the output dir of this program
33 | - Example 2: `java -jar "RPG Maker MV Decrypter.jar" restore "C:\my rpg mv game\" "C:\my rpg mv game\"`
34 | - Restores all Images in `C:\my rpg mv game\` and saves the restored images also to the game _(preserves structure)_
35 | - Example 3: `java -jar "RPG Maker MV Decrypter.jar" restore "C:\my rpg mv game\" "C:\my rpg mv game\" true false`
36 | - Like Example 2, just adding that the Script should verify it's a RPG-MV/MZ dir and the MV/MZ-Header on the files is correct
37 | - __encrypt__ - Encrypts all Files (Help: `java -jar "RPG Maker MV Decrypter.jar" ecrypt help`)
38 | - This Script (Re-)Encrypts all Files in the target dir
39 | - This Script NEEDs a Key (so it must be either in the Target-dir - `System.json`-File) or given as Parameter
40 | - Simple-Syntax: `java -jar "RPG Maker MV Decrypter.jar" encrypt [(Req.) target path] [output path] [to MV (true|false)] [key (auto|keyValue)]`
41 | - Full-Syntax: `java -jar "RPG Maker MV Decrypter.jar" encrypt [(Req.) target path] [output path] [to MV (true|false)] [key (auto|keyValue)] [headerLen (number)] [hsignature] [hversion] [hremain]`
42 | - Example 1: `java -jar "RPG Maker MV Decrypter.jar" encrypt "C:\my rpg mv game\"`
43 | - Encrypts all resource Files in `C:\my rpg mv game\` to the MV-Format with the detected Key
44 | - Example 2: `java -jar "RPG Maker MV Decrypter.jar" encrypt "C:\my rpg mz game\" output false`
45 | - Encrypts all resource File in `C:\my rpg mz game\` to the output dir of this program in the MZ-Format
46 | - Example 3: `java -jar "RPG Maker MV Decrypter.jar" encrypt "C:\my rpg mz game\" output false d41d8cd98f00b204e9800998ecf8427e`
47 | - Same as Example 2, just using a manual given Key: `d41d8cd98f00b204e9800998ecf8427e`
48 | - You can do more things with `encrypt` please use the help to see more details
49 | - __key__ - Detects and displays the Key (Help: `java -jar "RPG Maker MV Decrypter.jar" key help`)
50 | - This Script shows the Key of the given directory/project
51 | - Simple-Syntax: `java -jar "RPG Maker MV Decrypter.jar" key [(Req.) target path] [ask before image keysearch (true|false)]`
52 | - Full-Syntax: `java -jar "RPG Maker MV Decrypter.jar" key [(Req.) target path] [ask before image keysearch (true|false)] [headerLen (number)]`
53 | - Example 1: `java -jar "RPG Maker MV Decrypter.jar" key "C:\my rpg mv game\"`
54 | - 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
55 | - Example 2: `java -jar "RPG Maker MV Decrypter.jar" key "C:\my rpg mv game\" false`
56 | - Same as Example 1, just don't ask if search on images, it will always do automatically
57 | - __update__ - Updates the Program (Help: `java -jar "RPG Maker MV Decrypter.jar" update help`)
58 | - This Script updates the Program
59 | - Syntax: `java -jar "RPG Maker MV Decrypter.jar" update [(Optional) Sub-Command]`
60 | - Program Update Command: `java -jar "RPG Maker MV Decrypter.jar" update`
61 | - Open "What's new" in your Default-Browser: `java -jar "RPG Maker MV Decrypter.jar" update whatsnew`
62 |
--------------------------------------------------------------------------------
/deployment/start.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | java -jar "RPG Maker MV Decrypter.jar"
3 | pause
4 |
--------------------------------------------------------------------------------
/deployment/start.sh:
--------------------------------------------------------------------------------
1 | java -jar "RPG Maker MV Decrypter.jar"
--------------------------------------------------------------------------------
/deployment/update.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petschko/Java-RPG-Maker-MV-Decrypter/b6eb85c2aafacc07f14a6ee1d3def707e8721b3d/deployment/update.jar
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
The {@link #fillInStackTrace()} method is called to initialize 17 | * the stack trace data in the newly created throwable. 18 | * 19 | * @param path - Path of the Exception 20 | */ 21 | public PathException(String path) { 22 | super(); 23 | this.path = path; 24 | } 25 | 26 | /** 27 | * Constructs a new throwable with the specified detail message. The 28 | * cause is not initialized, and may subsequently be initialized by 29 | * a call to {@link #initCause}. 30 | * 31 | *
The {@link #fillInStackTrace()} method is called to initialize 32 | * the stack trace data in the newly created throwable. 33 | * 34 | * @param message the detail message. The detail message is saved for 35 | * later retrieval by the {@link #getMessage()} method. 36 | * @param path - Path of the Exception 37 | */ 38 | public PathException(String message, String path) { 39 | super(message); 40 | this.path = path; 41 | } 42 | 43 | /** 44 | * Constructs a new throwable with the specified detail message and 45 | * cause.
Note that the detail message associated with 46 | * {@code cause} is not automatically incorporated in 47 | * this throwable's detail message. 48 | * 49 | *
The {@link #fillInStackTrace()} method is called to initialize 50 | * the stack trace data in the newly created throwable. 51 | * 52 | * @param message the detail message (which is saved for later retrieval 53 | * by the {@link #getMessage()} method). 54 | * @param path - Path of the Exception 55 | * @param cause the cause (which is saved for later retrieval by the 56 | * {@link #getCause()} method). (A {@code null} value is 57 | * permitted, and indicates that the cause is nonexistent or 58 | * unknown.) 59 | */ 60 | public PathException(String message, String path, Throwable cause) { 61 | super(message, cause); 62 | this.path = path; 63 | } 64 | 65 | /** 66 | * Constructs a new throwable with the specified cause and a detail 67 | * message of {@code (cause==null ? null : cause.toString())} (which 68 | * typically contains the class and detail message of {@code cause}). 69 | * This constructor is useful for throwables that are little more than 70 | * wrappers for other throwables (for example, {@link 71 | * PrivilegedActionException}). 72 | * 73 | *
The {@link #fillInStackTrace()} method is called to initialize 74 | * the stack trace data in the newly created throwable. 75 | * 76 | * @param path - Path of the Exception 77 | * @param cause the cause (which is saved for later retrieval by the 78 | * {@link #getCause()} method). (A {@code null} value is 79 | * permitted, and indicates that the cause is nonexistent or 80 | * unknown.) 81 | */ 82 | public PathException(String path, Throwable cause) { 83 | super(cause); 84 | this.path = path; 85 | } 86 | 87 | /** 88 | * Constructs a new throwable with the specified detail message, 89 | * cause, {@linkplain #addSuppressed suppression} enabled or 90 | * disabled, and writable stack trace enabled or disabled. If 91 | * suppression is disabled, {@link #getSuppressed} for this object 92 | * will return a zero-length array and calls to {@link 93 | * #addSuppressed} that would otherwise append an exception to the 94 | * suppressed list will have no effect. If the writable stack 95 | * trace is false, this constructor will not call {@link 96 | * #fillInStackTrace()}, a {@code null} will be written to the 97 | * {@code stackTrace} field, and subsequent calls to {@code 98 | * fillInStackTrace} and {@link 99 | * #setStackTrace(StackTraceElement[])} will not set the stack 100 | * trace. If the writable stack trace is false, {@link 101 | * #getStackTrace} will return a zero length array. 102 | * 103 | *
Note that the other constructors of {@code Throwable} treat
104 | * suppression as being enabled and the stack trace as being
105 | * writable. Subclasses of {@code Throwable} should document any
106 | * conditions under which suppression is disabled and document
107 | * conditions under which the stack trace is not writable.
108 | * Disabling of suppression should only occur in exceptional
109 | * circumstances where special requirements exist, such as a
110 | * virtual machine reusing exception objects under low-memory
111 | * situations. Circumstances where a given exception object is
112 | * repeatedly caught and rethrown, such as to implement control
113 | * flow between two sub-systems, is another situation where
114 | * immutable throwable objects would be appropriate.
115 | *
116 | * @param message the detail message.
117 | * @param path - Path of the Exception
118 | * @param cause the cause. (A {@code null} value is permitted,
119 | * and indicates that the cause is nonexistent or unknown.)
120 | * @param enableSuppression whether or not suppression is enabled or disabled
121 | * @param writableStackTrace whether or not the stack trace should be
122 | * writable
123 | * @see OutOfMemoryError
124 | * @see NullPointerException
125 | * @see ArithmeticException
126 | */
127 | protected PathException(String message, String path, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
128 | super(message, cause, enableSuppression, writableStackTrace);
129 | this.path = path;
130 | }
131 |
132 | /**
133 | * Gets the Path
134 | *
135 | * @return - Path of the Exception
136 | */
137 | public String getPath() {
138 | return path;
139 | }
140 |
141 | /**
142 | * Returns the detail message string of this throwable.
143 | *
144 | * @return the detail message string of this {@code Throwable} instance
145 | * (which may be {@code null}).
146 | */
147 | @Override
148 | public String getMessage() {
149 | return super.getMessage() + " | Path: " + (this.getPath() == null ? "null" : this.getPath());
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/GUI_About.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui;
2 |
3 | import javax.swing.JButton;
4 | import javax.swing.JComponent;
5 | import javax.swing.JDialog;
6 | import javax.swing.JFrame;
7 | import java.awt.Component;
8 | import java.awt.GraphicsEnvironment;
9 | import java.awt.HeadlessException;
10 | import java.awt.event.ActionListener;
11 | import java.awt.event.WindowAdapter;
12 | import java.awt.event.WindowEvent;
13 |
14 | /**
15 | * @author Peter Dragicevic
16 | */
17 | public abstract class GUI_About extends JDialog {
18 | protected JImageLabel imagePanel;
19 | protected Component parent;
20 | protected JButton closeButton;
21 |
22 | /**
23 | * Creates a new, initially invisible Frame
with the
24 | * specified title.
25 | *
26 | * This constructor sets the component's locale property to the value
27 | * returned by Note that the detail message associated with
71 | * {@code cause} is not automatically incorporated in
72 | * this exception's detail message.
73 | *
74 | * @param message the detail message (which is saved for later retrieval
75 | * by the {@link #getMessage()} method).
76 | * @param currentVersion - Current Version
77 | * @param cause the cause (which is saved for later retrieval by the
78 | * {@link #getCause()} method). (A null value is
79 | * permitted, and indicates that the cause is nonexistent or
80 | * unknown.)
81 | */
82 | public UpdateException(String message, Version currentVersion, Throwable cause) {
83 | super(message, cause);
84 | this.setCurrentVersion(currentVersion);
85 | }
86 |
87 | /**
88 | * Constructs a new exception with the specified detail message and
89 | * cause. Note that the detail message associated with
90 | * {@code cause} is not automatically incorporated in
91 | * this exception's detail message.
92 | *
93 | * @param message the detail message (which is saved for later retrieval
94 | * by the {@link #getMessage()} method).
95 | * @param currentVersion - Current Version
96 | * @param newestVersion - Newest Version or null for none
97 | * @param cause the cause (which is saved for later retrieval by the
98 | * {@link #getCause()} method). (A null value is
99 | * permitted, and indicates that the cause is nonexistent or
100 | * unknown.)
101 | */
102 | public UpdateException(String message, Version currentVersion, Version newestVersion, Throwable cause) {
103 | super(message, cause);
104 | this.setCurrentVersion(currentVersion);
105 | this.setNewestVersion(newestVersion);
106 | }
107 |
108 | /**
109 | * Constructs a new exception with the specified cause and a detail
110 | * message of (cause==null ? null : cause.toString()) (which
111 | * typically contains the class and detail message of cause).
112 | * This constructor is useful for exceptions that are little more than
113 | * wrappers for other throwables (for example, {@link
114 | * PrivilegedActionException}).
115 | *
116 | * @param currentVersion - Current Version
117 | * @param cause the cause (which is saved for later retrieval by the
118 | * {@link #getCause()} method). (A null value is
119 | * permitted, and indicates that the cause is nonexistent or
120 | * unknown.)
121 | */
122 | public UpdateException(Version currentVersion, Throwable cause) {
123 | super(cause);
124 | this.setCurrentVersion(currentVersion);
125 | }
126 |
127 | /**
128 | * Constructs a new exception with the specified cause and a detail
129 | * message of (cause==null ? null : cause.toString()) (which
130 | * typically contains the class and detail message of cause).
131 | * This constructor is useful for exceptions that are little more than
132 | * wrappers for other throwables (for example, {@link
133 | * PrivilegedActionException}).
134 | *
135 | * @param currentVersion - Current Version
136 | * @param newestVersion - Newest Version or null for none
137 | * @param cause the cause (which is saved for later retrieval by the
138 | * {@link #getCause()} method). (A null value is
139 | * permitted, and indicates that the cause is nonexistent or
140 | * unknown.)
141 | */
142 | public UpdateException(Version currentVersion, Version newestVersion, Throwable cause) {
143 | super(cause);
144 | this.setCurrentVersion(currentVersion);
145 | this.setNewestVersion(newestVersion);
146 | }
147 |
148 | /**
149 | * Constructs a new exception with the specified detail message,
150 | * cause, suppression enabled or disabled, and writable stack
151 | * trace enabled or disabled.
152 | *
153 | * @param message the detail message.
154 | * @param currentVersion - Current Version
155 | * @param cause the cause. (A {@code null} value is permitted,
156 | * and indicates that the cause is nonexistent or unknown.)
157 | * @param enableSuppression whether or not suppression is enabled
158 | * or disabled
159 | * @param writableStackTrace whether or not the stack trace should
160 | * be writable
161 | */
162 | protected UpdateException(String message, Version currentVersion, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
163 | super(message, cause, enableSuppression, writableStackTrace);
164 | this.setCurrentVersion(currentVersion);
165 | }
166 |
167 | /**
168 | * Constructs a new exception with the specified detail message,
169 | * cause, suppression enabled or disabled, and writable stack
170 | * trace enabled or disabled.
171 | *
172 | * @param message the detail message.
173 | * @param currentVersion - Current Version
174 | * @param newestVersion - Newest Version or null for none
175 | * @param cause the cause. (A {@code null} value is permitted,
176 | * and indicates that the cause is nonexistent or unknown.)
177 | * @param enableSuppression whether or not suppression is enabled
178 | * or disabled
179 | * @param writableStackTrace whether or not the stack trace should
180 | * be writable
181 | */
182 | protected UpdateException(String message, Version currentVersion, Version newestVersion, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
183 | super(message, cause, enableSuppression, writableStackTrace);
184 | this.setCurrentVersion(currentVersion);
185 | this.setNewestVersion(newestVersion);
186 | }
187 |
188 | /**
189 | * Get the current Version
190 | *
191 | * @return - Current Version
192 | */
193 | public Version getCurrentVersion() {
194 | return currentVersion;
195 | }
196 |
197 | /**
198 | * Get the current Version as String
199 | *
200 | * @return - Current Version as String
201 | */
202 | public String getCurrentVersionAsString() {
203 | return currentVersion.getVersion();
204 | }
205 |
206 | /**
207 | * Set the current Version
208 | *
209 | * @param currentVersion - Current Version
210 | */
211 | private void setCurrentVersion(Version currentVersion) {
212 | this.currentVersion = currentVersion;
213 | }
214 |
215 | /**
216 | * Get the newest Version
217 | *
218 | * @return - Newest Version or null
219 | */
220 | public Version getNewestVersion() {
221 | return newestVersion;
222 | }
223 |
224 | /**
225 | * Get the newest Version as String
226 | *
227 | * @return - Newest Version as String
228 | */
229 | public String getNewestVersionAsString() {
230 | if(this.newestVersion == null)
231 | return "";
232 |
233 | return newestVersion.getVersion();
234 | }
235 |
236 | /**
237 | * Set the newest Version
238 | *
239 | * @param newestVersion - Newest Version or null
240 | */
241 | private void setNewestVersion(Version newestVersion) {
242 | this.newestVersion = newestVersion;
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/update/Version.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.update;
2 |
3 | /**
4 | * @author Peter Dragicevic
5 | */
6 | public class Version {
7 | private String version;
8 |
9 | /**
10 | * Version constructor
11 | *
12 | * @param version - Version
13 | */
14 | public Version(String version) {
15 | this.version = version;
16 | }
17 |
18 | /**
19 | * Get the Version
20 | *
21 | * @return - Version
22 | */
23 | public String getVersion() {
24 | return version;
25 | }
26 |
27 | /**
28 | * Compares 2 Versions
29 | *
30 | * @param version - Version to compare
31 | * @return - Versions are equal
32 | */
33 | public boolean versionsEqual(Version version) {
34 | return this.version.equals(version.getVersion());
35 | }
36 |
37 | /**
38 | * Checks if this Version is lower than the other Version
39 | *
40 | * @param version - Version to compare
41 | * @return - This Version is lower than the other
42 | */
43 | public boolean thisIsLowerThan(Version version) {
44 | String[] thisVersion = this.version.split("\\.");
45 | String[] otherVersion = version.version.split("\\.");
46 |
47 | // Ensure same length arrays
48 | if(thisVersion.length > otherVersion.length) {
49 | String[] tmp = new String[thisVersion.length];
50 |
51 | for(int i = 0; i < tmp.length; i++) {
52 | if(i < otherVersion.length)
53 | tmp[i] = otherVersion[i];
54 | else
55 | tmp[i] = "0";
56 | }
57 |
58 | otherVersion = tmp;
59 | } else if(otherVersion.length > thisVersion.length) {
60 | String[] tmp = new String[otherVersion.length];
61 |
62 | for(int i = 0; i < tmp.length; i++) {
63 | if(i < thisVersion.length)
64 | tmp[i] = thisVersion[i];
65 | else
66 | tmp[i] = "0";
67 | }
68 |
69 | thisVersion = tmp;
70 | }
71 |
72 | // Compare Versions
73 | for(int n = 0; n < thisVersion.length; n++) {
74 | int thisNumber = Integer.parseInt(thisVersion[n]);
75 | int otherNumber = Integer.parseInt(otherVersion[n]);
76 |
77 | if(thisNumber < otherNumber)
78 | return true;
79 | }
80 |
81 | return false;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/App.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt;
2 |
3 | import org.petschko.lib.Const;
4 | import org.petschko.lib.File;
5 | import org.petschko.lib.gui.notification.ErrorWindow;
6 | import org.petschko.rpgmakermv.decrypt.cmd.CMD;
7 | import org.petschko.rpgmakermv.decrypt.gui.GUI;
8 |
9 | import java.io.IOException;
10 | import java.util.jar.Attributes;
11 | import java.util.jar.Manifest;
12 |
13 | /**
14 | * @author Peter Dragicevic
15 | */
16 | public class App {
17 | private static Boolean useGUI = true;
18 | private static GUI gui;
19 | private static CMD cmd;
20 | public static String outputDir;
21 | public static Preferences preferences;
22 |
23 | /**
24 | * Main-Class
25 | *
26 | * @param args - Optional Arguments from Command-Line
27 | */
28 | public static void main(String[] args) {
29 | // Dynamically read the Versions number into the CFG
30 | Config.setVersion(readMfVersion());
31 |
32 | // Ensure System output dir always exists
33 | if(! File.existsDir(Config.DEFAULT_OUTPUT_DIR))
34 | File.createDirectory(Config.DEFAULT_OUTPUT_DIR);
35 |
36 | // Check whats given from CMD
37 | if(args.length > 0) {
38 | useGUI = false;
39 | cmd = new CMD(args);
40 | }
41 |
42 | if(useGUI) {
43 | // Show something when its started via .bat or shell file
44 | System.out.println(Config.PROGRAM_NAME + " - " + Config.VERSION + " by " + Const.CREATOR);
45 |
46 | // Use GUI
47 | preferences = new Preferences(Config.PREFERENCES_FILE);
48 | outputDir = App.preferences.getConfig(Preferences.LAST_OUTPUT_DIR, Config.DEFAULT_OUTPUT_DIR);
49 | gui = new GUI();
50 | } else {
51 | // Use Command-Line Version
52 | cmd.runCMD();
53 | }
54 | }
55 |
56 | /**
57 | * Shows the given message if no GUI is enabled
58 | *
59 | * @param msg - Message to display
60 | * @param messageStatus - Status of the Message
61 | */
62 | public static void showMessage(String msg, int messageStatus) {
63 | String status;
64 |
65 | switch(messageStatus) {
66 | case CMD.STATUS_ERROR:
67 | status = "[ERROR]: ";
68 | break;
69 | case CMD.STATUS_WARNING:
70 | status = "[WARN]: ";
71 | break;
72 | case CMD.STATUS_OK:
73 | status = "[SUCCESS]: ";
74 | break;
75 | default:
76 | status = "[INFO]: ";
77 | }
78 |
79 | if(! App.useGUI)
80 | System.out.println(status + msg);
81 | }
82 |
83 | /**
84 | * Shows the given message if no GUI is enabled
85 | *
86 | * @param msg - Message to display
87 | */
88 | public static void showMessage(String msg) {
89 | showMessage(msg, CMD.STATUS_INFO);
90 | }
91 |
92 | /**
93 | * Saves the settings, close the GUI and quit the Program
94 | */
95 | public static void closeGUI() {
96 | if(! App.preferences.save()) {
97 | ErrorWindow errorWindow = new ErrorWindow("Can't save Settings...", ErrorWindow.ERROR_LEVEL_ERROR, false);
98 | errorWindow.show();
99 | }
100 |
101 | App.gui.dispose();
102 | System.exit(0);
103 | }
104 |
105 | /**
106 | * Returns the Version-Number from the Manifest-File
107 | *
108 | * @return - Version number from the Manifest File or null for debug
109 | */
110 | public static String readMfVersion() {
111 | Manifest mf = new Manifest();
112 | try {
113 | mf.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"));
114 | } catch (IOException e) {
115 | throw new RuntimeException(e);
116 | }
117 |
118 | Attributes attributes = mf.getMainAttributes();
119 | return attributes.getValue("Version");
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/Config.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt;
2 |
3 | /**
4 | * @author Peter Dragicevic
5 | */
6 | public class Config {
7 | // Program Info
8 | public static String VERSION_NUMBER;
9 | public static String VERSION = "v%s Alpha";
10 | public static final String PROGRAM_NAME = "RPG-Maker MV/MZ Decrypter";
11 | public static final String PROJECT_PAGE_URL = "https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter";
12 | public static final String PROJECT_BUG_REPORT_URL = "https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter/-/issues";
13 | public static final String PROJECT_LICENCE_URL = "https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter/-/blob/master/LICENCE";
14 | public static final String AUTHOR_IMAGE = "/icons/petschko_icon.png";
15 | public static final String UPDATE_URL = "https://gitlab.com/Petschko/Java-RPG-Maker-MV-Decrypter/-/raw/master/version.txt?ref_type=heads";
16 |
17 | // File-Path-Settings
18 | public static final String DEFAULT_OUTPUT_DIR = "output";
19 | public static final String PREFERENCES_FILE = "config.pref";
20 |
21 | // Misc Settings
22 | public static boolean UPDATE_CHECK = true;
23 | public static final long UPDATE_CHECK_EVERY_SECS = 172800;
24 | public static final String THIS_JAR_FILE_NAME = "RPG Maker MV Decrypter.jar";
25 |
26 | /**
27 | * Constructor
28 | */
29 | private Config() {
30 | // VOID - This is a Static-Class
31 | }
32 |
33 | /**
34 | * Set the Version-Number to the Config
35 | *
36 | * @param version - Versions Number-String or NULL
37 | */
38 | public static void setVersion(String version) {
39 | VERSION_NUMBER = version;
40 | VERSION = String.format(VERSION, VERSION_NUMBER == null ? "NULL" : VERSION_NUMBER);
41 |
42 | if(VERSION_NUMBER == null)
43 | UPDATE_CHECK = false;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/Finder.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt;
2 |
3 | import org.petschko.lib.Const;
4 | import org.petschko.lib.File;
5 |
6 | import java.util.ArrayList;
7 |
8 | /**
9 | * @author Peter Dragicevic
10 | */
11 | class Finder {
12 | /**
13 | * Constructor
14 | */
15 | private Finder() {
16 | // VOID - This is a Static-Class
17 | }
18 |
19 | /**
20 | * Search all know places for the System-File
21 | *
22 | * @param projectDir - Directory of the Project
23 | * @return - System-File-Object if found else null
24 | */
25 | static File findSystemFile(String projectDir) {
26 | String[] filePaths = new String[] {
27 | "data" + Const.DS + "System.json",
28 | "www" + Const.DS + "data" + Const.DS + "System.json"
29 | };
30 |
31 | return findFromArray(filePaths, projectDir);
32 | }
33 |
34 | /**
35 | * Finds the Project-File
36 | *
37 | * @param projectDir - Directory were to search
38 | * @return - Project File or null if not found
39 | */
40 | static File findProjectFile(String projectDir) {
41 | String[] potentialPaths = new String[] {
42 | "Game.rpgproject",
43 | "game.rmmzproject"
44 | };
45 |
46 | return findFromArray(potentialPaths, projectDir);
47 | }
48 |
49 | /**
50 | * Check if Encryption-Key name is may different from given - Tests all know Encryption-Key Names
51 | *
52 | * @param systemFile - System.json File
53 | * @return - Key-Name or null if not found
54 | */
55 | static String testEncryptionKeyNames(File systemFile) {
56 | String[] keyNames = new String[]{"encryptionKey"};
57 | Decrypter d = new Decrypter();
58 | String result = null;
59 |
60 | for(String keyName : keyNames) {
61 | try {
62 | d.detectEncryptionKeyFromJson(systemFile, keyName);
63 |
64 | if(d.getDecryptCode() != null) {
65 | result = keyName;
66 | break;
67 | }
68 | } catch(Exception e) {
69 | // Void
70 | }
71 | }
72 |
73 | return result;
74 | }
75 |
76 | /**
77 | * Checks if there is a RPG-Maker file within the Directory
78 | *
79 | * @param dir - Path to the Directory
80 | * @return - true if a File was found else false
81 | */
82 | static boolean verifyRPGDir(String dir) {
83 | if(dir == null) {
84 | Exception e = new Exception("Dir can't be null!");
85 | e.printStackTrace();
86 | return false;
87 | }
88 |
89 | ArrayList
30 | * This constructor sets the component's locale property to the value
31 | * returned by JComponent.getDefaultLocale
.
28 | *
29 | * @param title the title for the frame
30 | * @param relativeTo relative to which parent component
31 | * @throws HeadlessException if GraphicsEnvironment.isHeadless()
32 | * returns true.
33 | * @see GraphicsEnvironment#isHeadless
34 | * @see Component#setSize
35 | * @see Component#setVisible
36 | * @see JComponent#getDefaultLocale
37 | */
38 | public GUI_About(String title, JFrame relativeTo) throws HeadlessException {
39 | super(relativeTo, title, JDialog.DEFAULT_MODALITY_TYPE);
40 | this.parent = relativeTo;
41 | this.imagePanel = this.aboutIcon();
42 |
43 | this.setVisible(false);
44 | this.createCloseButton();
45 | this.constructAbout();
46 | this.windowCloseOperation();
47 |
48 | this.setLocationRelativeTo(this.parent);
49 | }
50 |
51 | /**
52 | * Construct the Content of the About-Window
53 | */
54 | protected abstract void constructAbout();
55 |
56 | /**
57 | * Returns the text of the Close-Button
58 | *
59 | * @return - Button-Text
60 | */
61 | protected abstract String closeButtonText();
62 |
63 | /**
64 | * Creates the About-Icon
65 | *
66 | * @return - JImageLabel or null if not set
67 | */
68 | protected abstract JImageLabel aboutIcon();
69 |
70 | /**
71 | * Window Close Operation
72 | */
73 | protected void windowCloseOperation() {
74 | this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
75 | this.addWindowListener(new WindowAdapter() {
76 | @Override
77 | public void windowClosing(WindowEvent e) {
78 | hideWindow();
79 | }
80 | });
81 | }
82 |
83 | /**
84 | * Creates the close Button
85 | */
86 | protected void createCloseButton() {
87 | this.closeButton = new JButton(this.closeButtonText());
88 | this.closeButton.addActionListener(this.closeButtonAction());
89 | }
90 |
91 | /**
92 | * Close Action for the Button
93 | *
94 | * @return - ActionListener
95 | */
96 | protected ActionListener closeButtonAction() {
97 | return e -> this.hideWindow();
98 | }
99 |
100 | /**
101 | * Show this Window
102 | */
103 | public void showWindow() {
104 | this.setLocationRelativeTo(this.parent);
105 | this.setVisible(true);
106 | this.setAlwaysOnTop(true);
107 | }
108 |
109 | /**
110 | * Hides the Window
111 | */
112 | protected void hideWindow() {
113 | this.setAlwaysOnTop(false);
114 | this.setVisible(false);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/JDirectoryChooser.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui;
2 |
3 | import javax.swing.JFileChooser;
4 | import java.io.File;
5 |
6 | /**
7 | * @author Peter Dragicevic
8 | */
9 | public class JDirectoryChooser extends JFileChooser{
10 | /**
11 | * Constructs a JFileChooser
using the given path.
12 | * Passing in a null
13 | * string causes the file chooser to point to the user's default directory.
14 | * This default depends on the operating system. It is
15 | * typically the "My Documents" folder on Windows, and the user's
16 | * home directory on Unix.
17 | *
18 | * @param currentDirectoryPath a String
giving the path
19 | * to a file or directory
20 | */
21 | public JDirectoryChooser(String currentDirectoryPath) {
22 | super(currentDirectoryPath);
23 |
24 | this.setupDirChooser();
25 | }
26 |
27 | /**
28 | * Constructs a JFileChooser
using the given File
29 | * as the path. Passing in a null
file
30 | * causes the file chooser to point to the user's default directory.
31 | * This default depends on the operating system. It is
32 | * typically the "My Documents" folder on Windows, and the user's
33 | * home directory on Unix.
34 | *
35 | * @param currentDirectory a File
object specifying
36 | * the path to a file or directory
37 | */
38 | public JDirectoryChooser(File currentDirectory) {
39 | super(currentDirectory);
40 |
41 | this.setupDirChooser();
42 | }
43 |
44 | /**
45 | * Setup the Parameter so that it look & works like a DirectoryChooser
46 | */
47 | private void setupDirChooser() {
48 | this.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
49 | this.setAcceptAllFileFilterUsed(false);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/JImageLabel.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui;
2 |
3 | import org.petschko.lib.Image;
4 |
5 | import javax.imageio.ImageIO;
6 | import javax.swing.ImageIcon;
7 | import javax.swing.JLabel;
8 | import java.awt.image.BufferedImage;
9 | import java.io.IOException;
10 | import java.net.URL;
11 |
12 | /**
13 | * @author Peter Dragicevic
14 | */
15 | public class JImageLabel extends JLabel {
16 | private BufferedImage image = null;
17 |
18 | /**
19 | * Creates a new JPanel
with a double buffer
20 | * and a flow layout.
21 | *
22 | * @param imagePath - Path of the Image
23 | */
24 | public JImageLabel(String imagePath) {
25 | this.setImage(imagePath, false);
26 | }
27 |
28 | /**
29 | * Creates a new JPanel
with a double buffer
30 | * and a flow layout.
31 | *
32 | * @param image - File Pointing to the Image
33 | */
34 | public JImageLabel(java.io.File image) {
35 | this.setImage(image);
36 | }
37 |
38 | /**
39 | * Creates a new JPanel
with a double buffer
40 | * and a flow layout.
41 | *
42 | * @param imagePath - Path or ClassPath to the Image
43 | * @param useURL - true if use class path else false
44 | */
45 | public JImageLabel(String imagePath, boolean useURL) {
46 | this.setImage(imagePath, useURL);
47 | }
48 |
49 | /**
50 | * Returns the Image as BufferedImage
51 | *
52 | * @return - Buffered Image or null if not set
53 | */
54 | public BufferedImage getImage() {
55 | return image;
56 | }
57 |
58 | /**
59 | * Set this Image direct as Buffered Image
60 | *
61 | * @param image - new BufferedImage
62 | */
63 | public void setImage(BufferedImage image) {
64 | this.image = image;
65 | this.createImagePanel();
66 | }
67 |
68 | /**
69 | * Set a new Image as File for the Panel
70 | *
71 | * @param file - File Pointing to the Image
72 | */
73 | public void setImage(java.io.File file) {
74 | this.setBufferedImage(file);
75 | }
76 |
77 | /**
78 | * Set a new Image as String (Path or Class-Path) for the Panel
79 | *
80 | * @param imagePath - Path or Class-Path
81 | * @param useURL - true uses Class-Path instead of a Path
82 | */
83 | public void setImage(String imagePath, boolean useURL) {
84 | if(imagePath == null) {
85 | Exception e = new Exception("Image Path can't be null");
86 | e.printStackTrace();
87 | return;
88 | }
89 |
90 | if(useURL) {
91 | this.setBufferedImage(getClass().getResource(imagePath));
92 | } else {
93 | java.io.File imageFile;
94 |
95 | try {
96 | imageFile = new java.io.File(imagePath);
97 | } catch(Exception e) {
98 | e.printStackTrace();
99 | this.image = null;
100 |
101 | return;
102 | }
103 |
104 | this.setBufferedImage(imageFile);
105 | }
106 | }
107 |
108 | /**
109 | * Reads the imageURL
110 | *
111 | * @param imageURL - URL of the Image
112 | */
113 | private void setBufferedImage(URL imageURL) {
114 | if(imageURL == null) {
115 | this.image = null;
116 |
117 | return;
118 | }
119 |
120 | try {
121 | this.image = ImageIO.read(imageURL);
122 | } catch(IOException e) {
123 | e.printStackTrace();
124 | this.image = null;
125 |
126 | return;
127 | }
128 |
129 | // Try to create the new Panel after reading
130 | this.createImagePanel();
131 | }
132 |
133 | /**
134 | * Reads an Image-File
135 | *
136 | * @param imageFile - Image-File
137 | */
138 | private void setBufferedImage(java.io.File imageFile) {
139 | try {
140 | this.image = ImageIO.read(imageFile);
141 | } catch(IOException e) {
142 | e.printStackTrace();
143 | this.image = null;
144 |
145 | return;
146 | }
147 |
148 | // Try to create the new Panel after reading
149 | this.createImagePanel();
150 | }
151 |
152 | /**
153 | * Assign the Buffered Image to the Panel
154 | */
155 | private void createImagePanel() {
156 | if(this.image != null)
157 | this.setIcon(new ImageIcon(this.image));
158 | }
159 |
160 | /**
161 | * Resize the Element
162 | *
163 | * @param width - New Width
164 | * @param height - New Height
165 | */
166 | public void setImageSize(int width, int height) {
167 | Image img = new Image(this.image);
168 |
169 | try {
170 | img.resize(width, height);
171 | } catch(Exception e) {
172 | e.printStackTrace();
173 |
174 | return;
175 | }
176 |
177 | this.setImage(img.getBufferedImage());
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/JLabelExtra.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui;
2 |
3 | import javax.swing.JLabel;
4 | import java.awt.Color;
5 | import java.awt.Cursor;
6 | import java.awt.Desktop;
7 | import java.awt.event.MouseAdapter;
8 | import java.awt.event.MouseEvent;
9 | import java.awt.font.TextAttribute;
10 | import java.io.IOException;
11 | import java.net.URI;
12 | import java.net.URISyntaxException;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | /**
17 | * @author Peter Dragicevic
18 | */
19 | public class JLabelExtra extends JLabel {
20 | private String url = null;
21 | private MouseAdapter urlClickEvent = null;
22 | private boolean isBold = false;
23 | private boolean isUnderline = false;
24 | private boolean isItalic = false;
25 |
26 | /**
27 | * Creates a JLabel
instance with the specified
28 | * text and horizontal alignment.
29 | * The label is centered vertically in its display area.
30 | *
31 | * @param text The text to be displayed by the label.
32 | * @param horizontalAlignment One of the following constants
33 | * defined in SwingConstants
:
34 | * LEFT
,
35 | * CENTER
,
36 | * RIGHT
,
37 | * LEADING
or
38 | */
39 | public JLabelExtra(String text, int horizontalAlignment) {
40 | super(text, horizontalAlignment);
41 | }
42 |
43 | /**
44 | * Creates a JLabel
instance with the specified text.
45 | * The label is aligned against the leading edge of its display area,
46 | * and centered vertically.
47 | *
48 | * @param text The text to be displayed by the label.
49 | */
50 | public JLabelExtra(String text) {
51 | super(text);
52 | }
53 |
54 | /**
55 | * Creates a JLabel
instance with
56 | * no image and with an empty string for the title.
57 | * The label is centered vertically
58 | * in its display area.
59 | * The label's contents, once set, will be displayed on the leading edge
60 | * of the label's display area.
61 | */
62 | public JLabelExtra() {
63 | // Void
64 | }
65 |
66 | /**
67 | * Sets the Text-Color of the JLabelExtra
68 | *
69 | * @param color - new Color for the Text or null for default
70 | */
71 | public void setTextColor(Color color) {
72 | if(color == null) {
73 | this.setForeground(new JLabel().getForeground());
74 | return;
75 | }
76 |
77 | this.setForeground(color);
78 | }
79 |
80 | /**
81 | * Sets if the Text should be Bold
82 | *
83 | * @param bold - true if the text should be bold else false
84 | */
85 | public void setBold(boolean bold) {
86 | if(bold && ! this.isBold) {
87 | // Set it Bold
88 | this.changeStyleAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
89 | this.isBold = true;
90 | } else if(! bold && this.isBold) {
91 | // Remove Bold
92 | this.changeStyleAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
93 | this.isBold = false;
94 | }
95 | }
96 |
97 | /**
98 | * Sets if the Text should be Underlined
99 | *
100 | * @param underline - true if the text should be underlined else false
101 | */
102 | public void setUnderline(boolean underline) {
103 | if(underline && ! this.isUnderline) {
104 | // Underline it
105 | this.changeStyleAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
106 | this.isUnderline = true;
107 | } else if(! underline && this.isUnderline) {
108 | // Remove Underline
109 | this.changeStyleAttribute(TextAttribute.UNDERLINE, -1);
110 | this.isUnderline = false;
111 | }
112 | }
113 |
114 | /**
115 | * Sets if the Text should be Italic
116 | *
117 | * @param italic - true if the text should be italic else false
118 | */
119 | public void setItalic(boolean italic) {
120 | if(italic && ! this.isItalic) {
121 | // Set Italic
122 | this.changeStyleAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
123 | this.isItalic = true;
124 | } else if(! italic && this.isItalic) {
125 | // Remove Italic
126 | this.changeStyleAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
127 | this.isItalic = false;
128 | }
129 | }
130 |
131 | /**
132 | * Sets the Font-Type of the Text
133 | *
134 | * @param fontType - Font-Type of the Text or null for default
135 | */
136 | public void setFontType(String fontType) {
137 | if(fontType == null) {
138 | this.changeStyleAttribute(TextAttribute.FONT, new JLabel().getFont().getFontName());
139 | return;
140 | }
141 |
142 | this.changeStyleAttribute(TextAttribute.FONT, fontType);
143 | }
144 |
145 | /**
146 | * Sets the size of the Text
147 | *
148 | * @param fontSize - Font-Size of the Text or <=0 for default
149 | */
150 | public void setFontSize(int fontSize) {
151 | if(fontSize < 1) {
152 | this.changeStyleAttribute(TextAttribute.SIZE, new JLabel().getFont().getSize());
153 | return;
154 | }
155 |
156 | this.changeStyleAttribute(TextAttribute.SIZE, fontSize);
157 | }
158 |
159 | /**
160 | * Set a URL and let the User click on this
161 | *
162 | * @param url - URL to set or null if you want remove the URL
163 | * @param defaultURLStyle - true Styles the URL for you Underlined-Blue else it don't style it for you
164 | */
165 | public void setURL(String url, boolean defaultURLStyle) {
166 | if(url == null) {
167 | this.removeURL(defaultURLStyle);
168 | return;
169 | }
170 |
171 | if(this.url != null) {
172 | // Don't change anything if the url is the same
173 | if(this.url.equals(url))
174 | return;
175 |
176 | // Remove old URL if url is different
177 | this.removeURL(defaultURLStyle);
178 | }
179 |
180 | // Styles
181 | if(defaultURLStyle) {
182 | this.setUnderline(true);
183 | this.setTextColor(Color.BLUE);
184 | }
185 |
186 | // Assign new URL
187 | this.url = url;
188 | this.setCursor(new Cursor(Cursor.HAND_CURSOR));
189 | this.createMouseURLListener();
190 | this.addMouseListener(this.urlClickEvent);
191 | }
192 |
193 | /**
194 | * Removes the URL Event and reset some styles back
195 | *
196 | * @param defaultURLStyle - true remove default URL-Styles else it don't remove styles
197 | */
198 | private void removeURL(boolean defaultURLStyle) {
199 | this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
200 |
201 | // Remove Styles
202 | if(defaultURLStyle) {
203 | this.setUnderline(false);
204 | this.setTextColor(null);
205 | }
206 |
207 | if(this.urlClickEvent != null) {
208 | this.removeMouseListener(this.urlClickEvent);
209 | this.urlClickEvent = null;
210 | this.url = null;
211 | }
212 | }
213 |
214 | /**
215 | * Creates a MouseAdapter from the given URL
216 | */
217 | private void createMouseURLListener() {
218 | if(this.url == null)
219 | return;
220 |
221 | this.urlClickEvent = new MouseAdapter() {
222 | /**
223 | * {@inheritDoc}
224 | *
225 | * @param e
226 | */
227 | @Override
228 | public void mouseClicked(MouseEvent e) {
229 | try {
230 | Desktop.getDesktop().browse(new URI(url));
231 | } catch (URISyntaxException | IOException ex) {
232 | ex.printStackTrace();
233 | }
234 | }
235 | };
236 | }
237 |
238 | /**
239 | * Changes an Attribute of the Font
240 | *
241 | * @param attributeKey - Key of the Attribute
242 | * @param value - New Value of the Attribute
243 | */
244 | private void changeStyleAttribute(TextAttribute attributeKey, Object value) {
245 | MapJPanel
with a double buffer
16 | * and a box layout.
17 | */
18 | public JPanelLine() {
19 | this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
20 | this.setAlignmentX(Component.LEFT_ALIGNMENT);
21 | }
22 |
23 | /**
24 | * Adds a Label with 1 empty space
25 | */
26 | public void addSpaceLabel() {
27 | this.add(new JLabel(" "));
28 | }
29 |
30 | /**
31 | * Adds a Space-Dimension
32 | *
33 | * @param len - Length of the Dimension
34 | */
35 | public void addSpaceDimension(int len) {
36 | this.add(Box.createRigidArea(new Dimension(len, 0)));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/notification/ErrorWindow.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui.notification;
2 |
3 | /**
4 | * @author Peter Dragicevic
5 | */
6 | public class ErrorWindow extends NotificationWindow {
7 | /**
8 | * NotificationWindow Constructor
9 | *
10 | * @param message - Message for this Notification
11 | * @param errorLevel - Error-Level of this Notification
12 | * @param stopProgram - Stop Program when Displaying this
13 | */
14 | public ErrorWindow(String message, int errorLevel, boolean stopProgram) {
15 | super(message, null, errorLevel, stopProgram);
16 | }
17 |
18 | /**
19 | * NotificationWindow Constructor
20 | *
21 | * @param message - Message for this Notification
22 | * @param errorLevel - Error-Level of this Notification
23 | * @param stopProgram - Stop Program when Displaying this
24 | * @param e - Exception of this Notification
25 | */
26 | public ErrorWindow(String message, int errorLevel, boolean stopProgram, Exception e) {
27 | super(message, null, errorLevel, stopProgram, e);
28 | }
29 |
30 | /**
31 | * NotificationWindow Constructor
32 | *
33 | * @param message - Message for this Notification
34 | * @param title - Title for this Notification
35 | * @param errorLevel - Error-Level of this Notification
36 | * @param stopProgram - Stop Program when Displaying this
37 | * @param e - Exception of this Notification
38 | */
39 | public ErrorWindow(String message, String title, int errorLevel, boolean stopProgram, Exception e) {
40 | super(message, title, errorLevel, stopProgram, e);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/notification/InfoWindow.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui.notification;
2 |
3 | /**
4 | * @author Peter Dragicevic
5 | */
6 | public class InfoWindow extends NotificationWindow {
7 | /**
8 | * NotificationWindow Constructor
9 | *
10 | * @param message - Message for this Notification
11 | */
12 | public InfoWindow(String message) {
13 | super(message, null);
14 | }
15 |
16 | /**
17 | * NotificationWindow Constructor
18 | *
19 | * @param message - Message for this Notification
20 | * @param title - Title for this Notification
21 | */
22 | public InfoWindow(String message, String title) {
23 | super(message, title);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/gui/notification/NotificationWindow.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.gui.notification;
2 |
3 | import javax.swing.JOptionPane;
4 | import java.awt.Component;
5 | import java.io.PrintWriter;
6 | import java.io.StringWriter;
7 |
8 | /**
9 | * @author Peter Dragicevic
10 | */
11 | abstract class NotificationWindow {
12 | public static final int ERROR_LEVEL_FATAL = 4;
13 | public static final int ERROR_LEVEL_ERROR = 3;
14 | public static final int ERROR_LEVEL_WARNING = 2;
15 | public static final int ERROR_LEVEL_NOTICE = 1;
16 | public static final int ERROR_LEVEL_INFO = 0;
17 |
18 | private int errorLevel;
19 | private String title;
20 | private String message;
21 | private boolean stopProgram = false;
22 | private Exception e = null;
23 |
24 | /**
25 | * NotificationWindow Constructor
26 | *
27 | * @param message - Message for this Notification
28 | * @param title - Title for this Notification
29 | */
30 | NotificationWindow(String message, String title) {
31 | this.errorLevel = ERROR_LEVEL_INFO;
32 | this.setTitle(title);
33 | this.message = message;
34 | }
35 |
36 | /**
37 | * NotificationWindow Constructor
38 | *
39 | * @param message - Message for this Notification
40 | * @param title - Title for this Notification
41 | * @param errorLevel - Error-Level of this Notification
42 | */
43 | NotificationWindow(String message, String title, int errorLevel) {
44 | this.errorLevel = errorLevel;
45 | this.setTitle(title);
46 | this.message = message;
47 | }
48 |
49 | /**
50 | * NotificationWindow Constructor
51 | *
52 | * @param message - Message for this Notification
53 | * @param title - Title for this Notification
54 | * @param errorLevel - Error-Level of this Notification
55 | * @param stopProgram - Stop Program when Displaying this
56 | */
57 | NotificationWindow(String message, String title, int errorLevel, boolean stopProgram) {
58 | this.errorLevel = errorLevel;
59 | this.setTitle(title);
60 | this.message = message;
61 | this.stopProgram = stopProgram;
62 | }
63 |
64 | /**
65 | * NotificationWindow Constructor
66 | *
67 | * @param message - Message for this Notification
68 | * @param title - Title for this Notification
69 | * @param errorLevel - Error-Level of this Notification
70 | * @param stopProgram - Stop Program when Displaying this
71 | * @param e - Exception of this Notification
72 | */
73 | NotificationWindow(String message, String title, int errorLevel, boolean stopProgram, Exception e) {
74 | this.errorLevel = errorLevel;
75 | this.setTitle(title);
76 | this.message = message;
77 | this.stopProgram = stopProgram;
78 | this.e = e;
79 | }
80 |
81 | /**
82 | * Returns the Error-Level for this Notification
83 | *
84 | * @return - Error-Level for this Notification
85 | */
86 | public int getErrorLevel() {
87 | return errorLevel;
88 | }
89 |
90 | /**
91 | * Set the Error-Level for this Notification
92 | *
93 | * @param errorLevel - Error-Level for this Notification
94 | */
95 | protected void setErrorLevel(int errorLevel) {
96 | this.errorLevel = errorLevel;
97 | }
98 |
99 | /**
100 | * Returns the Title for this Notification
101 | *
102 | * @return - Title for this Notification
103 | */
104 | public String getTitle() {
105 | return title;
106 | }
107 |
108 | /**
109 | * Sets the Title for this Notification
110 | *
111 | * @param title - Title for this Notification
112 | */
113 | public void setTitle(String title) {
114 | if(title == null)
115 | this.setDefaultTitle();
116 | else
117 | this.title = title;
118 | }
119 |
120 | /**
121 | * Returns the Message that will shown
122 | *
123 | * @return - Notification Message
124 | */
125 | public String getMessage() {
126 | return message;
127 | }
128 |
129 | /**
130 | * Sets the Message for this Notification
131 | *
132 | * @param message - Message to display
133 | */
134 | public void setMessage(String message) {
135 | this.message = message;
136 | }
137 |
138 | /**
139 | * Returns if the Program will stop when showing this Dialog
140 | *
141 | * @return - true if the Program will stop on showing else false
142 | */
143 | public boolean isStopProgram() {
144 | return stopProgram;
145 | }
146 |
147 | /**
148 | * Set if the Program should stop if the Window is shown
149 | *
150 | * @param stopProgram - true if the Program should stop on showing else false
151 | */
152 | public void setStopProgram(boolean stopProgram) {
153 | this.stopProgram = stopProgram;
154 | }
155 |
156 | /**
157 | * Returns the Exception of the Dialog
158 | *
159 | * @return - Exception or null
160 | */
161 | public Exception getE() {
162 | return e;
163 | }
164 |
165 | /**
166 | * Sets the Exception for this Dialog
167 | *
168 | * @param e - Exception
169 | */
170 | public void setE(Exception e) {
171 | this.e = e;
172 | }
173 |
174 | /**
175 | * Sets the Title depending on the Error-Level
176 | */
177 | protected void setDefaultTitle() {
178 | switch(this.errorLevel) {
179 | case ERROR_LEVEL_NOTICE:
180 | this.title = "Notice";
181 | break;
182 | case ERROR_LEVEL_WARNING:
183 | this.title = "Warning";
184 | break;
185 | case ERROR_LEVEL_ERROR:
186 | this.title = "Error";
187 | break;
188 | case ERROR_LEVEL_FATAL:
189 | this.title = "Fatal-Error";
190 | break;
191 | case ERROR_LEVEL_INFO:
192 | default:
193 | this.title = "Info";
194 | }
195 | }
196 |
197 | /**
198 | * Returns the JOptionPane Type depending on the Error-Level
199 | *
200 | * @return - JOptionPane Type
201 | */
202 | protected int getJOptionType() {
203 | switch(this.errorLevel) {
204 | case ERROR_LEVEL_WARNING:
205 | return JOptionPane.WARNING_MESSAGE;
206 | case ERROR_LEVEL_ERROR:
207 | case ERROR_LEVEL_FATAL:
208 | return JOptionPane.ERROR_MESSAGE;
209 | case ERROR_LEVEL_NOTICE:
210 | case ERROR_LEVEL_INFO:
211 | default:
212 | return JOptionPane.INFORMATION_MESSAGE;
213 | }
214 | }
215 |
216 | /**
217 | * Returns the Message with Exception-Trace if there is an Exception set
218 | *
219 | * @return - Full-Message
220 | */
221 | protected String getFullMessage() {
222 | if(this.e != null) {
223 | StringWriter stringWriter = new StringWriter();
224 | this.e.printStackTrace(new PrintWriter(stringWriter));
225 |
226 | return this.message + " | Exception-Trace: " + stringWriter.toString();
227 | }
228 |
229 | return this.message;
230 | }
231 |
232 | /**
233 | * Shows this Notification-Window
234 | */
235 | public void show() {
236 | this.show(null);
237 | }
238 |
239 | /**
240 | * Shows this Notification-Window
241 | *
242 | * @param parentComponent - Parent Component or null for none
243 | */
244 | public void show(Component parentComponent) {
245 | JOptionPane.showConfirmDialog(parentComponent, this.getFullMessage(), this.getTitle(), JOptionPane.DEFAULT_OPTION, this.getJOptionType());
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/update/Update.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.update;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.net.MalformedURLException;
7 | import java.net.URL;
8 |
9 | /**
10 | * @author Peter Dragicevic
11 | */
12 | public class Update {
13 | private UpdateCache updateCache;
14 | private URL checkVersionUrl;
15 | private URL whatsNewUrl = null;
16 | private URL downloadURL = null;
17 | private Version currentVersion;
18 | private Version newestVersion = null;
19 | private boolean hasNewVersion = false;
20 | private boolean ignoreCache = false;
21 |
22 | /**
23 | * Update Constructor
24 | *
25 | * @param checkVersionUrl - URL to get the newest Version-Number
26 | * @param currentVersion - Current Version
27 | * @throws IOException - IO-Exception
28 | */
29 | public Update(String checkVersionUrl, String currentVersion) throws IOException {
30 | this.updateCache = new UpdateCache();
31 | this.checkVersionUrl = new URL(checkVersionUrl);
32 | this.currentVersion = new Version(currentVersion);
33 |
34 | this.init();
35 | }
36 |
37 | /**
38 | * Update Constructor
39 | *
40 | * @param checkVersionUrl - URL to get the newest Version-Number
41 | * @param currentVersion - Current Version
42 | * @param cacheTime - Cache-Time in Sec
43 | * @throws IOException - IO-Exception
44 | */
45 | public Update(String checkVersionUrl, String currentVersion, long cacheTime) throws IOException {
46 | this.updateCache = new UpdateCache(cacheTime);
47 | this.checkVersionUrl = new URL(checkVersionUrl);
48 | this.currentVersion = new Version(currentVersion);
49 |
50 | this.init();
51 | }
52 |
53 | /**
54 | * Update Constructor
55 | *
56 | * @param checkVersionUrl - URL to get the newest Version-Number
57 | * @param currentVersion - Current Version
58 | * @param ignoreCache - Should the Cache be ignored?
59 | * @throws IOException - IO-Exception
60 | */
61 | public Update(String checkVersionUrl, String currentVersion, boolean ignoreCache) throws IOException {
62 | this.updateCache = new UpdateCache();
63 | this.checkVersionUrl = new URL(checkVersionUrl);
64 | this.currentVersion = new Version(currentVersion);
65 | this.ignoreCache = ignoreCache;
66 |
67 | this.init();
68 | }
69 |
70 | /**
71 | * Gets the Whats-New URL
72 | *
73 | * @return - Whats-New URL
74 | */
75 | public URL getWhatsNewUrl() {
76 | return whatsNewUrl;
77 | }
78 |
79 | /**
80 | * Initiates this instance (may loads cache)
81 | */
82 | private void init() throws IOException {
83 | if(this.ignoreCache) {
84 | this.getUpdateInfo();
85 | } else {
86 | if(this.updateCache.loadCache()) {
87 | this.newestVersion = this.updateCache.newestVersionCache;
88 | this.downloadURL = this.updateCache.cachedDownloadUrl;
89 | this.whatsNewUrl = this.updateCache.cachedWhatsNewUrl;
90 | } else {
91 | this.getUpdateInfo();
92 | }
93 | }
94 |
95 | this.checkVersion();
96 | }
97 |
98 | /**
99 | * Get all information from the File for the Update process
100 | */
101 | private void getUpdateInfo() throws IOException {
102 | // Read the Update-URL
103 | InputStream content = this.checkVersionUrl.openStream();
104 |
105 |
106 | // Convert the read Content to Strings
107 | int c;
108 | int currentString = 0;
109 | StringBuilder version = new StringBuilder();
110 | StringBuilder downloadUrl = new StringBuilder();
111 | StringBuilder whatsNewUrl = new StringBuilder();
112 |
113 | while(true) {
114 | try {
115 | c = content.read();
116 |
117 | // Exit loop if file reaches end
118 | if(c == -1)
119 | break;
120 |
121 | if(c == (int) ';')
122 | currentString++;
123 | else {
124 | switch(currentString) {
125 | case 0:
126 | version.append((char) c);
127 | break;
128 | case 1:
129 | downloadUrl.append((char) c);
130 | break;
131 | case 2:
132 | whatsNewUrl.append((char) c);
133 | break;
134 | default:
135 | }
136 | }
137 | } catch(IOException e) {
138 | e.printStackTrace();
139 | break;
140 | }
141 | }
142 |
143 | this.newestVersion = new Version(version.toString().trim());
144 |
145 | try {
146 | this.downloadURL = new URL(downloadUrl.toString().trim());
147 | this.whatsNewUrl = new URL(whatsNewUrl.toString().trim());
148 | } catch(MalformedURLException e) {
149 | e.printStackTrace();
150 | }
151 |
152 | this.savesCache();
153 | }
154 |
155 | /**
156 | * Saves new Data to the Cache
157 | */
158 | private void savesCache() {
159 | this.updateCache.newestVersionCache = this.newestVersion;
160 | this.updateCache.cachedDownloadUrl = this.downloadURL;
161 | this.updateCache.cachedWhatsNewUrl = this.whatsNewUrl;
162 |
163 | this.updateCache.saveCache();
164 | }
165 |
166 | /**
167 | * Checks if the Version is the newest
168 | */
169 | private void checkVersion() {
170 | if(this.newestVersion == null)
171 | return;
172 |
173 | if(! this.currentVersion.versionsEqual(this.newestVersion))
174 | this.hasNewVersion = this.currentVersion.thisIsLowerThan(this.newestVersion);
175 | }
176 |
177 | /**
178 | * Shows if the current Version is the newest
179 | *
180 | * @return - Is newest Version
181 | */
182 | public boolean isHasNewVersion() {
183 | return this.hasNewVersion;
184 | }
185 |
186 | /**
187 | * Get the newest Version-Number
188 | *
189 | * @return - Newest Version-Number or null if could not read Update-URL
190 | */
191 | public String getNewestVersion() {
192 | return newestVersion.getVersion();
193 | }
194 |
195 | /**
196 | * Get the current Version
197 | *
198 | * @return - Current Version
199 | */
200 | public String getCurrentVersion() {
201 | return currentVersion.getVersion();
202 | }
203 |
204 | /**
205 | * Starts the updater but not relaunch after update
206 | *
207 | * @param targetJar - Target jar which should be updated
208 | * @param gui - Should the Updater show a GUI window
209 | */
210 | public void runUpdate(String targetJar, boolean gui) throws UpdateException {
211 | this.runUpdate(targetJar, gui, false, null);
212 | }
213 |
214 |
215 | /**
216 | * Starts the updater
217 | *
218 | * @param targetJar - Target jar which should be updated
219 | * @param gui - Should the Updater show a GUI window
220 | * @param relaunch - Relaunch this Program after Update
221 | * @param relaunchArgs - Args for relaunch, can be null if none
222 | */
223 | public void runUpdate(String targetJar, boolean gui, boolean relaunch, String[] relaunchArgs) throws UpdateException {
224 | File updaterFile = new File("update.jar");
225 | File targetJarFile = new File(targetJar);
226 |
227 | if(this.newestVersion == null)
228 | throw new UpdateException("Newest Version is not set!", this.currentVersion);
229 |
230 | if(this.newestVersion.versionsEqual(new Version("")))
231 | throw new UpdateException("Newest Version is empty...", this.currentVersion);
232 |
233 | if(this.newestVersion.versionsEqual(this.currentVersion))
234 | throw new UpdateException("This Program is already up to date!", this.currentVersion, this.newestVersion);
235 |
236 | if(! targetJarFile.exists() || targetJarFile.isDirectory())
237 | throw new UpdateException("Can not find the Target-Jar", this.currentVersion);
238 |
239 | if(! updaterFile.exists() || updaterFile.isDirectory())
240 | throw new UpdateException("Updater not found!", this.currentVersion);
241 |
242 | String[] run = {
243 | "java",
244 | "-jar",
245 | "update.jar",
246 | "\"" + targetJar + "\"",
247 | "\"" + this.downloadURL.toString() + "\"",
248 | gui ? "true" : "false",
249 | relaunch ? "true" : "false"
250 | };
251 |
252 | // Add args
253 | if(relaunchArgs != null) {
254 | String[] tmp = new String[run.length + relaunchArgs.length];
255 | int i;
256 | for(i = 0; i < run.length; i++)
257 | tmp[i] = run[i];
258 |
259 | int n = i;
260 | for(; i < tmp.length; i++)
261 | tmp[i] = relaunchArgs[i - n];
262 |
263 | run = tmp;
264 | }
265 |
266 | try {
267 | Runtime.getRuntime().exec(run);
268 | } catch (Exception e) {
269 | throw new UpdateException(e.getMessage(), this.currentVersion, e);
270 | }
271 | System.exit(0);
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/update/UpdateCache.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.update;
2 |
3 | import java.io.*;
4 | import java.net.MalformedURLException;
5 | import java.net.URL;
6 | import java.sql.Timestamp;
7 | import java.util.Properties;
8 |
9 | /**
10 | * @author Peter Dragicevic
11 | */
12 | class UpdateCache {
13 | private static final String PROP_NEWEST_VERSION_CACHE = "newestVersionCache";
14 | private static final String PROP_CACHED_DOWNLOAD_URL = "cachedDownloadUrl";
15 | private static final String PROP_WHATS_NEW_URL = "cachedWhatsNewUrl";
16 | private static final String PROP_LAST_CHECK = "lastCheck";
17 | private static final String FILE_PATH = "updateCache.pref";
18 |
19 | private File propertyFile = null;
20 | private Properties properties = null;
21 | private long currentTime;
22 | private long checkAgainAfterSec = 86400; // Default 1 Day
23 | private long lastCheck = 0;
24 | Version newestVersionCache = null;
25 | URL cachedDownloadUrl = null;
26 | URL cachedWhatsNewUrl = null;
27 |
28 | /**
29 | * UpdateCache constructor
30 | */
31 | UpdateCache() {
32 | this.setTime();
33 | }
34 |
35 | /**
36 | * UpdateCache constructor
37 | *
38 | * @param checkAgainAfterSec - Checks again after secs from last check, this overwrites default value
39 | */
40 | UpdateCache(long checkAgainAfterSec) {
41 | this.setTime();
42 | this.checkAgainAfterSec = checkAgainAfterSec;
43 | }
44 |
45 | /**
46 | * Sets current time
47 | */
48 | private void setTime() {
49 | Timestamp timestamp = new Timestamp(System.currentTimeMillis());
50 |
51 | this.currentTime = timestamp.getTime() / 1000;
52 | }
53 |
54 | /**
55 | * Loads the cache from a File
56 | *
57 | * @return - true if cache was loaded successfully else false if either not all data provided or need new check
58 | */
59 | boolean loadCache() {
60 | this.propertyFile = new File(FILE_PATH);
61 | if(! this.propertyFile.exists() || this.propertyFile.isDirectory()) {
62 | this.propertyFile = null;
63 | return false;
64 | }
65 |
66 | this.properties = new Properties();
67 | Reader reader;
68 | try {
69 | reader = new FileReader(this.propertyFile);
70 | this.properties.load(reader);
71 | } catch(Exception e) {
72 | return false;
73 | }
74 |
75 | // Set the values
76 | this.lastCheck = Long.parseLong(this.properties.getProperty(PROP_LAST_CHECK, "0"));
77 | String cachedVersion = this.properties.getProperty(PROP_NEWEST_VERSION_CACHE, "");
78 | this.newestVersionCache = cachedVersion.equals("") ? null : new Version(cachedVersion);
79 | try {
80 | this.cachedDownloadUrl = new URL(this.properties.getProperty(PROP_CACHED_DOWNLOAD_URL, ""));
81 | } catch(MalformedURLException e) {
82 | this.cachedDownloadUrl = null;
83 | }
84 | try {
85 | this.cachedWhatsNewUrl = new URL(this.properties.getProperty(PROP_WHATS_NEW_URL, ""));
86 | } catch(MalformedURLException e) {
87 | this.cachedWhatsNewUrl = null;
88 | }
89 |
90 | if(this.cacheToOld())
91 | return false;
92 |
93 | return this.newestVersionCache != null && this.cachedDownloadUrl != null && this.cachedWhatsNewUrl != null;
94 | }
95 |
96 | /**
97 | * Saves the cache to a File
98 | */
99 | void saveCache() {
100 | this.lastCheck = this.currentTime;
101 |
102 | if(this.propertyFile == null)
103 | this.propertyFile = new File(FILE_PATH);
104 |
105 | // Create missing file
106 | if(! this.propertyFile.exists()) {
107 | try {
108 | new FileWriter(this.propertyFile).close();
109 | } catch(IOException e) {
110 | e.printStackTrace();
111 |
112 | return;
113 | }
114 |
115 | if(! this.propertyFile.exists())
116 | return;
117 | }
118 |
119 | if(this.properties == null)
120 | this.properties = new Properties();
121 |
122 | // Set the new values
123 | this.properties.setProperty(PROP_LAST_CHECK, String.valueOf(this.lastCheck));
124 | this.properties.setProperty(PROP_NEWEST_VERSION_CACHE, this.newestVersionCache.getVersion());
125 | this.properties.setProperty(PROP_CACHED_DOWNLOAD_URL, this.cachedDownloadUrl.toString());
126 | this.properties.setProperty(PROP_WHATS_NEW_URL, this.cachedWhatsNewUrl.toString());
127 |
128 | try {
129 | FileWriter fileWriter = new FileWriter(FILE_PATH);
130 | this.properties.store(fileWriter, "Update Cache File");
131 | } catch(IOException e) {
132 | e.printStackTrace();
133 | }
134 | }
135 |
136 | /**
137 | * Shows if the cache is to old
138 | *
139 | * @return - Cache is to Old
140 | */
141 | private boolean cacheToOld() {
142 | return this.currentTime > this.lastCheck + this.checkAgainAfterSec;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/lib/update/UpdateException.java:
--------------------------------------------------------------------------------
1 | package org.petschko.lib.update;
2 |
3 | import java.security.PrivilegedActionException;
4 |
5 | /**
6 | * @author Peter Dragicevic
7 | */
8 | public class UpdateException extends Exception {
9 | private Version currentVersion;
10 | private Version newestVersion = null;
11 |
12 | /**
13 | * Constructs a new exception with {@code null} as its detail message.
14 | * The cause is not initialized, and may subsequently be initialized by a
15 | * call to {@link #initCause}.
16 | *
17 | * @param currentVersion - Current Version
18 | */
19 | public UpdateException(Version currentVersion) {
20 | super();
21 | this.setCurrentVersion(currentVersion);
22 | }
23 |
24 | /**
25 | * Constructs a new exception with {@code null} as its detail message.
26 | * The cause is not initialized, and may subsequently be initialized by a
27 | * call to {@link #initCause}.
28 | *
29 | * @param currentVersion - Current Version
30 | * @param newestVersion - Newest Version or null for none
31 | */
32 | public UpdateException(Version currentVersion, Version newestVersion) {
33 | super();
34 | this.setCurrentVersion(currentVersion);
35 | this.setNewestVersion(newestVersion);
36 | }
37 |
38 | /**
39 | * Constructs a new exception with the specified detail message. The
40 | * cause is not initialized, and may subsequently be initialized by
41 | * a call to {@link #initCause}.
42 | *
43 | * @param message the detail message. The detail message is saved for
44 | * later retrieval by the {@link #getMessage()} method.
45 | * @param currentVersion - Current Version
46 | */
47 | public UpdateException(String message, Version currentVersion) {
48 | super(message);
49 | this.setCurrentVersion(currentVersion);
50 | }
51 |
52 | /**
53 | * Constructs a new exception with the specified detail message. The
54 | * cause is not initialized, and may subsequently be initialized by
55 | * a call to {@link #initCause}.
56 | *
57 | * @param message the detail message. The detail message is saved for
58 | * later retrieval by the {@link #getMessage()} method.
59 | * @param currentVersion - Current Version
60 | * @param newestVersion - Newest Version or null for none
61 | */
62 | public UpdateException(String message, Version currentVersion, Version newestVersion) {
63 | super(message);
64 | this.setCurrentVersion(currentVersion);
65 | this.setNewestVersion(newestVersion);
66 | }
67 |
68 | /**
69 | * Constructs a new exception with the specified detail message and
70 | * cause. Frame
with the
28 | * specified title.
29 | * JComponent.getDefaultLocale
.
32 | *
33 | * @param title the title for the frame
34 | * @param relativeTo relative to which parent component
35 | * @throws HeadlessException if GraphicsEnvironment.isHeadless()
36 | * returns true.
37 | * @see GraphicsEnvironment#isHeadless
38 | * @see Component#setSize
39 | * @see Component#setVisible
40 | * @see JComponent#getDefaultLocale
41 | */
42 | About(String title, JFrame relativeTo) throws HeadlessException {
43 | super(title, relativeTo);
44 | }
45 |
46 | /**
47 | * Construct the Content of the About-Window
48 | */
49 | @Override
50 | protected void constructAbout() {
51 | int lineSpace = 4;
52 |
53 | // Initial Comps - Panels
54 | JPanel borderFrame = new JPanel();
55 | JPanel descriptionContainer = new JPanel();
56 | JPanel logoPanel = new JPanel();
57 | JPanel okButton = new JPanel();
58 |
59 | // Initial Comps - Labels
60 | JPanelLine versionLine = new JPanelLine();
61 | JLabelExtra versionHeading = new JLabelExtra("Version:");
62 | JLabel version = new JLabel(Config.VERSION);
63 |
64 | JPanelLine licenceLine = new JPanelLine();
65 | JLabelExtra licenceHeading = new JLabelExtra("Licence:");
66 | JLabelExtra licence = new JLabelExtra("MIT-Licence");
67 | licence.setURL(Config.PROJECT_LICENCE_URL, true);
68 |
69 | JPanelLine projectLine = new JPanelLine();
70 | JLabelExtra projectHpHeading = new JLabelExtra("Project-HP:");
71 | JLabelExtra projectHp = new JLabelExtra("Visit the Project-Page on GitLab");
72 | projectHp.setURL(Config.PROJECT_PAGE_URL, true);
73 |
74 | JPanelLine creditLine = new JPanelLine();
75 | JLabelExtra creditHeading = new JLabelExtra("Credits:");
76 | JPanelLine creatorLine = new JPanelLine();
77 | JLabel programmedBy = new JLabel(Const.CREATOR + " (Programmer) - ");
78 | JLabelExtra programmedByURL = new JLabelExtra("Website");
79 | programmedByURL.setURL(Const.CREATOR_URL, true);
80 | JLabelExtra programmedByDonate = new JLabelExtra("Donate");
81 | programmedByDonate.setURL(Const.CREATOR_DONATION_URL, true);
82 |
83 | // Set Layouts
84 | borderFrame.setLayout(new BorderLayout());
85 | descriptionContainer.setLayout(new BoxLayout(descriptionContainer, BoxLayout.Y_AXIS));
86 |
87 | // Style
88 | versionHeading.setUnderline(true);
89 | licenceHeading.setUnderline(true);
90 | projectHpHeading.setUnderline(true);
91 | creditHeading.setUnderline(true);
92 | borderFrame.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
93 | descriptionContainer.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0));
94 |
95 | // Add stuff
96 | logoPanel.add(this.imagePanel);
97 | okButton.add(this.closeButton);
98 |
99 | versionLine.add(versionHeading);
100 | versionLine.addSpaceDimension(10);
101 | versionLine.add(version);
102 | licenceLine.add(licenceHeading);
103 | licenceLine.addSpaceDimension(10);
104 | licenceLine.add(licence);
105 | projectLine.add(projectHpHeading);
106 | projectLine.addSpaceDimension(10);
107 | projectLine.add(projectHp);
108 | creditLine.add(creditHeading);
109 | creatorLine.add(programmedBy);
110 | creatorLine.add(programmedByURL);
111 | creatorLine.add(new JLabel(" | "));
112 | creatorLine.add(programmedByDonate);
113 |
114 | descriptionContainer.add(versionLine);
115 | descriptionContainer.add(Box.createRigidArea(new Dimension(0, lineSpace)));
116 | descriptionContainer.add(licenceLine);
117 | descriptionContainer.add(Box.createRigidArea(new Dimension(0, lineSpace)));
118 | descriptionContainer.add(projectLine);
119 | descriptionContainer.add(Box.createRigidArea(new Dimension(0, lineSpace)));
120 | descriptionContainer.add(creditLine);
121 | descriptionContainer.add(creatorLine);
122 |
123 | borderFrame.add(logoPanel, BorderLayout.NORTH);
124 | borderFrame.add(descriptionContainer, BorderLayout.CENTER);
125 | borderFrame.add(okButton, BorderLayout.SOUTH);
126 |
127 | this.add(borderFrame);
128 | this.setResizable(false);
129 | this.pack();
130 | }
131 |
132 | /**
133 | * Returns the text of the Close-Button
134 | *
135 | * @return - Button-Text
136 | */
137 | @Override
138 | protected String closeButtonText() {
139 | return "Ok";
140 | }
141 |
142 | /**
143 | * Creates the About-Icon
144 | *
145 | * @return - JImageLabel or null if not set
146 | */
147 | @Override
148 | protected JImageLabel aboutIcon() {
149 | JImageLabel imagePanel = new JImageLabel(Config.AUTHOR_IMAGE, true);
150 |
151 | // Ensure this size
152 | imagePanel.setImageSize(200, 200);
153 |
154 | return imagePanel;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/gui/ActionListener.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt.gui;
2 |
3 | import org.petschko.lib.File;
4 | import org.petschko.lib.Functions;
5 | import org.petschko.lib.gui.JDirectoryChooser;
6 | import org.petschko.lib.gui.notification.ErrorWindow;
7 | import org.petschko.lib.gui.notification.InfoWindow;
8 | import org.petschko.rpgmakermv.decrypt.App;
9 | import org.petschko.rpgmakermv.decrypt.Preferences;
10 |
11 | import javax.swing.JFileChooser;
12 | import javax.swing.JOptionPane;
13 | import javax.swing.UIManager;
14 | import javax.swing.filechooser.FileNameExtensionFilter;
15 | import java.awt.Desktop;
16 | import java.awt.event.WindowAdapter;
17 | import java.awt.event.WindowEvent;
18 |
19 | /**
20 | * @author Peter Dragicevic
21 | */
22 | class ActionListener {
23 |
24 | /**
25 | * Close via Menu ActionListener
26 | *
27 | * @return - Close ActionListener
28 | */
29 | static java.awt.event.ActionListener closeMenu() {
30 | return e -> App.closeGUI();
31 | }
32 |
33 | /**
34 | * Close-Action
35 | *
36 | * @return - Close WindowAdapter
37 | */
38 | static WindowAdapter closeButton() {
39 | return new WindowAdapter() {
40 | @Override
41 | public void windowClosing(WindowEvent e) {
42 | App.closeGUI();
43 | }
44 | };
45 | }
46 |
47 | /**
48 | * Switches a Config-Value with the given name
49 | *
50 | * @param configName - Config-Name
51 | * @return - Switch-Setting ActionListener
52 | */
53 | static java.awt.event.ActionListener switchSetting(String configName) {
54 | if(configName == null) {
55 | Exception e = new Exception("configName can't be null!");
56 | e.printStackTrace();
57 | }
58 |
59 | return e -> App.preferences.switchBoolConfig(configName);
60 | }
61 |
62 | /**
63 | * Open-Website ActionListener
64 | *
65 | * @param url - Target URL
66 | * @return - Open-Website ActionListener
67 | */
68 | static java.awt.event.ActionListener openWebsite(String url) {
69 | return e -> Functions.openWebsite(url);
70 | }
71 |
72 | /**
73 | * Open an Explorer with the given Path
74 | *
75 | * @param directoryPath - Path to open
76 | * @return Open-Explorer ActionListener
77 | */
78 | static java.awt.event.ActionListener openExplorer(String directoryPath) {
79 | return e -> {
80 | Desktop desktop = Desktop.getDesktop();
81 | String path = File.ensureDSonEndOfPath(directoryPath);
82 |
83 | if(path == null) {
84 | ErrorWindow errorWindow = new ErrorWindow(
85 | "File-Explorer can't be opened due to: Directory can't be null!",
86 | ErrorWindow.ERROR_LEVEL_ERROR,
87 | false
88 | );
89 |
90 | errorWindow.show();
91 | return;
92 | }
93 |
94 | try {
95 | desktop.open(new java.io.File(path).getAbsoluteFile());
96 | } catch(Exception ex) {
97 | ex.printStackTrace();
98 | ErrorWindow errorWindow = new ErrorWindow(
99 | "Unable to open the File-Explorer with the Directory: " + directoryPath,
100 | ErrorWindow.ERROR_LEVEL_ERROR,
101 | false
102 | );
103 |
104 | errorWindow.show();
105 | }
106 | };
107 | }
108 |
109 | /**
110 | * Opens the File-Dialog and selects the RPG-Maker MV/MZ Project directory
111 | *
112 | * @param gui - Main GUI Object
113 | * @return - Select RPG-Maker Project-Dir ActionListener
114 | */
115 | static java.awt.event.ActionListener selectRPGMDir(GUI gui) {
116 | return e -> {
117 | String openDir = App.preferences.getConfig(Preferences.LAST_RPG_DIR, ".");
118 |
119 | if(! File.existsDir(openDir))
120 | openDir = ".";
121 |
122 | UIManager.put("FileChooser.readOnly", Boolean.TRUE);
123 | JDirectoryChooser dirChooser = new JDirectoryChooser(openDir);
124 | int choose = dirChooser.showDialog(gui.getMainWindow(), null);
125 |
126 | if(dirChooser.getSelectedFile() != null && choose == JDirectoryChooser.APPROVE_OPTION) {
127 | App.preferences.setConfig(Preferences.LAST_RPG_DIR, dirChooser.getCurrentDirectory().getPath());
128 |
129 | gui.openRPGProject(dirChooser.getSelectedFile().getPath(), true);
130 | }
131 | };
132 | }
133 |
134 | /**
135 | * Changes the Output dir with a Directory Chooser
136 | *
137 | * @param gui - Main GUI Object
138 | * @return - Change output dir ActionListener
139 | */
140 | static java.awt.event.ActionListener changeOutputDirectory(GUI gui) {
141 | return e -> {
142 | // Warn the user that the selected directory will be cleared
143 | if(Boolean.parseBoolean(App.preferences.getConfig(Preferences.CLEAR_OUTPUT_DIR_BEFORE_DECRYPT, "true")))
144 | new InfoWindow("You have chosen, that the selected Directory will be cleared.\nBeware that this Program clear the selected Directory (Deletes all Files within)! Don't select directories where you have important Files or Sub-Directories in!\n\n(Or turn off the clearing under Options)", "Important Info about your Files").show(gui.getMainWindow());
145 |
146 | String openDir = App.preferences.getConfig(Preferences.LAST_OUTPUT_PARENT_DIR, ".");
147 |
148 | if(! File.existsDir(openDir))
149 | openDir = ".";
150 |
151 | UIManager.put("FileChooser.readOnly", Boolean.TRUE);
152 | JDirectoryChooser dirChooser = new JDirectoryChooser(openDir);
153 | int choose = dirChooser.showDialog(gui.getMainMenu(), null);
154 |
155 | if(dirChooser.getSelectedFile() != null && choose == JDirectoryChooser.APPROVE_OPTION) {
156 | App.preferences.setConfig(Preferences.LAST_OUTPUT_PARENT_DIR, dirChooser.getCurrentDirectory().getPath());
157 | App.preferences.setConfig(Preferences.LAST_OUTPUT_DIR, dirChooser.getSelectedFile().getPath());
158 | gui.setNewOutputDir(dirChooser.getSelectedFile().getPath());
159 | gui.getMainMenu().doClearOutputDir.setEnabled(true);
160 | }
161 | };
162 | }
163 |
164 | /**
165 | * Changes the current output directory path to the executable directory path
166 | *
167 | * @param gui - Main GUI Object
168 | * @return - Change output dir to current dir ActionListener
169 | */
170 | static java.awt.event.ActionListener changeOutputDirToCurrentDir(GUI gui) {
171 | return e -> {
172 | // Warn the user that the selected directory will be cleared
173 | if(Boolean.parseBoolean(App.preferences.getConfig(Preferences.CLEAR_OUTPUT_DIR_BEFORE_DECRYPT, "true")))
174 | new InfoWindow("You have chosen, that the selected Directory will be cleared.\nBeware that this Program clear the selected Directory (Deletes all Files within)! Don't select directories where you have important Files or Sub-Directories in!\n\n(Or turn off the clearing under Options)", "Important Info about your Files").show(gui.getMainWindow());
175 |
176 | int answer = JOptionPane.showOptionDialog(
177 | gui.getMainWindow(),
178 | "Do you really want to change the output directory to the Directory of this Program?",
179 | "Change Directory",
180 | JOptionPane.YES_NO_OPTION,
181 | JOptionPane.QUESTION_MESSAGE,
182 | null,
183 | null,
184 | 1
185 | );
186 |
187 | if(answer == 1)
188 | return;
189 |
190 | final String newDir = ".";
191 |
192 | App.preferences.setConfig(Preferences.LAST_OUTPUT_PARENT_DIR, newDir);
193 | App.preferences.setConfig(Preferences.LAST_OUTPUT_DIR, newDir);
194 | gui.setNewOutputDir(newDir);
195 | gui.getMainMenu().doClearOutputDir.setEnabled(false);
196 | };
197 | }
198 |
199 | /**
200 | * Opens a File-Chooser and detects the Key from an Encrypted Image
201 | *
202 | * @param gui - Main GUI Object
203 | * @return - File-Chooser and detection from Image
204 | */
205 | static java.awt.event.ActionListener detectKeyFromImage(GUI gui) {
206 | return e -> {
207 | String openDir = gui.getRpgProject().getPath();
208 |
209 | if(! File.existsDir(openDir))
210 | openDir = ".";
211 |
212 | // Add settings to File-Chooser
213 | UIManager.put("FileChooser.readOnly", Boolean.TRUE);
214 | FileNameExtensionFilter filter = new FileNameExtensionFilter("Encrypted RPG Pictures", "rpgmvp", "png_");
215 | JFileChooser fileChooser = new JFileChooser(openDir);
216 | fileChooser.setFileFilter(filter);
217 |
218 | int choose = fileChooser.showDialog(gui.getMainWindow(), null);
219 |
220 | if(fileChooser.getSelectedFile() != null && choose == JFileChooser.APPROVE_OPTION) {
221 | File file;
222 | try {
223 | file = new File(fileChooser.getSelectedFile().getPath());
224 | } catch (Exception ex) {
225 | ErrorWindow errorWindow = new ErrorWindow(
226 | "Could not load the selected File...",
227 | ErrorWindow.ERROR_LEVEL_ERROR,
228 | false,
229 | ex
230 | );
231 | errorWindow.show(gui.getMainWindow());
232 |
233 | return;
234 | }
235 |
236 | try {
237 | gui.getDecrypter().detectEncryptionKeyFromImage(file);
238 | } catch (Exception ex) {
239 | ErrorWindow errorWindow = new ErrorWindow(
240 | "Could not find the Key from the selected File...",
241 | ErrorWindow.ERROR_LEVEL_ERROR,
242 | false,
243 | ex
244 | );
245 | errorWindow.show(gui.getMainWindow());
246 | return;
247 | }
248 |
249 | // If found update the values and show it to the user
250 | gui.setExtractedKey();
251 | }
252 | };
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/gui/FileInfo.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt.gui;
2 |
3 | import org.petschko.lib.File;
4 |
5 | import javax.swing.BorderFactory;
6 | import javax.swing.JPanel;
7 | import javax.swing.JTextField;
8 |
9 | /**
10 | * @author Peter Dragicevic
11 | */
12 | class FileInfo extends JPanel {
13 | private File file = null;
14 | private JTextField filePath = new JTextField();
15 | private JTextField fileExt = new JTextField();
16 | private JPanel realExt = new JPanel();
17 | private JTextField realFileExt = new JTextField();
18 |
19 |
20 | /**
21 | * FileInfo Constructor
22 | */
23 | FileInfo() {
24 | this.setBorder(BorderFactory.createTitledBorder("File-Info"));
25 | // todo add comps together
26 | }
27 |
28 | void setFile(File file) {
29 | this.file = file;
30 | this.loadFileData();
31 | }
32 |
33 | private void loadFileData() {
34 | //todo load and set this element
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/gui/GUI.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt.gui;
2 |
3 | import org.petschko.lib.Const;
4 | import org.petschko.lib.File;
5 | import org.petschko.lib.Functions;
6 | import org.petschko.lib.exceptions.PathException;
7 | import org.petschko.lib.gui.*;
8 | import org.petschko.lib.gui.notification.ErrorWindow;
9 | import org.petschko.lib.gui.notification.InfoWindow;
10 | import org.petschko.rpgmakermv.decrypt.*;
11 |
12 | import javax.swing.*;
13 | import javax.swing.JOptionPane;
14 | import java.awt.BorderLayout;
15 | import java.awt.Color;
16 | import java.awt.Dimension;
17 | import java.awt.GridLayout;
18 | import java.util.ArrayList;
19 |
20 | /**
21 | * @author Peter Dragicevic
22 | */
23 | public class GUI {
24 | private JFrame mainWindow;
25 | private Menu mainMenu;
26 | private JPanel windowPanel = new JPanel(new BorderLayout());
27 | JPanel projectFilesPanel = new JPanel();
28 | JListJPanel
with a double buffer
40 | * and a flow layout.
41 | */
42 | ProjectInfo() {
43 | this.setBorder(BorderFactory.createTitledBorder("Project-Info"));
44 | this.setLayout(new GridLayout(2, 1));
45 |
46 | mainInfo.setBorder(BorderFactory.createEmptyBorder(5,7, 5, 7));
47 | keyInfo.setBorder(BorderFactory.createEmptyBorder(5,7, 5, 7));
48 |
49 | this.add(mainInfo);
50 | this.add(keyInfo);
51 | }
52 |
53 | /**
54 | *Sets the Encrypted Files count
55 | *
56 | * @param encryptedFilesCount - Encrypted Files count
57 | */
58 | void setEncryptedFilesCount(int encryptedFilesCount) {
59 | this.encryptedFilesCount = encryptedFilesCount;
60 | }
61 |
62 | /**
63 | * Sets the Resource Files count
64 | *
65 | * @param resourceFilesCount - Resource Files count
66 | */
67 | void setResourceFilesCount(int resourceFilesCount) {
68 | this.resourceFilesCount = resourceFilesCount;
69 | }
70 |
71 | /**
72 | * Sets if it has the Project-File
73 | *
74 | * @param hasProjectFile - has it the Project-File
75 | */
76 | void setHasProjectFile(boolean hasProjectFile) {
77 | this.hasProjectFile = hasProjectFile;
78 | }
79 |
80 | /**
81 | * Sets if it has the System.json
82 | *
83 | * @param hasSystemFile - has it the System.json
84 | */
85 | void setHasSystemFile(boolean hasSystemFile) {
86 | this.hasSystemFile = hasSystemFile;
87 | }
88 |
89 | /**
90 | * Sets the Encryption-Key
91 | *
92 | * @param encryptionKey - Encryption-Key
93 | */
94 | void setEncryptionKey(String encryptionKey) {
95 | this.encryptionKey = encryptionKey;
96 | }
97 |
98 | /**
99 | * Sets the Header-Len
100 | *
101 | * @param headerLen - Header-Len
102 | */
103 | public void setHeaderLen(int headerLen) {
104 | this.headerLen = headerLen;
105 | }
106 |
107 | /**
108 | * Sets the Header-Signature
109 | *
110 | * @param signature - Header-Signature
111 | */
112 | void setSignature(String signature) {
113 | this.signature = signature;
114 | }
115 |
116 | /**
117 | * Sets the Header-Version
118 | *
119 | * @param version - Header-Version
120 | */
121 | void setVersion(String version) {
122 | this.version = version;
123 | }
124 |
125 | /**
126 | * Sets the Header-Remain
127 | *
128 | * @param remain - Header-Remain
129 | */
130 | void setRemain(String remain) {
131 | this.remain = remain;
132 | }
133 |
134 | /**
135 | * Sets the Values from a RPG-Project
136 | *
137 | * @param rpgProject - RPG-Project
138 | */
139 | void setValuesFromRPGProject(RPG_Project rpgProject) {
140 | if(rpgProject == null)
141 | return;
142 |
143 | this.encryptedFilesCount = rpgProject.getEncryptedFiles().size();
144 | this.resourceFilesCount = rpgProject.getResourceFiles().size();
145 | this.hasProjectFile = rpgProject.getProjectFile() != null;
146 | this.hasSystemFile = rpgProject.getSystem() != null;
147 | }
148 |
149 | /**
150 | * Sets the Values from the Decrypter
151 | *
152 | * @param decrypter - Decrypter
153 | */
154 | void setValuesFromDecrypter(Decrypter decrypter) {
155 | if(decrypter == null)
156 | return;
157 |
158 | this.encryptionKey = decrypter.getDecryptCode();
159 | this.headerLen = decrypter.getHeaderLen();
160 | this.signature = decrypter.getSignature();
161 | this.version = decrypter.getVersion();
162 | this.remain = decrypter.getRemain();
163 | }
164 |
165 | /**
166 | * Removes all internal Layouts
167 | */
168 | private void removeAllLayouts() {
169 | mainInfo.removeAll();
170 | keyInfo.removeAll();
171 | encryptedFiles.removeAll();
172 | resourceFiles.removeAll();
173 | projectFile.removeAll();
174 | systemFile.removeAll();
175 | jEncryptionKey.removeAll();
176 | jHeaderLen.removeAll();
177 | jSignature.removeAll();
178 | jVersion.removeAll();
179 | jRemain.removeAll();
180 | }
181 |
182 | /**
183 | * Creates the No-Project Layout
184 | */
185 | private void noProjectLayout() {
186 | removeAllLayouts();
187 |
188 | JLabel jLabel = new JLabel("No Project");
189 | jLabel.setForeground(Color.GRAY);
190 | mainInfo.add(jLabel);
191 | }
192 |
193 | /**
194 | * Builds the content with all Info-Values
195 | */
196 | private void buildContent() {
197 | removeAllLayouts();
198 | this.keyInfo.setLayout(new BoxLayout(this.keyInfo, BoxLayout.Y_AXIS));
199 |
200 | this.encryptedFiles.add(new JLabel("Encrypted Files:"));
201 | JLabel encryptedFilesCountLabel = new JLabel(String.valueOf(this.encryptedFilesCount));
202 | if(this.encryptedFilesCount == 0)
203 | encryptedFilesCountLabel.setForeground(Color.RED);
204 | this.encryptedFiles.add(encryptedFilesCountLabel);
205 |
206 | this.resourceFiles.add(new JLabel("Resource-Files:"));
207 | JLabel resourceFilesCountLabel = new JLabel(String.valueOf(this.resourceFilesCount));
208 | if(this.resourceFilesCount == 0)
209 | resourceFilesCountLabel.setForeground(Color.RED);
210 | this.resourceFiles.add(resourceFilesCountLabel);
211 |
212 | this.systemFile.add(new JLabel("System.json:"));
213 | JLabel hasSystemJsonLabel = new JLabel(this.hasSystemFile ? "Found" : "Not Found");
214 | hasSystemJsonLabel.setForeground(this.hasSystemFile ? new Color(6, 125, 23) : Color.RED);
215 | this.systemFile.add(hasSystemJsonLabel);
216 |
217 | this.projectFile.add(new JLabel("Project-File:"));
218 | JLabel hasProjectFile = new JLabel(this.hasProjectFile ? "Found" : "Not Found");
219 | hasProjectFile.setForeground(this.hasProjectFile ? new Color(6, 125, 23) : Color.RED);
220 | this.projectFile.add(hasProjectFile);
221 |
222 | this.jEncryptionKey.add(new JLabel("Key: "));
223 | JLabel keyLabel = new JLabel(this.encryptionKey == null ? "Not Found!" : this.encryptionKey);
224 | if(this.encryptionKey == null)
225 | keyLabel.setForeground(Color.RED);
226 | this.jEncryptionKey.add(keyLabel);
227 |
228 | this.jHeaderLen.add(new JLabel("Header-Length: "));
229 | JLabel headerLabel = new JLabel(String.valueOf(this.headerLen));
230 | if(this.headerLen != Decrypter.DEFAULT_HEADER_LEN && this.headerLen != 0) {
231 | headerLabel.setForeground(Color.BLUE);
232 | headerLabel.setText(headerLabel.getText() + " (Custom)");
233 | }
234 | if(this.headerLen == 0)
235 | headerLabel.setForeground(Color.RED);
236 | this.jHeaderLen.add(headerLabel);
237 |
238 | this.jSignature.add(new JLabel("Signature: "));
239 | JLabel signatureLabel = new JLabel(this.signature == null ? "-" : this.signature);
240 | if(this.signature == null)
241 | signatureLabel.setForeground(Color.RED);
242 | else if(! this.signature.equals(Decrypter.DEFAULT_SIGNATURE)) {
243 | signatureLabel.setForeground(Color.BLUE);
244 | signatureLabel.setText(signatureLabel.getText() + " (Custom)");
245 | }
246 | this.jSignature.add(signatureLabel);
247 |
248 | this.jVersion.add(new JLabel("Version: "));
249 | JLabel versionLabel = new JLabel(this.version == null ? "-" : this.version);
250 | if(this.version == null)
251 | versionLabel.setForeground(Color.RED);
252 | else if(! this.version.equals(Decrypter.DEFAULT_VERSION)) {
253 | versionLabel.setForeground(Color.BLUE);
254 | versionLabel.setText(versionLabel.getText() + " (Custom)");
255 | }
256 | this.jVersion.add(versionLabel);
257 |
258 | this.jRemain.add(new JLabel("Remain: "));
259 | JLabel remainLabel = new JLabel(this.remain == null ? "-" : this.remain);
260 | if(this.remain == null)
261 | remainLabel.setForeground(Color.RED);
262 | else if(! this.remain.equals(Decrypter.DEFAULT_REMAIN)) {
263 | remainLabel.setForeground(Color.BLUE);
264 | remainLabel.setText(remainLabel.getText() + " (Custom)");
265 | }
266 | this.jRemain.add(remainLabel);
267 |
268 | this.mainInfo.add(this.encryptedFiles);
269 | this.mainInfo.add(this.resourceFiles);
270 | this.mainInfo.add(this.systemFile);
271 | this.mainInfo.add(this.projectFile);
272 | this.mainInfo.validate();
273 |
274 | this.keyInfo.add(this.jEncryptionKey);
275 | this.keyInfo.add(this.jHeaderLen);
276 | this.keyInfo.add(this.jSignature);
277 | this.keyInfo.add(this.jVersion);
278 | this.keyInfo.add(this.jRemain);
279 | this.keyInfo.validate();
280 | }
281 |
282 | /**
283 | * Refreshes the Layout & Shown Values
284 | */
285 | void refresh() {
286 | buildContent();
287 | validate();
288 | }
289 |
290 | /**
291 | * Resets the Layout to No-Project
292 | */
293 | void reset() {
294 | encryptedFilesCount = 0;
295 | resourceFilesCount = 0;
296 | hasProjectFile = false;
297 | hasSystemFile = false;
298 | encryptionKey = null;
299 | headerLen = 0;
300 | signature = null;
301 | version = null;
302 | remain = null;
303 |
304 | noProjectLayout();
305 | validate();
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/gui/Update.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt.gui;
2 |
3 | import org.petschko.lib.Const;
4 | import org.petschko.lib.gui.JOptionPane;
5 | import org.petschko.lib.gui.notification.ErrorWindow;
6 | import org.petschko.lib.gui.notification.InfoWindow;
7 | import org.petschko.lib.update.UpdateException;
8 | import org.petschko.rpgmakermv.decrypt.App;
9 | import org.petschko.rpgmakermv.decrypt.Config;
10 | import org.petschko.rpgmakermv.decrypt.Preferences;
11 |
12 | import java.awt.*;
13 | import java.io.IOException;
14 | import java.net.URI;
15 | import java.net.URISyntaxException;
16 |
17 | /**
18 | * @author Peter Dragicevic
19 | */
20 | class Update {
21 | private GUI gui;
22 | private org.petschko.lib.update.Update update = null;
23 | private String[] options;
24 | private boolean autoOptionExists = false;
25 | private boolean ranAutomatically = false;
26 |
27 | /**
28 | * Update constructor
29 | *
30 | * @param gui - Main GUI-Object
31 | */
32 | Update(GUI gui) {
33 | this.gui = gui;
34 | this.options = new String[] {"Update", "Show whats new", "Cancel"};
35 |
36 | this.init();
37 | }
38 |
39 | /**
40 | * Update constructor
41 | *
42 | * @param gui - Main GUI-Object
43 | * @param auto - This ran automatically
44 | */
45 | Update(GUI gui, boolean auto) {
46 | this.gui = gui;
47 | this.options = new String[] {"Update", "Show whats new", "Disable update check", "Cancel"};
48 | this.autoOptionExists = true;
49 | this.ranAutomatically = auto;
50 |
51 | this.init();
52 | }
53 |
54 | /**
55 | * Inits the Object
56 | */
57 | private void init() {
58 | try {
59 | if(this.ranAutomatically)
60 | update = new org.petschko.lib.update.Update(Config.UPDATE_URL, Config.VERSION_NUMBER, Config.UPDATE_CHECK_EVERY_SECS);
61 | else
62 | update = new org.petschko.lib.update.Update(Config.UPDATE_URL, Config.VERSION_NUMBER, true);
63 | } catch (IOException e) {
64 | if(! this.ranAutomatically) {
65 | ErrorWindow ew = new ErrorWindow("Can't check for Updates...", ErrorWindow.ERROR_LEVEL_WARNING, false);
66 | ew.show(this.gui.getMainWindow());
67 | }
68 | }
69 |
70 | this.checkIfUpdate();
71 | }
72 |
73 | /**
74 | * Checks if an update exists
75 | */
76 | private void checkIfUpdate() {
77 | if(update != null) {
78 | if(update.isHasNewVersion()) {
79 | // Ask the user what to do
80 | int response = JOptionPane.showOptionDialog(
81 | this.gui.getMainWindow(),
82 | "Update found!" + Const.NEW_LINE +
83 | "Your Version: " + Config.VERSION_NUMBER + Const.NEW_LINE +
84 | "New Version: " + update.getNewestVersion() + Const.NEW_LINE + Const.NEW_LINE +
85 | "What do you want to do?",
86 | "Update found",
87 | JOptionPane.DEFAULT_OPTION,
88 | JOptionPane.QUESTION_MESSAGE,
89 | null,
90 | this.options,
91 | this.options[0]
92 | );
93 |
94 | if(response == 0)
95 | this.runUpdate();
96 | else if(response == 1)
97 | this.showWhatsNew();
98 | else if(this.autoOptionExists && response == 2) {
99 | App.preferences.switchBoolConfig(Preferences.AUTO_CHECK_FOR_UPDATES);
100 | gui.getMainMenu().checkForUpdates.setState(false);
101 | }
102 | } else if(! this.ranAutomatically) {
103 | InfoWindow infoWindow = new InfoWindow("You're using the newest Version!", "No update found");
104 | infoWindow.show(this.gui.getMainWindow());
105 | }
106 | }
107 | }
108 |
109 | /**
110 | * Runs the update
111 | */
112 | private void runUpdate() {
113 | try {
114 | update.runUpdate(Config.THIS_JAR_FILE_NAME, true, true, null);
115 | } catch(UpdateException e) {
116 | ErrorWindow errorWindow = new ErrorWindow("Update Failed!", ErrorWindow.ERROR_LEVEL_ERROR, false, e);
117 | errorWindow.show(this.gui.getMainWindow());
118 |
119 | e.printStackTrace();
120 | }
121 | }
122 |
123 | /**
124 | * Brings the user to the whats new url
125 | */
126 | private void showWhatsNew() {
127 | if(Desktop.isDesktopSupported()) {
128 | Desktop desktop = Desktop.getDesktop();
129 |
130 | if(desktop.isSupported(Desktop.Action.BROWSE)) {
131 | try {
132 | URI uri = new URI(update.getWhatsNewUrl().toString());
133 | desktop.browse(uri);
134 | } catch(IOException | URISyntaxException e) {
135 | ErrorWindow errorWindow = new ErrorWindow("Can't open \"What's new...\"", ErrorWindow.ERROR_LEVEL_ERROR, false, e);
136 | errorWindow.show(this.gui.getMainWindow());
137 |
138 | e.printStackTrace();
139 | }
140 | }
141 | } else {
142 | ErrorWindow errorWindow = new ErrorWindow("Can't open \"What's new...\"..." + Const.NEW_LINE + "This operation isnt supported by your OS!", ErrorWindow.ERROR_LEVEL_ERROR, false);
143 | errorWindow.show(this.gui.getMainWindow());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/java/org/petschko/rpgmakermv/decrypt/gui/WorkerDecryption.java:
--------------------------------------------------------------------------------
1 | package org.petschko.rpgmakermv.decrypt.gui;
2 |
3 | import org.petschko.lib.File;
4 | import org.petschko.lib.Functions;
5 | import org.petschko.lib.gui.notification.InfoWindow;
6 | import org.petschko.rpgmakermv.decrypt.App;
7 | import org.petschko.rpgmakermv.decrypt.Preferences;
8 |
9 | import javax.swing.ProgressMonitor;
10 | import java.awt.event.ActionEvent;
11 | import java.awt.event.ActionListener;
12 | import java.util.ArrayList;
13 |
14 | /**
15 | * @author Peter Dragicevic
16 | */
17 | class WorkerDecryption extends WorkerEncryption implements ActionListener {
18 | private boolean restoreImages = false;
19 |
20 | /**
21 | * WorkerDecryption constructor
22 | *
23 | * @param gui - GUI-Object
24 | * @param files - Files to Decrypt
25 | */
26 | WorkerDecryption(GUI gui, ArrayList