Changed checksum signature for multiple checksums

This commit is contained in:
Robin K 2021-12-25 22:49:23 +01:00
parent d725e2a527
commit 53c7158d2d
7 changed files with 128 additions and 54 deletions

View File

@ -4,6 +4,7 @@ ECUDEFERROR = ECU Definition Error
TABLELOADERR = There was an error loading table {0}
YES = Yes
NO = No
CHECKSUMFIXED = %d/%d Checksums needed to be updated.
CHKSUMINVALID = One or more ROM image Checksums is invalid. Calculate new Checksums?\n(NOTE: this will only fix the Checksums it will NOT repair a corrupt ROM image.
CHECKSUMFIX = Checksum Fix
INVLAIDCHKSUM = Checksum is invalid.\nThe ROM image may be corrupt or it has been hex edited manually.\nThe checksum can be corrected when the ROM is saved if your trust it is not corrupt.

View File

@ -49,6 +49,7 @@ import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import com.romraider.Settings;
import com.romraider.editor.ecu.ECUEditorManager;
import com.romraider.logger.ecu.ui.handler.table.TableUpdateHandler;
import com.romraider.maps.checksum.ChecksumManager;
import com.romraider.swing.CategoryTreeNode;
@ -515,11 +516,13 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
if (!checksumManagers.isEmpty()) {
for(ChecksumManager cm: checksumManagers) {
if (cm == null || !cm.validate(binData)) {
int localCorrectCs = cm.validate(binData);
if (cm == null || cm.getNumberOfChecksums() != localCorrectCs) {
valid = false;
}
else {
correctChecksums++;
correctChecksums+=localCorrectCs;
}
}
}
@ -534,9 +537,26 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
return correctChecksums;
}
public void updateChecksum() {
public int updateChecksum() {
int updatedCs = 0;
for(ChecksumManager cm: checksumManagers) {
cm.update(binData);
updatedCs+=cm.update(binData);
}
ECUEditorManager.getECUEditor().getStatusPanel().setStatus(
String.format(rb.getString("CHECKSUMFIXED"), updatedCs, getTotalAmountOfChecksums()));
return updatedCs;
}
public int getTotalAmountOfChecksums() {
int cs = 0;
for(ChecksumManager cm: checksumManagers) {
cs+=cm.getNumberOfChecksums();
}
return cs;
}
}

View File

@ -48,19 +48,36 @@ public final class ChecksumALT2 extends NissanChecksum {
}
}
public boolean validate(byte[] binData) {
public int validate(byte[] binData) {
calculator.calculate(range, binData, results);
final boolean valid =
(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) &&
(results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true)) &&
(results.get(START) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(START), 2, false)) &&
(results.get(SKIPLOC) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(SKIPLOC), 2, false));
return valid;
int valid = 0;
if(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) {
valid++;
}
if(results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true)) {
valid++;
}
if(results.get(START) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(START), 2, false)) {
valid++;
}
if(results.get(SKIPLOC) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(SKIPLOC), 2, false)) {
valid++;
}
return valid;
}
public void update(byte[] binData) {
public int update(byte[] binData) {
super.update(binData);
int updateNeeded = getNumberOfChecksums();
System.arraycopy(parseIntegerValue(results.get(START), Settings.Endian.BIG, 2), 0, binData, range.get(START), 2);
System.arraycopy(parseIntegerValue(results.get(SKIPLOC), Settings.Endian.BIG, 2), 0, binData, range.get(SKIPLOC), 2);
return updateNeeded;
}
}

View File

