Skip to content
This repository was archived by the owner on Sep 26, 2023. It is now read-only.

Commit bcd551e

Browse files
authored
Merge pull request #25 from Petschko/dev
Added support for Keyless-Image restoring
2 parents 5a7e801 + 8f997f0 commit bcd551e

File tree

7 files changed

+142
-54
lines changed

7 files changed

+142
-54
lines changed

src/org/petschko/lib/File.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ private void setExtension(@Nullable String extension) {
8686
if(extension != null) {
8787
if (extension.equals(""))
8888
extension = null;
89+
else
90+
extension = extension.toLowerCase();
8991
}
9092

9193
this.extension = extension;
@@ -514,4 +516,68 @@ public static boolean createDirectory(@NotNull String directoryPath) {
514516
public static boolean clearDirectory(@NotNull String directoryPath) {
515517
return File.deleteDirectoryOperation(directoryPath, true, false);
516518
}
519+
520+
/**
521+
* Returns the real Extension of the current fake extension
522+
*
523+
* @return - Real File-Extension
524+
*/
525+
public String realExtByFakeExt() {
526+
switch(this.extension) {
527+
case "rpgmvp":
528+
case "png_":
529+
return "png";
530+
case "rpgmvm":
531+
case "m4a_":
532+
return "m4a";
533+
case "rpgmvo":
534+
case "ogg_":
535+
return "ogg";
536+
default:
537+
return "unknown";
538+
}
539+
}
540+
541+
/**
542+
* Shows if this file is an Image
543+
*
544+
* @return - true if the file is an image
545+
*/
546+
public boolean isImage() {
547+
switch(this.extension) {
548+
case "rpgmvp":
549+
case "png_":
550+
case "jpg":
551+
case "jpeg":
552+
case "png":
553+
case "gif":
554+
case "bmp":
555+
case "ico":
556+
return true;
557+
default:
558+
return false;
559+
}
560+
}
561+
562+
/**
563+
* Check if the given Extension is an Encrypted Extension
564+
*
565+
* @return - true if the Extension is an encrypted File-extension else false
566+
*/
567+
public boolean isFileEncryptedExt() {
568+
if(this.extension == null)
569+
return false;
570+
571+
switch(this.extension) {
572+
case "rpgmvp":
573+
case "rpgmvm":
574+
case "rpgmvo":
575+
case "png_":
576+
case "m4a_":
577+
case "ogg_":
578+
return true;
579+
default:
580+
return false;
581+
}
582+
}
517583
}

src/org/petschko/rpgmakermv/decrypt/Config.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
class Config {
1414
// Program Info
15-
static final String versionNumber = "0.1.4.0";
15+
static final String versionNumber = "0.1.5.0";
1616
static final String version = "v" + versionNumber + " Alpha";
1717
static final String programName = "RPG-Maker MV Decrypter";
1818
static final String projectPageURL = "https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter";

src/org/petschko/rpgmakermv/decrypt/Decrypter.java

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Notes: Decrypter class
2121
*/
2222
class Decrypter {
23+
static final String pngHeader = "89504E470D0A1A0A0000000D49484452";
24+
static byte[] pngHeaderBytes = null;
25+
2326
static final int defaultHeaderLen = 16;
2427
static final String defaultSignature = "5250474d56000000";
2528
static final String defaultVersion = "000301";
@@ -205,6 +208,20 @@ private void calcRealDecryptionCode() throws NullPointerException {
205208
* @throws Exception - Various Exceptions
206209
*/
207210
void decryptFile(File file) throws Exception {
211+
decryptFile(file, false);
212+
}
213+
214+
/**
215+
* Decrypts the File (Header) and removes the Encryption-Header
216+
*
217+
* @param file - Encrypted File
218+
* @param restorePictures - Restore Pictures without the Key
219+
* @throws Exception - Various Exceptions
220+
*/
221+
void decryptFile(File file, boolean restorePictures) throws Exception {
222+
if(restorePictures && (! file.isImage() || ! file.isFileEncryptedExt()))
223+
return;
224+
208225
try {
209226
if(! file.load())
210227
throw new FileSystemException(file.getFilePath(), "", "Can't load File-Content...");
@@ -215,7 +232,7 @@ void decryptFile(File file) throws Exception {
215232
}
216233

217234
// Check if all required external stuff is here
218-
if(this.getDecryptCode() == null)
235+
if(this.getDecryptCode() == null && ! restorePictures)
219236
throw new NullPointerException("Decryption-Code is not set!");
220237
if(file.getContent() == null)
221238
throw new NullPointerException("File-Content is not loaded!");
@@ -233,16 +250,19 @@ void decryptFile(File file) throws Exception {
233250
// Remove Fake-Header from rest
234251
content = Decrypter.getByteArray(content, this.getHeaderLen());
235252

236-
// Decrypt Real-Header & First part of the Content
253+
237254
if(content.length > 0) {
238255
for(int i = 0; i < this.getHeaderLen(); i++) {
239-
content[i] = (byte) (content[i] ^ (byte) Integer.parseInt(this.getRealDecryptCode()[i], 16));
256+
if(restorePictures) // Restore Pictures
257+
content[i] = getPNGHeaderByteArray()[i];
258+
else // Decrypt Real-Header & First part of the Content
259+
content[i] = (byte) (content[i] ^ (byte) Integer.parseInt(this.getRealDecryptCode()[i], 16));
240260
}
241261
}
242262

243263
// Update File-Content
244264
file.setContent(content);
245-
file.changeExtension(Decrypter.realExtByFakeExt(file.getExtension()));
265+
file.changeExtension(file.realExtByFakeExt());
246266
}
247267

248268
/**
@@ -309,6 +329,26 @@ void detectEncryptionKey(File file, String keyName) throws JSONException, NullPo
309329
this.setDecryptCode(key);
310330
}
311331

332+
/**
333+
* Returns the PNG-Header Byte Array
334+
*
335+
* @return PNG-Header Byte Array
336+
*/
337+
private byte[] getPNGHeaderByteArray() {
338+
if(pngHeaderBytes != null)
339+
return pngHeaderBytes;
340+
341+
String[] pngHeaderArr = pngHeader.split("(?<=\\G.{2})");
342+
byte[] pngHeaderBytesArray = new byte[this.getHeaderLen()];
343+
344+
for(int i = 0; i < this.getHeaderLen(); i++) {
345+
pngHeaderBytesArray[i] = (byte) Integer.parseInt(pngHeaderArr[i], 16);
346+
}
347+
pngHeaderBytes = pngHeaderBytesArray;
348+
349+
return pngHeaderBytes;
350+
}
351+
312352
/**
313353
* Get a new Byte-Array with given start pos and length
314354
*
@@ -351,26 +391,4 @@ private static byte[] getByteArray(byte[] byteArray, int startPos, int length) {
351391
private static byte[] getByteArray(byte[] byteArray, int startPos) {
352392
return getByteArray(byteArray, startPos, -1);
353393
}
354-
355-
/**
356-
* Returns the real Extension of the current fake extension
357-
*
358-
* @param fakeExt - Fake Extension where you want to get the real Extension
359-
* @return - Real File-Extension
360-
*/
361-
private static String realExtByFakeExt(@NotNull String fakeExt) {
362-
switch(fakeExt.toLowerCase()) {
363-
case "rpgmvp":
364-
case "png_":
365-
return "png";
366-
case "rpgmvm":
367-
case "m4a_":
368-
return "m4a";
369-
case "rpgmvo":
370-
case "ogg_":
371-
return "ogg";
372-
default:
373-
return "unknown";
374-
}
375-
}
376394
}

src/org/petschko/rpgmakermv/decrypt/Finder.java

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,6 @@ static File findSystemFile(@Nullable String projectDir) {
5555
return null;
5656
}
5757

58-
/**
59-
* Check if the given Extension is an Encrypted Extension
60-
*
61-
* @param extension - File-Extension to check
62-
* @return - true if the Extension is an encrypted File-extension else false
63-
*/
64-
static boolean isFileEncryptedExt(@Nullable String extension) {
65-
if(extension == null)
66-
extension = "";
67-
68-
switch(extension.toLowerCase()) {
69-
case "rpgmvp":
70-
case "rpgmvm":
71-
case "rpgmvo":
72-
case "png_":
73-
case "m4a_":
74-
case "ogg_":
75-
return true;
76-
default:
77-
return false;
78-
}
79-
}
80-
8158
/**
8259
* Check if Encryption-Key name is may different from given - Tests all know Encryption-Key Names
8360
*

src/org/petschko/rpgmakermv/decrypt/GUI.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ private void assignRPGActionListener() {
214214
this.mainMenu.openRPGDirExplorer.addActionListener(GUI_ActionListener.openExplorer(this.rpgProject.getPath()));
215215
//this.mainMenu.allFiles.addActionListener(this.decrypt(this.rpgProject.getEncryptedFiles()));
216216
this.mainMenu.allFiles.addActionListener(new GUI_Decryption(this.rpgProject.getEncryptedFiles()));
217+
this.mainMenu.restoreImages.addActionListener(new GUI_Decryption(this.rpgProject.getEncryptedFiles(), true));
217218
}
218219

219220
/**
@@ -250,6 +251,7 @@ private void setNewOutputDir(String newOutputDir) {
250251
private class GUI_Decryption extends SwingWorker<Void, Void> implements ActionListener {
251252
private ArrayList<File> files;
252253
private ProgressMonitor progressMonitor;
254+
private boolean restoreImages = false;
253255

254256
/**
255257
* GUI_Decryption constructor
@@ -260,6 +262,17 @@ private class GUI_Decryption extends SwingWorker<Void, Void> implements ActionLi
260262
this.files = files;
261263
}
262264

265+
/**
266+
* GUI_Decryption constructor
267+
*
268+
* @param files - Files to Decrypt
269+
* @param restoreImages - Restores Images without key
270+
*/
271+
GUI_Decryption(ArrayList<File> files, boolean restoreImages) {
272+
this.files = files;
273+
this.restoreImages = restoreImages;
274+
}
275+
263276
/**
264277
* Computes a result, or throws an exception if unable to do so.
265278
*
@@ -361,11 +374,12 @@ protected Void doInBackground() throws Exception {
361374
this.progressMonitor.setNote("File: " + file.getFilePath());
362375
try {
363376
System.out.println("Decrypt: " + file.getFilePath());
364-
decrypter.decryptFile(file);
377+
decrypter.decryptFile(file, this.restoreImages);
365378
} catch(Exception e1) {
366379
e1.printStackTrace();
367380
} finally {
368-
rpgProject.saveFile(file, Functions.strToBool(App.preferences.getConfig(Preferences.overwriteFiles, "false")));
381+
if(! this.restoreImages || file.isImage())
382+
rpgProject.saveFile(file, Functions.strToBool(App.preferences.getConfig(Preferences.overwriteFiles, "false")));
369383
}
370384
// Add Progress to Progress-Monitor
371385
i++;
@@ -402,7 +416,12 @@ protected void done() {
402416
} else {
403417
System.out.println("Done.");
404418

405-
InfoWindow infoWindow = new InfoWindow("Decryption complete! =)");
419+
InfoWindow infoWindow;
420+
if(this.restoreImages)
421+
infoWindow = new InfoWindow("Images are restored! ^-^");
422+
else
423+
infoWindow = new InfoWindow("Decryption complete! =)");
424+
406425
infoWindow.show(mainWindow);
407426
}
408427
}

src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class GUI_Menu extends JMenuBar {
3939
// Decrypt-Menu-Sub
4040
JMenuItem selectedFiles;
4141
JMenuItem allFiles;
42+
JMenuItem restoreImages;
4243
JMenuItem setEncryptionKey;
4344
JMenuItem setEncryptionFile;
4445
JMenuItem changeDecrypterSignature;
@@ -49,6 +50,7 @@ class GUI_Menu extends JMenuBar {
4950

5051
// Info-Menu-Sub
5152
JMenuItem help;
53+
JMenuItem updateProgram;
5254
JMenuItem reportABug;
5355
JMenuItem about;
5456

@@ -102,6 +104,7 @@ private void constructDecryptMenu() {
102104
// Sub-Items
103105
this.selectedFiles = new JMenuItem("Selected Files");
104106
this.allFiles = new JMenuItem("All Files");
107+
this.restoreImages = new JMenuItem("Restore Images (No Key)");
105108
this.setEncryptionKey = new JMenuItem("Set Encryption-Key...");
106109
this.setEncryptionFile = new JMenuItem("Select Encryption-File...");
107110
this.changeDecrypterSignature = new JMenuItem("Change Decrypter Signature...");
@@ -124,6 +127,7 @@ private void constructInfoMenu() {
124127
this.info = new JMenu("Info");
125128

126129
this.help = new JMenuItem("Help");
130+
this.updateProgram = new JMenuItem("Check for Updates");
127131
this.reportABug = new JMenuItem("Report a Bug...");
128132
this.about = new JMenuItem("About");
129133
}
@@ -151,6 +155,7 @@ private void addAllMenus() {
151155
this.add(this.decrypt);
152156
this.decrypt.add(this.selectedFiles);
153157
this.decrypt.add(this.allFiles);
158+
this.decrypt.add(this.restoreImages);
154159
this.decrypt.addSeparator();
155160
this.decrypt.add(this.setEncryptionKey);
156161
this.decrypt.add(this.setEncryptionFile);
@@ -162,6 +167,7 @@ private void addAllMenus() {
162167

163168
this.add(this.info);
164169
this.info.add(this.help);
170+
this.info.add(this.updateProgram);
165171
this.info.add(this.reportABug);
166172
this.info.addSeparator();
167173
this.info.add(this.about);
@@ -176,6 +182,7 @@ void enableOnRPGProject(boolean enable) {
176182
this.openRPGDirExplorer.setEnabled(enable);
177183
//this.selectedFiles.setEnabled(enable);
178184
this.allFiles.setEnabled(enable);
185+
this.restoreImages.setEnabled(enable);
179186
//this.setEncryptionKey.setEnabled(enable);
180187
//this.setEncryptionFile.setEnabled(enable);
181188
//this.restoreProject.setEnabled(enable);
@@ -191,5 +198,6 @@ private void disableUnimplemented() {
191198
this.changeDecrypterSignature.setEnabled(false);
192199
this.restoreProject.setEnabled(false);
193200
this.help.setEnabled(false);
201+
this.updateProgram.setEnabled(false);
194202
}
195203
}

src/org/petschko/rpgmakermv/decrypt/RPGProject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ private void findEncryptedFiles() {
219219
return;
220220

221221
for(File file : this.getFiles()) {
222-
if(Finder.isFileEncryptedExt(file.getExtension()))
222+
if(file.isFileEncryptedExt())
223223
this.getEncryptedFiles().add(file);
224224
}
225225
}

0 commit comments

Comments
 (0)