Giter Site home page Giter Site logo

d2s-format's People

Contributors

grandpagamehacker avatar gucio321 avatar krisives avatar satandidnowrong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d2s-format's Issues

[Suggestion]: My C++ version of the checksum algorithm should it help anyone

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);
}

Implementation of checksum calculation in javascript

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 offset for 1.12 d2s

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.

Fix formatting

Something changed in Markdown now it doesnt render the tables

[Suggestion]: My PHP version of the checksum algorithm should it help anyone

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);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.