From 1e4e17003dbaf08722a1f8f0bd38631974b1056f Mon Sep 17 00:00:00 2001 From: Imanol-Mikel Barba Sabariego Date: Mon, 6 Jul 2020 04:25:29 +0100 Subject: [PATCH] WIP --- d2char.c | 38 ++++++++++++++++++++++++++++++++++++++ d2char.h | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ d2strings.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 0 deletions(-) create mode 100644 d2char.c create mode 100644 d2char.h create mode 100644 d2strings.h diff --git a/d2char.c b/d2char.c new file mode 100644 index 0000000..e341b8d --- /dev/null +++ b/d2char.c @@ -0,0 +1,38 @@ +#include "d2char.h" +#include + +uint32_t calcChecksum(D2CharHeader* c, void* charData) { + uint32_t origChecksum = c->checksum; + c->checksum = 0; + uint32_t sum = 0; + void* data = malloc(c->fileSize); + memcpy(data, (void*)c, D2S_HEADER_LENGTH); + memcpy(data + D2S_HEADER_LENGTH, charData, c->fileSize - D2S_HEADER_LENGTH); + for(int i = 0; i < c->fileSize; ++i) { + sum = (sum << 1) + ((uint8_t*)data)[i]; + } + free(data); + c->checksum = origChecksum; + return sum; +} + +int checkChecksum(D2CharHeader* c, void* charData) { + uint32_t checksum = calcChecksum(c, charData); + return c->checksum == checksum; +} + +int isHardcore(D2CharHeader* c) { + return c->charStatus & D2S_CHARSTATUS_HARDCORE; +} + +int hasDied(D2CharHeader* c) { + return c->charStatus & D2S_CHARSTATUS_DIED; +} + +int isExpansion(D2CharHeader* c) { + return c->charStatus & D2S_CHARSTATUS_EXPANSION; +} + +int isLadder(D2CharHeader* c) { + return c->charStatus & D2S_CHARSTATUS_LADDER; +} \ No newline at end of file diff --git a/d2char.h b/d2char.h new file mode 100644 index 0000000..a0ed17f --- /dev/null +++ b/d2char.h @@ -0,0 +1,95 @@ +#ifndef D2CHAR_H +#define D2CHAR_H + +#include +#include "d2strings.h" + +#define D2S_HEADER_LENGTH 765 +#define D2S_SIGNATURE 0xAA55AA55 +#define D2S_CHECKSUM_OFFSET 12 +#define D2S_CHECKSUM_LENGTH 4 +#define D2S_CHARNAME_LENGTH 16 +#define D2S_HOTKEYS_LENGTH 64 +#define D2S_CHAR_APPEARANCE_LENGTH 32 +#define D2S_DIFFICULTY_LENGTH 3 +#define D2S_QUESTS_LENGTH 298 +#define D2S_WAYPOINTS_LENGTH 81 +#define D2S_NPCDATA_LENGTH 51 + +#define D2S_CHARSTATUS_HARDCORE 0x04 +#define D2S_CHARSTATUS_DIED 0x08 +#define D2S_CHARSTATUS_EXPANSION 0x20 +#define D2S_CHARSTATUS_LADDER 0x40 + +#define D2S_CHARPROGRESS_CLASSIC_TIER0 3 +#define D2S_CHARPROGRESS_CLASSIC_TIER1 +#define D2S_CHARPROGRESS_CLASSIC_TIER2 +#define D2S_CHARPROGRESS_CLASSIC_TIER3 +#define D2S_CHARPROGRESS_EXPANSION_TIER0 +#define D2S_CHARPROGRESS_EXPANSION_TIER1 +#define D2S_CHARPROGRESS_EXPANSION_TIER2 +#define D2S_CHARPROGRESS_EXPANSION_TIER3 + +enum D2Version { + VER_106 = 71, + VER_107 = 87, + VER_108XP = 87, + VER_108 = 89, + VER_109 = 92, + VER_110 = 96 +}; + +enum D2CharClass { + D2S_CHARCLASS_AMAZON = 0x00, + D2S_CHARCLASS_SORCERESS = 0x01, + D2S_CHARCLASS_NECROMANCER = 0x02, + D2S_CHARCLASS_PALADIN = 0x03, + D2S_CHARCLASS_BARBARIAN = 0x04, + D2S_CHARCLASS_DRUID = 0x05, + D2S_CHARCLASS_ASSASSIN = 0x06 +}; + +typedef struct __attribute__((packed)){ + uint32_t signature; + uint32_t versionID; + uint32_t fileSize; + uint32_t checksum; + uint32_t activeWeapon; // TODO + char name[D2S_CHARNAME_LENGTH]; + uint8_t charStatus; + uint8_t charProgress; + uint16_t unknown1; // TODO + uint8_t charClass; + uint16_t unknown2; // TODO + uint8_t charLevel; + uint32_t unknown3; // TODO + uint32_t lastPlayed; + uint32_t unknown4; // TODO + uint8_t hotkeys[D2S_HOTKEYS_LENGTH]; + uint32_t leftAbility; + uint32_t rightAbility; + uint32_t leftAbilityAlt; + uint32_t rightAbilityAlt; + uint8_t charAppearance[D2S_CHAR_APPEARANCE_LENGTH]; + uint8_t difficulty[D2S_DIFFICULTY_LENGTH]; + uint32_t mapID; + uint16_t unknown5; + uint16_t mercenaryStatus; + uint32_t mercenarySeed; + uint16_t mercenaryNameID; + uint16_t mercenaryType; + uint32_t mercenaryExp; + uint8_t unknown6[144]; + uint8_t questData[D2S_QUESTS_LENGTH]; + uint8_t waypointData[D2S_WAYPOINTS_LENGTH]; + uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO +} D2CharHeader; + +uint32_t calcChecksum(D2CharHeader* c, void* charData); +int checkChecksum(D2CharHeader* c, void* charData); +int isHardcore(D2CharHeader* c); +int hasDied(D2CharHeader* c); +int isExpansion(D2CharHeader* c); +int isLadder(D2CharHeader* c); + +#endif \ No newline at end of file diff --git a/d2strings.h b/d2strings.h new file mode 100644 index 0000000..0400615 --- /dev/null +++ b/d2strings.h @@ -0,0 +1,31 @@ +#ifndef D2STRINGS_H +#define D2STRINGS_H + +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_M = ""; +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_M = "Sir"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_M = "Lord"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_M = "Baron"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_HARDCORE_M = ""; +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_M = "Count"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_M = "Duke"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_M = "King"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_F = ""; +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_F = "Dame"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_F = "Lady"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_F = "Baroness"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_HARDCORE_F = ""; +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_F = "Countess"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_F = "Duchess"; +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_F = "Queen"; + +const char* D2S_CHARPROGRESS_EXPANSION_TIER0_NAME = ""; +const char* D2S_CHARPROGRESS_EXPANSION_TIER1_NAME = "Slayer"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER2_NAME = "Champion"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_M = "Patriarch"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_F = "Matriarch"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER0_NAME_HARDCORE = ""; +const char* D2S_CHARPROGRESS_EXPANSION_TIER1_NAME_HARDCORE = "Destroyer"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER2_NAME_HARDCORE = "Conqueror"; +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_HARDCORE = "Guardian"; + +#endif \ No newline at end of file -- libgit2 0.22.2