@ -39,40 +39,39 @@ import com.romraider.util.HexUtil;
private int xorloc;
private byte xort;
private boolean configured = false;
public ChecksumBYTEXOR() {}
@Override
public void configure(Map<String, String> vars) {
this.start = HexUtil.hexToInt(vars.get(START));
this.end = HexUtil.hexToInt(vars.get(END));
this.xorloc = HexUtil.hexToInt(vars.get(XORLOC));
}
this.configured = true;
@Override
public int getNumberOfChecksums() {
return 1;
}
@Override
public int validate(byte[] binData) {
calculate(binData);
int valid = 0;
if(xort == (byte)parseByteValue(binData, Settings.Endian.BIG, xorloc, 1, false))
valid++;
return valid;
}
@Override
public boolean validate(byte[] binData) {
if(!configured) {
System.err.println("Checksum Manager was not configured before it was used for validating!");
return false;
}
else {
calculate(binData);
final boolean valid = (xort == (byte)parseByteValue(binData, Settings.Endian.BIG, xorloc, 1, false));
return valid;
}
}
public int update(byte[] binData) {
int updateNeeded = 0;
calculate(binData);
@Override
public void update(byte[] binData) {
if(!configured)
System.err.println("Checksum Manager was not configured before it was used for updating!");
else {
calculate(binData);
binData[xorloc] = xort;
}
if(binData[xorloc] != xort) updateNeeded++;
binData[xorloc] = xort;
return updateNeeded;
}
private void calculate(byte[] binData) {

View File

@ -25,7 +25,6 @@ import static javax.swing.JOptionPane.showMessageDialog;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.Map;
import java.util.ResourceBundle;
@ -74,7 +73,7 @@ public final class ChecksumFactory {
//Custom checksum which comes with the definition
//Path is relative to the current definition directory
if(pathCustomChecksum != null && rom.getDefinitionPath() != null) {
path = Paths.get(rom.getDefinitionPath().getParent(), pathCustomChecksum).toString();
path = rom.getDefinitionPath().getParent() + pathCustomChecksum;
cl = new URLClassLoader(new URL[]{new File(path).toURI().toURL()});
cls = cl.loadClass(ChecksumFactory.class.getPackage().getName() + "." + type);

View File

@ -36,16 +36,23 @@ public interface ChecksumManager {
*/
void configure(Map<String, String> vars);
/**
* Returns the amount of checksums
* @return Number of total checksums
*/
int getNumberOfChecksums();
/**
* Perform the checksum validation upon ROM file loading.
* @param binData - the ROM file to validate
* @return true or false, the result of validation
* @return Number of correct checksums
*/
boolean validate(byte[] data);
int validate(byte[] data);
/**
* Update the checksum upon saving the ROM file.
* @param data - the ROM file to update
* @param data - the ROM file to update
* @return Number of checksums which needed to be updated
*/
void update(byte[] data);
int update(byte[] data);
}

View File

@ -22,6 +22,7 @@ package com.romraider.maps.checksum;
import static com.romraider.xml.RomAttributeParser.parseByteValue;
import static com.romraider.xml.RomAttributeParser.parseIntegerValue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -43,6 +44,7 @@ import com.romraider.util.HexUtil;
protected final Map<String, Integer> results = new HashMap<String, Integer>();
protected Calculator calculator;
@Override
public void configure(Map<String, String> vars) {
range.put(START, HexUtil.hexToInt(vars.get(START)));
range.put(END, HexUtil.hexToInt(vars.get(END)));
@ -50,17 +52,46 @@ import com.romraider.util.HexUtil;
range.put(XORLOC, HexUtil.hexToInt(vars.get(XORLOC)));
}
public boolean validate(byte[] binData) {
@Override
public int getNumberOfChecksums() {
return 2;
}
@Override
public int validate(byte[] binData) {
calculator.calculate(range, binData, results);
final boolean valid =
(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) &&
(results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true));
int valid = 0;
if(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) {
valid++;
}
if((results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true))) {
valid++;
}
return valid;
}
public void update(byte[] binData) {
@Override
public int update(byte[] binData) {
calculator.calculate(range, binData, results);
int updateNeeded = getNumberOfChecksums();
if(!Arrays.equals(parseIntegerValue(results.get(SUMT), Settings.Endian.BIG, 4),
Arrays.copyOfRange(binData, range.get(SUMLOC), 4))){
updateNeeded++;
}
if(!Arrays.equals(parseIntegerValue(results.get(XORT), Settings.Endian.BIG, 4),
Arrays.copyOfRange(binData, range.get(XORLOC), 4))){
updateNeeded++;
}
//TODO: Dont copy if arrays dont need updating
System.arraycopy(parseIntegerValue(results.get(SUMT), Settings.Endian.BIG, 4), 0, binData, range.get(SUMLOC), 4);
System.arraycopy(parseIntegerValue(results.get(XORT), Settings.Endian.BIG, 4), 0, binData, range.get(XORLOC), 4);
return updateNeeded;
}
}