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

Commit

Permalink
Merge pull request #25 from Petschko/dev
Browse files Browse the repository at this point in the history
Added support for Keyless-Image restoring
  • Loading branch information
Petschko authored Feb 14, 2021
2 parents 5a7e801 + 8f997f0 commit bcd551e
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 54 deletions.
66 changes: 66 additions & 0 deletions src/org/petschko/lib/File.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ private void setExtension(@Nullable String extension) {
if(extension != null) {
if (extension.equals(""))
extension = null;
else
extension = extension.toLowerCase();
}

this.extension = extension;
Expand Down Expand Up @@ -514,4 +516,68 @@ public static boolean createDirectory(@NotNull String directoryPath) {
public static boolean clearDirectory(@NotNull String directoryPath) {
return File.deleteDirectoryOperation(directoryPath, true, false);
}

/**
* Returns the real Extension of the current fake extension
*
* @return - Real File-Extension
*/
public String realExtByFakeExt() {
switch(this.extension) {
case "rpgmvp":
case "png_":
return "png";
case "rpgmvm":
case "m4a_":
return "m4a";
case "rpgmvo":
case "ogg_":
return "ogg";
default:
return "unknown";
}
}

/**
* Shows if this file is an Image
*
* @return - true if the file is an image
*/
public boolean isImage() {
switch(this.extension) {
case "rpgmvp":
case "png_":
case "jpg":
case "jpeg":
case "png":
case "gif":
case "bmp":
case "ico":
return true;
default:
return false;
}
}

/**
* Check if the given Extension is an Encrypted Extension
*
* @return - true if the Extension is an encrypted File-extension else false
*/
public boolean isFileEncryptedExt() {
if(this.extension == null)
return false;

switch(this.extension) {
case "rpgmvp":
case "rpgmvm":
case "rpgmvo":
case "png_":
case "m4a_":
case "ogg_":
return true;
default:
return false;
}
}
}
2 changes: 1 addition & 1 deletion src/org/petschko/rpgmakermv/decrypt/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
class Config {
// Program Info
static final String versionNumber = "0.1.4.0";
static final String versionNumber = "0.1.5.0";
static final String version = "v" + versionNumber + " Alpha";
static final String programName = "RPG-Maker MV Decrypter";
static final String projectPageURL = "https://github.com/Petschko/Java-RPG-Maker-MV-Decrypter";
Expand Down
70 changes: 44 additions & 26 deletions src/org/petschko/rpgmakermv/decrypt/Decrypter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
* Notes: Decrypter class
*/
class Decrypter {
static final String pngHeader = "89504E470D0A1A0A0000000D49484452";
static byte[] pngHeaderBytes = null;

static final int defaultHeaderLen = 16;
static final String defaultSignature = "5250474d56000000";
static final String defaultVersion = "000301";
Expand Down Expand Up @@ -205,6 +208,20 @@ private void calcRealDecryptionCode() throws NullPointerException {
* @throws Exception - Various Exceptions
*/
void decryptFile(File file) throws Exception {
decryptFile(file, false);
}

/**
* Decrypts the File (Header) and removes the Encryption-Header
*
* @param file - Encrypted File
* @param restorePictures - Restore Pictures without the Key
* @throws Exception - Various Exceptions
*/
void decryptFile(File file, boolean restorePictures) throws Exception {
if(restorePictures && (! file.isImage() || ! file.isFileEncryptedExt()))
return;

try {
if(! file.load())
throw new FileSystemException(file.getFilePath(), "", "Can't load File-Content...");
Expand All @@ -215,7 +232,7 @@ void decryptFile(File file) throws Exception {
}

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

// Decrypt Real-Header & First part of the Content

if(content.length > 0) {
for(int i = 0; i < this.getHeaderLen(); i++) {
content[i] = (byte) (content[i] ^ (byte) Integer.parseInt(this.getRealDecryptCode()[i], 16));
if(restorePictures) // Restore Pictures
content[i] = getPNGHeaderByteArray()[i];
else // Decrypt Real-Header & First part of the Content
content[i] = (byte) (content[i] ^ (byte) Integer.parseInt(this.getRealDecryptCode()[i], 16));
}
}

// Update File-Content
file.setContent(content);
file.changeExtension(Decrypter.realExtByFakeExt(file.getExtension()));
file.changeExtension(file.realExtByFakeExt());
}

/**
Expand Down Expand Up @@ -309,6 +329,26 @@ void detectEncryptionKey(File file, String keyName) throws JSONException, NullPo
this.setDecryptCode(key);
}

/**
* Returns the PNG-Header Byte Array
*
* @return PNG-Header Byte Array
*/
private byte[] getPNGHeaderByteArray() {
if(pngHeaderBytes != null)
return pngHeaderBytes;

String[] pngHeaderArr = pngHeader.split("(?<=\\G.{2})");
byte[] pngHeaderBytesArray = new byte[this.getHeaderLen()];

for(int i = 0; i < this.getHeaderLen(); i++) {
pngHeaderBytesArray[i] = (byte) Integer.parseInt(pngHeaderArr[i], 16);
}
pngHeaderBytes = pngHeaderBytesArray;

return pngHeaderBytes;
}

/**
* Get a new Byte-Array with given start pos and length
*
Expand Down Expand Up @@ -351,26 +391,4 @@ private static byte[] getByteArray(byte[] byteArray, int startPos, int length) {
private static byte[] getByteArray(byte[] byteArray, int startPos) {
return getByteArray(byteArray, startPos, -1);
}

/**
* Returns the real Extension of the current fake extension
*
* @param fakeExt - Fake Extension where you want to get the real Extension
* @return - Real File-Extension
*/
private static String realExtByFakeExt(@NotNull String fakeExt) {
switch(fakeExt.toLowerCase()) {
case "rpgmvp":
case "png_":
return "png";
case "rpgmvm":
case "m4a_":
return "m4a";
case "rpgmvo":
case "ogg_":
return "ogg";
default:
return "unknown";
}
}
}
23 changes: 0 additions & 23 deletions src/org/petschko/rpgmakermv/decrypt/Finder.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,6 @@ static File findSystemFile(@Nullable String projectDir) {
return null;
}

/**
* Check if the given Extension is an Encrypted Extension
*
* @param extension - File-Extension to check
* @return - true if the Extension is an encrypted File-extension else false
*/
static boolean isFileEncryptedExt(@Nullable String extension) {
if(extension == null)
extension = "";

switch(extension.toLowerCase()) {
case "rpgmvp":
case "rpgmvm":
case "rpgmvo":
case "png_":
case "m4a_":
case "ogg_":
return true;
default:
return false;
}
}

/**
* Check if Encryption-Key name is may different from given - Tests all know Encryption-Key Names
*
Expand Down
25 changes: 22 additions & 3 deletions src/org/petschko/rpgmakermv/decrypt/GUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ private void assignRPGActionListener() {
this.mainMenu.openRPGDirExplorer.addActionListener(GUI_ActionListener.openExplorer(this.rpgProject.getPath()));
//this.mainMenu.allFiles.addActionListener(this.decrypt(this.rpgProject.getEncryptedFiles()));
this.mainMenu.allFiles.addActionListener(new GUI_Decryption(this.rpgProject.getEncryptedFiles()));
this.mainMenu.restoreImages.addActionListener(new GUI_Decryption(this.rpgProject.getEncryptedFiles(), true));
}

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

/**
* GUI_Decryption constructor
Expand All @@ -260,6 +262,17 @@ private class GUI_Decryption extends SwingWorker<Void, Void> implements ActionLi
this.files = files;
}

/**
* GUI_Decryption constructor
*
* @param files - Files to Decrypt
* @param restoreImages - Restores Images without key
*/
GUI_Decryption(ArrayList<File> files, boolean restoreImages) {
this.files = files;
this.restoreImages = restoreImages;
}

/**
* Computes a result, or throws an exception if unable to do so.
*
Expand Down Expand Up @@ -361,11 +374,12 @@ protected Void doInBackground() throws Exception {
this.progressMonitor.setNote("File: " + file.getFilePath());
try {
System.out.println("Decrypt: " + file.getFilePath());
decrypter.decryptFile(file);
decrypter.decryptFile(file, this.restoreImages);
} catch(Exception e1) {
e1.printStackTrace();
} finally {
rpgProject.saveFile(file, Functions.strToBool(App.preferences.getConfig(Preferences.overwriteFiles, "false")));
if(! this.restoreImages || file.isImage())
rpgProject.saveFile(file, Functions.strToBool(App.preferences.getConfig(Preferences.overwriteFiles, "false")));
}
// Add Progress to Progress-Monitor
i++;
Expand Down Expand Up @@ -402,7 +416,12 @@ protected void done() {
} else {
System.out.println("Done.");

InfoWindow infoWindow = new InfoWindow("Decryption complete! =)");
InfoWindow infoWindow;
if(this.restoreImages)
infoWindow = new InfoWindow("Images are restored! ^-^");
else
infoWindow = new InfoWindow("Decryption complete! =)");

infoWindow.show(mainWindow);
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/org/petschko/rpgmakermv/decrypt/GUI_Menu.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class GUI_Menu extends JMenuBar {
// Decrypt-Menu-Sub
JMenuItem selectedFiles;
JMenuItem allFiles;
JMenuItem restoreImages;
JMenuItem setEncryptionKey;
JMenuItem setEncryptionFile;
JMenuItem changeDecrypterSignature;
Expand All @@ -49,6 +50,7 @@ class GUI_Menu extends JMenuBar {

// Info-Menu-Sub
JMenuItem help;
JMenuItem updateProgram;
JMenuItem reportABug;
JMenuItem about;

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

this.help = new JMenuItem("Help");
this.updateProgram = new JMenuItem("Check for Updates");
this.reportABug = new JMenuItem("Report a Bug...");
this.about = new JMenuItem("About");
}
Expand Down Expand Up @@ -151,6 +155,7 @@ private void addAllMenus() {
this.add(this.decrypt);
this.decrypt.add(this.selectedFiles);
this.decrypt.add(this.allFiles);
this.decrypt.add(this.restoreImages);
this.decrypt.addSeparator();
this.decrypt.add(this.setEncryptionKey);
this.decrypt.add(this.setEncryptionFile);
Expand All @@ -162,6 +167,7 @@ private void addAllMenus() {

this.add(this.info);
this.info.add(this.help);
this.info.add(this.updateProgram);
this.info.add(this.reportABug);
this.info.addSeparator();
this.info.add(this.about);
Expand All @@ -176,6 +182,7 @@ void enableOnRPGProject(boolean enable) {
this.openRPGDirExplorer.setEnabled(enable);
//this.selectedFiles.setEnabled(enable);
this.allFiles.setEnabled(enable);
this.restoreImages.setEnabled(enable);
//this.setEncryptionKey.setEnabled(enable);
//this.setEncryptionFile.setEnabled(enable);
//this.restoreProject.setEnabled(enable);
Expand All @@ -191,5 +198,6 @@ private void disableUnimplemented() {
this.changeDecrypterSignature.setEnabled(false);
this.restoreProject.setEnabled(false);
this.help.setEnabled(false);
this.updateProgram.setEnabled(false);
}
}
2 changes: 1 addition & 1 deletion src/org/petschko/rpgmakermv/decrypt/RPGProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ private void findEncryptedFiles() {
return;

for(File file : this.getFiles()) {
if(Finder.isFileEncryptedExt(file.getExtension()))
if(file.isFileEncryptedExt())
this.getEncryptedFiles().add(file);
}
}
Expand Down

0 comments on commit bcd551e

Please sign in to comment.