2022-05-07 12:25:27 +00:00
|
|
|
<?php
|
2022-06-22 07:34:39 +00:00
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
/*
|
|
|
|
Diablo 2 D2S Save File Checksum Calculator
|
|
|
|
By Hash Borgir (https://www.psychedelicsdaily.com)
|
|
|
|
@date 6/4/2022
|
|
|
|
|
|
|
|
Checksum field is at byte 12.
|
|
|
|
Bytes 12/13/14/15 as a uint32.
|
|
|
|
Set this to 0.
|
|
|
|
After clearing the checksum field add up the values of all the bytes in the file and rotate the running total one bit to the left before adding the next byte.
|
|
|
|
*/
|
|
|
|
|
|
|
|
function swapEndianness(string $hex) {
|
|
|
|
return implode('', array_reverse(str_split($hex, 2)));
|
|
|
|
}
|
2022-06-22 07:34:39 +00:00
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
function checksum($fileData) {
|
|
|
|
$nSignature = 0;
|
|
|
|
foreach ($fileData as $k => $byte) {
|
|
|
|
if ($k == 12 || $k == 13 || $k == 14 || $k == 15) {
|
|
|
|
$byte = 0;
|
2022-06-22 07:34:39 +00:00
|
|
|
}
|
2022-07-06 23:41:24 +00:00
|
|
|
$nSignature = ((($nSignature << 1) | ($nSignature >> 31)) + $byte & 0xFFFFFFFF);
|
2022-06-22 07:34:39 +00:00
|
|
|
}
|
2022-07-06 23:41:24 +00:00
|
|
|
return swapEndianness(str_pad(dechex($nSignature), 8, 0, STR_PAD_LEFT));
|
2022-06-21 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
$filename = "D:\Diablo II\MODS\ironman-dev\save\Necro.d2s";
|
|
|
|
$fp = fopen($filename, "r+b");
|
2022-07-03 10:13:50 +00:00
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
fseek($fp, 12); // go to byte 12
|
|
|
|
fwrite($fp, pack('I', 0)); // clear the checksum field uInt32
|
2022-07-03 10:13:50 +00:00
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
$fileData = unpack('C*', file_get_contents($filename)); // open file and unpack
|
2022-07-03 10:13:50 +00:00
|
|
|
|
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
var_dump(checksum($fileData));
|
2022-06-22 07:47:49 +00:00
|
|
|
|
2022-07-06 23:41:24 +00:00
|
|
|
fseek($fp, 12); // go to byte 12
|
|
|
|
fwrite($fp, pack('H8', checksum($fileData))); // write new checksum
|
|
|
|
fclose($fp);
|