krisives / d2s-format Goto Github PK
View Code? Open in Web Editor NEWDiablo II Save File Format (.d2s format)
Diablo II Save File Format (.d2s format)
This is ready to be built in VS2022.
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <stdio.h>
#include<string>
using namespace std;
char** argv = NULL;
void main(int argc, char** argv)
{
if (argv[1] == NULL) {
cout << "\n\n\tNo .d2s file specified. \n\n\tUsage: d2scs.exe char.d2s\n\n" << endl;
return;
}
FILE* charFile;
charFile = fopen(argv[1], "r+b");
// zero out the previous checksum
char zero[4] = { 0 };
fseek(charFile, 12, SEEK_SET);
fwrite(zero, sizeof(char),sizeof(zero), charFile);
fflush(charFile);
fseek(charFile, 0, SEEK_SET);
unsigned char saveFileData[16];
unsigned long counter = 0;
unsigned int uSum = 0;
int n;
int uVar = 0;
int byte;
while ((n = fread(saveFileData, sizeof(char), 16, charFile)) > 0) {
int i;
for (i = 0; i < n; i++) {
// Current byte in charFile
byte = (unsigned)saveFileData[i];
//SAME as uSum line, just to double check if both produce the same checksum
if (uVar < 0)
byte++;
uVar = byte + uVar * 2;
//SAME as above block, just to double check if both produce the same checksum
uSum = ((uSum << 1) | (uSum >> 31)) + (unsigned)saveFileData[i];
}
counter += 16;
}
unsigned long r_uVar = _byteswap_ulong(uVar);
unsigned long r_uSum = _byteswap_ulong(uSum);
// write new checksum
fseek(charFile, 12, SEEK_SET);
fwrite(&uVar, sizeof(uVar), 1, charFile);
fflush(charFile);
fseek(charFile, 0, SEEK_SET);
printf("\n\n\t%08x checksum written to %s\n\n", r_uVar, argv[1]);
fclose(charFile);
}
according to http://www.coreyh.org/diablo-2-files/documentation/d2s_save_file_format_1.13d.html, the value of bytes 16-20 is the number of the currently active weapon set. Unfortunately, I have no means of checking that right now :)
const fs = require("fs");
const path = require("path");
const file = path.join(process.cwd(), "path_to_save.d2s");
function calculateSum(data) {
let sum = 0;
for (let i = 0; i < data.length; i++) {
let ch = data[i];
if (i >= 12 && i < 16) {
ch = 0;
}
ch += sum < 0;
sum = (sum << 1) + ch;
}
return sum;
}
function littleToBigEndian(number) {
return new DataView(
Int32Array.of(
new DataView(Int32Array.of(number).buffer).getUint32(0, true)
).buffer
);
}
function ashex(buffer) {
return buffer.getUint32(0, false).toString(16);
}
async function readSafeFile() {
return await new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) return reject(err);
return resolve(data);
});
});
}
async function writeCheckSumToSafeFile(data) {
return await new Promise((resolve, reject) => {
fs.writeFile(file, data, err => {
if (err) reject(err);
resolve();
});
});
}
readSafeFile().then(data => {
const sum = calculateSum(data);
const bufferSum = littleToBigEndian(sum);
const hex = ashex(bufferSum);
const newData = data;
for (let i = 0; i < 4; i++) {
newData[12 + i] = bufferSum.getInt8(i);
}
writeCheckSumToSafeFile(newData).then(() => console.log(hex));
});
Xp is stored at offset 802 as 4 byte little endian unsigned int multiplied by 2.
Eg, if your in-game xp is 79 689 129, then at offset 802 you'll see:
79 689 129 * 2 = 159 378 258 => hex => 52 EB 7F 09
So if you set xp bytes to zeros 00 00 00 00, you have to update char level (offset:43, 1 byte) with 01 and so on.
Can show nodejs code how to reset char level to 1.
should be add :
if checksum <0 ch = data[i]+1 # add this line
checksum = checksum<<1 + che
Something changed in Markdown now it doesnt render the tables
Hi. Thanks for the great resource. Please add my version of the checksum algorithm in PHP should this help anyone.
<?php
/*
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.
*/
/**
* @param string $hex
* @return string
*/
function swapEndianness(string $hex) {
return implode('', array_reverse(str_split($hex, 2)));
}
/**
* Calculate D2S Checksum
* @param $data
* @return string
*/
function checksum($fileData) {
$nSignature = 0;
foreach ($fileData as $k => $byte) {
if ($k == 12 || $k == 13 || $k == 14 || $k == 15) { // skip bytes 12,13,14,15
$byte = 0;
}
$nSignature = ((($nSignature << 1) | ($nSignature >> 31)) + $byte & 0xFFFFFFFF);
}
return swapEndianness(str_pad(dechex($nSignature), 8, 0, STR_PAD_LEFT));
}
$filename = "D:\Diablo II\MODS\ironman-dev\save\Sorc.d2s";
$fp = fopen($filename, "rb+");
fseek($fp, 12); // go to byte 12
fwrite($fp, pack('I', 0)); // clear the checksum field uInt32
$fileData = unpack('C*', file_get_contents($filename)); // open file and unpack
fseek($fp, 12); // go to byte 12
fwrite($fp, pack('H8', checksum($fileData))); // write new checksum
fclose($fp);
Hey!
http://coreyh.org/diablo-2-1.13d-code/
Plenty of code to help you with your d2s deconstruction.
adios.
Version: 1.14d
Before resetting, offset 0x1AB was 2.
After resetting, it's 1.
Change it back to 2, the reset option reappears.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.