diff --git a/app/src/main/cpp/xdelta3.c b/app/src/main/cpp/xdelta3.c
index a02e5f5..86842ea 100644
--- a/app/src/main/cpp/xdelta3.c
+++ b/app/src/main/cpp/xdelta3.c
@@ -30,7 +30,7 @@ along with UniPatcher. If not, see .
#include "xdelta3/xdelta3/xdelta3.h"
#include "xdelta3/xdelta3/xdelta3.c"
-int apply(FILE *patch, FILE *in, FILE *out);
+int apply(FILE *patch, FILE *in, FILE *out, int ignoreChecksum);
const int ERR_UNABLE_OPEN_PATCH = -5001;
const int ERR_UNABLE_OPEN_ROM = -5002;
@@ -41,7 +41,8 @@ int Java_org_emunix_unipatcher_patcher_XDelta_xdelta3apply(JNIEnv *env,
jobject this,
jstring patchPath,
jstring romPath,
- jstring outputPath) {
+ jstring outputPath,
+ jboolean ignoreChecksum) {
int ret = 0;
const char *patchName = (*env)->GetStringUTFChars(env, patchPath, NULL);
const char *romName = (*env)->GetStringUTFChars(env, romPath, NULL);
@@ -70,7 +71,7 @@ int Java_org_emunix_unipatcher_patcher_XDelta_xdelta3apply(JNIEnv *env,
return ERR_UNABLE_OPEN_OUTPUT;
}
- ret = apply(patchFile, romFile, outputFile);
+ ret = apply(patchFile, romFile, outputFile, (int)ignoreChecksum);
fclose(patchFile);
fclose(romFile);
@@ -78,7 +79,7 @@ int Java_org_emunix_unipatcher_patcher_XDelta_xdelta3apply(JNIEnv *env,
return ret;
}
-int apply(FILE *patch, FILE *in, FILE *out) {
+int apply(FILE *patch, FILE *in, FILE *out, int ignoreChecksum) {
int BUFFER_SIZE = 32768;
int r, ret;
@@ -93,6 +94,9 @@ int apply(FILE *patch, FILE *in, FILE *out) {
xd3_init_config(&config, 0);
config.winsize = BUFFER_SIZE;
+ if (ignoreChecksum) {
+ config.flags |= XD3_ADLER32_NOVER;
+ }
xd3_config_stream(&stream, &config);
source.blksize = BUFFER_SIZE;
diff --git a/app/src/main/java/org/emunix/unipatcher/Settings.java b/app/src/main/java/org/emunix/unipatcher/Settings.java
index f1b98b0..c71d277 100644
--- a/app/src/main/java/org/emunix/unipatcher/Settings.java
+++ b/app/src/main/java/org/emunix/unipatcher/Settings.java
@@ -69,4 +69,9 @@ public class Settings {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getString("output_directory", "");
}
+
+ public static boolean getIgnoreChecksum(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ return prefs.getBoolean("ignore_checksum", false);
+ }
}
diff --git a/app/src/main/java/org/emunix/unipatcher/WorkerService.java b/app/src/main/java/org/emunix/unipatcher/WorkerService.java
index 5cb7459..dcc2dff 100644
--- a/app/src/main/java/org/emunix/unipatcher/WorkerService.java
+++ b/app/src/main/java/org/emunix/unipatcher/WorkerService.java
@@ -158,7 +158,7 @@ public class WorkerService extends IntentService {
try {
if ("ppf".equals(ext))
Utils.copyFile(this, romFile, outputFile);
- patcher.apply();
+ patcher.apply(Settings.getIgnoreChecksum(this));
} catch (PatchException | IOException e) {
if (Utils.getFreeSpace(outputFile.getParentFile()) == 0) {
errorMsg = getString(R.string.notify_error_not_enough_space);
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/APS.java b/app/src/main/java/org/emunix/unipatcher/patcher/APS.java
index 5c2f9be..8fdc7e5 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/APS.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/APS.java
@@ -43,7 +43,7 @@ public class APS extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
Patcher aps = null;
switch (checkAPS(patchFile)) {
case APS_N64_PATCH:
@@ -56,7 +56,7 @@ public class APS extends Patcher {
throw new PatchException(context.getString(R.string.notify_error_not_aps_patch));
}
- aps.apply();
+ aps.apply(ignoreChecksum);
}
public int checkAPS(File file) throws PatchException, IOException {
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/APS_GBA.java b/app/src/main/java/org/emunix/unipatcher/patcher/APS_GBA.java
index 1fd36cf..60f4412 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/APS_GBA.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/APS_GBA.java
@@ -77,7 +77,7 @@ public class APS_GBA extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
long fileSize1, fileSize2, bytesLeft, offset;
int crc, patchCrc1, patchCrc2, pCount, oCount;
boolean isOriginal = false;
@@ -138,7 +138,8 @@ public class APS_GBA extends Patcher {
} else if (crc == patchCrc2) {
isModified = true;
} else {
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum)
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
}
if (isOriginal && isModified)
throw new PatchException(context.getString(R.string.notify_error_not_aps_patch));
@@ -153,7 +154,7 @@ public class APS_GBA extends Patcher {
if (isOriginal) {
Utils.truncateFile(outputFile, fileSize2);
- } else {
+ } else if (isModified) {
Utils.truncateFile(outputFile, fileSize1);
}
}
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/APS_N64.java b/app/src/main/java/org/emunix/unipatcher/patcher/APS_N64.java
index 2faa42a..694b712 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/APS_N64.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/APS_N64.java
@@ -47,7 +47,7 @@ public class APS_N64 extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
BufferedInputStream romStream = null;
BufferedInputStream patchStream = null;
BufferedOutputStream outputStream = null;
@@ -96,8 +96,10 @@ public class APS_N64 extends Patcher {
int country = patchStream.read();
byte[] crc = new byte[8];
patchStream.read(crc);
- if (!validateROM(endianness, cardID, country, crc))
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ if (!validateROM(endianness, cardID, country, crc))
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
// skip bytes for future expansion
byte[] skip = new byte[5];
patchStream.read(skip);
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/BPS.java b/app/src/main/java/org/emunix/unipatcher/patcher/BPS.java
index 46719ff..922226a 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/BPS.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/BPS.java
@@ -50,7 +50,7 @@ public class BPS extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
if (patchFile.length() < 19) {
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
@@ -68,9 +68,11 @@ public class BPS extends Patcher {
if (bpsCrc.getPatchFileCRC() != bpsCrc.getRealPatchCRC())
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
- long realRomCrc = FileUtils.checksumCRC32(romFile);
- if (realRomCrc != bpsCrc.getInputFileCRC()) {
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ long realRomCrc = FileUtils.checksumCRC32(romFile);
+ if (realRomCrc != bpsCrc.getInputFileCRC()) {
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
}
patch = new RandomAccessFile(patchFile, "r").getChannel();
@@ -133,9 +135,11 @@ public class BPS extends Patcher {
IOUtils.closeQuietly(output);
}
- long realOutCrc = FileUtils.checksumCRC32(outputFile);
- if (realOutCrc != bpsCrc.getOutputFileCRC())
- throw new PatchException(context.getString(R.string.notify_error_wrong_checksum_after_patching));
+ if(!ignoreChecksum) {
+ long realOutCrc = FileUtils.checksumCRC32(outputFile);
+ if (realOutCrc != bpsCrc.getOutputFileCRC())
+ throw new PatchException(context.getString(R.string.notify_error_wrong_checksum_after_patching));
+ }
}
// decode pointer
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/DPS.java b/app/src/main/java/org/emunix/unipatcher/patcher/DPS.java
index bcf60a7..4f848b4 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/DPS.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/DPS.java
@@ -42,7 +42,7 @@ public class DPS extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
if (patchFile.length() < MIN_SIZE_PATCH) {
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
@@ -63,9 +63,11 @@ public class DPS extends Patcher {
throw new PatchException(context.getString(R.string.notify_error_not_dps_patch));
// verify rom
- long romSize = getUInt(buffer, 194);
- if (romSize != romFile.length())
- throw new IOException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ long romSize = getUInt(buffer, 194);
+ if (romSize != romFile.length())
+ throw new IOException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
romStream = new RandomAccessFile(romFile, "r");
outputStream = new RandomAccessFile(outputFile, "rw");
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/EBP.java b/app/src/main/java/org/emunix/unipatcher/patcher/EBP.java
index fb3457b..b86901d 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/EBP.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/EBP.java
@@ -68,12 +68,12 @@ public class EBP extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
File cleanRom = File.createTempFile("rom", null, context.getCacheDir());
File ipsPatch = File.createTempFile("patch", null, context.getCacheDir());
try {
Utils.copyFile(context, romFile, cleanRom);
- prepareCleanRom(cleanRom);
+ prepareCleanRom(cleanRom, ignoreChecksum);
EBPtoIPS(patchFile, ipsPatch);
@@ -85,7 +85,7 @@ public class EBP extends Patcher {
}
}
- private void prepareCleanRom(File file) throws IOException, PatchException {
+ private void prepareCleanRom(File file, boolean ignoreChecksum) throws IOException, PatchException {
// delete smc header
SnesSmcHeader smc = new SnesSmcHeader();
try {
@@ -95,8 +95,10 @@ public class EBP extends Patcher {
}
// check rom size and remove unused expanded space
- if (file.length() < EB_CLEAN_ROM_SIZE)
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ if (file.length() < EB_CLEAN_ROM_SIZE)
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
if (file.length() > EB_CLEAN_ROM_SIZE && checkExpanded(file))
removeExpanded(file);
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java b/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java
index 23f69d8..65dce3e 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/IPS.java
@@ -50,6 +50,10 @@ public class IPS extends Patcher {
}
@Override
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
+ apply();
+ }
+
public void apply() throws PatchException, IOException {
BufferedInputStream romStream = null;
BufferedInputStream patchStream = null;
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/PPF.java b/app/src/main/java/org/emunix/unipatcher/patcher/PPF.java
index 1bc5005..373e2bd 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/PPF.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/PPF.java
@@ -68,7 +68,7 @@ public class PPF extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
if (patchFile.length() < 61) {
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
}
@@ -78,10 +78,10 @@ public class PPF extends Patcher {
applyPPF1();
break;
case 2:
- applyPPF2();
+ applyPPF2(ignoreChecksum);
break;
case 3:
- applyPPF3();
+ applyPPF3(ignoreChecksum);
break;
default:
throw new PatchException(context.getString(R.string.notify_error_not_ppf_patch));
@@ -112,15 +112,17 @@ public class PPF extends Patcher {
}
}
- private void applyPPF2() throws IOException, PatchException {
+ private void applyPPF2(boolean ignoreChecksum) throws IOException, PatchException {
try {
patchStream = new RandomAccessFile(patchFile, "r");
// Check size of ROM
patchStream.seek(56);
long romSize = readLittleEndianInt(patchStream);
- if (romSize != romFile.length()) {
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ if (romSize != romFile.length()) {
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
}
outputStream = new RandomAccessFile(outputFile, "rw");
@@ -131,8 +133,10 @@ public class PPF extends Patcher {
outputStream.seek(0x9320);
patchStream.read(patchBinaryBlock, 0, 1024);
outputStream.read(romBinaryBlock, 0, 1024);
- if (!Arrays.equals(patchBinaryBlock, romBinaryBlock))
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ if (!Arrays.equals(patchBinaryBlock, romBinaryBlock))
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
// Calculate end of patch data
long dataEnd = patchFile.length();
@@ -160,7 +164,7 @@ public class PPF extends Patcher {
}
}
- private void applyPPF3() throws IOException, PatchException {
+ private void applyPPF3(boolean ignoreChecksum) throws IOException, PatchException {
try {
patchStream = new RandomAccessFile(patchFile, "r");
outputStream = new RandomAccessFile(outputFile, "rw");
@@ -182,8 +186,10 @@ public class PPF extends Patcher {
}
patchStream.read(patchBinaryBlock, 0, 1024);
outputStream.read(romBinaryBlock, 0, 1024);
- if (!Arrays.equals(patchBinaryBlock, romBinaryBlock))
- throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ if (!Arrays.equals(patchBinaryBlock, romBinaryBlock))
+ throw new PatchException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
}
// Calculate end of patch data
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/Patcher.java b/app/src/main/java/org/emunix/unipatcher/patcher/Patcher.java
index bbadf2e..4ff5512 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/Patcher.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/Patcher.java
@@ -37,5 +37,5 @@ public abstract class Patcher {
outputFile = output;
}
- public abstract void apply() throws PatchException, IOException;
+ public abstract void apply(boolean ignoreChecksum) throws PatchException, IOException;
}
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/UPS.java b/app/src/main/java/org/emunix/unipatcher/patcher/UPS.java
index 9383dec..81e19b0 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/UPS.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/UPS.java
@@ -44,7 +44,7 @@ public class UPS extends Patcher {
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
if (patchFile.length() < 18) {
throw new PatchException(context.getString(R.string.notify_error_patch_corrupted));
@@ -90,7 +90,9 @@ public class UPS extends Patcher {
ySize = tmp;
upsCrc.swapInOut();
} else {
- throw new IOException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ if (!ignoreChecksum) {
+ throw new IOException(context.getString(R.string.notify_error_rom_not_compatible_with_patch));
+ }
}
romStream = new BufferedInputStream(new FileInputStream(romFile));
@@ -125,9 +127,11 @@ public class UPS extends Patcher {
IOUtils.closeQuietly(outputStream);
}
- long realOutCrc = FileUtils.checksumCRC32(outputFile);
- if (realOutCrc != upsCrc.getOutputFileCRC())
- throw new PatchException(context.getString(R.string.notify_error_wrong_checksum_after_patching));
+ if (!ignoreChecksum) {
+ long realOutCrc = FileUtils.checksumCRC32(outputFile);
+ if (realOutCrc != upsCrc.getOutputFileCRC())
+ throw new PatchException(context.getString(R.string.notify_error_wrong_checksum_after_patching));
+ }
}
// decode pointer
diff --git a/app/src/main/java/org/emunix/unipatcher/patcher/XDelta.java b/app/src/main/java/org/emunix/unipatcher/patcher/XDelta.java
index 970a1fb..153ff41 100644
--- a/app/src/main/java/org/emunix/unipatcher/patcher/XDelta.java
+++ b/app/src/main/java/org/emunix/unipatcher/patcher/XDelta.java
@@ -38,14 +38,14 @@ public class XDelta extends Patcher {
private static final int ERR_WRONG_CHECKSUM = -5010;
private static final int ERR_INVALID_INPUT = -17712;
- public static native int xdelta3apply(String patchPath, String romPath, String outputPath);
+ public static native int xdelta3apply(String patchPath, String romPath, String outputPath, boolean ignoreChecksum);
public XDelta(Context context, File patch, File rom, File output) {
super(context, patch, rom, output);
}
@Override
- public void apply() throws PatchException, IOException {
+ public void apply(boolean ignoreChecksum) throws PatchException, IOException {
if (checkXDelta1(patchFile))
throw new PatchException(context.getString(R.string.notify_error_xdelta1_unsupported));
@@ -55,7 +55,7 @@ public class XDelta extends Patcher {
throw new PatchException(context.getString(R.string.notify_error_failed_load_lib_xdelta3));
}
- int ret = xdelta3apply(patchFile.getPath(), romFile.getPath(), outputFile.getPath());
+ int ret = xdelta3apply(patchFile.getPath(), romFile.getPath(), outputFile.getPath(), ignoreChecksum);
switch (ret) {
case NO_ERROR:
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 585fec2..803be43 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -113,6 +113,9 @@
Укажите директорию с патчами
Укажите директорию для сохранения
Иначе ROM будет сохранён в директорию с ROM\'ами
+ Применение патчей
+ Игнорировать контрольную сумму
+ Не показывать ошибку, если используется неподходящий ROM. Используйте осторожно: включив эту опцию можно получить непроходимую игру.
Помощь
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ca5a176..63af5a4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -113,6 +113,9 @@
Specify patches directory
Specify output directory
Otherwise ROM will be stored in the ROM directory
+ Patching
+ Ignore checksums
+ Do not interrupt patching if you use the wrong ROM. Use caution: this option can break your game.
Help
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 5d3ea05..f0a1a97 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -33,4 +33,12 @@
android:summary="@string/settings_output_directory_description"
android:title="@string/settings_output_directory"/>
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/org/emunix/unipatcher/patcher/BPSTest.java b/app/src/test/java/org/emunix/unipatcher/patcher/BPSTest.java
index 947a5e4..c4f1b89 100644
--- a/app/src/test/java/org/emunix/unipatcher/patcher/BPSTest.java
+++ b/app/src/test/java/org/emunix/unipatcher/patcher/BPSTest.java
@@ -48,7 +48,7 @@ public class BPSTest {
BPS patcher = new BPS(mockContext, patch, in, out);
try {
- patcher.apply();
+ patcher.apply(false);
} catch (PatchException | IOException e) {
fail("Patching failed");
}
diff --git a/app/src/test/java/org/emunix/unipatcher/patcher/UPSTest.java b/app/src/test/java/org/emunix/unipatcher/patcher/UPSTest.java
index f2b3adf..b36776f 100644
--- a/app/src/test/java/org/emunix/unipatcher/patcher/UPSTest.java
+++ b/app/src/test/java/org/emunix/unipatcher/patcher/UPSTest.java
@@ -67,7 +67,7 @@ public class UPSTest {
UPS patcher = new UPS(mockContext, patch, in, out);
try {
- patcher.apply();
+ patcher.apply(false);
} catch (PatchException | IOException e) {
fail("Patching failed");
}