Commit 1e4e17003dbaf08722a1f8f0bd38631974b1056f
0 parents
WIP
Showing
3 changed files
with
164 additions
and
0 deletions
d2char.c
0 โ 100644
1 | +++ a/d2char.c | ||
1 | +#include "d2char.h" | ||
2 | +#include <stdlib.h> | ||
3 | + | ||
4 | +uint32_t calcChecksum(D2CharHeader* c, void* charData) { | ||
5 | + uint32_t origChecksum = c->checksum; | ||
6 | + c->checksum = 0; | ||
7 | + uint32_t sum = 0; | ||
8 | + void* data = malloc(c->fileSize); | ||
9 | + memcpy(data, (void*)c, D2S_HEADER_LENGTH); | ||
10 | + memcpy(data + D2S_HEADER_LENGTH, charData, c->fileSize - D2S_HEADER_LENGTH); | ||
11 | + for(int i = 0; i < c->fileSize; ++i) { | ||
12 | + sum = (sum << 1) + ((uint8_t*)data)[i]; | ||
13 | + } | ||
14 | + free(data); | ||
15 | + c->checksum = origChecksum; | ||
16 | + return sum; | ||
17 | +} | ||
18 | + | ||
19 | +int checkChecksum(D2CharHeader* c, void* charData) { | ||
20 | + uint32_t checksum = calcChecksum(c, charData); | ||
21 | + return c->checksum == checksum; | ||
22 | +} | ||
23 | + | ||
24 | +int isHardcore(D2CharHeader* c) { | ||
25 | + return c->charStatus & D2S_CHARSTATUS_HARDCORE; | ||
26 | +} | ||
27 | + | ||
28 | +int hasDied(D2CharHeader* c) { | ||
29 | + return c->charStatus & D2S_CHARSTATUS_DIED; | ||
30 | +} | ||
31 | + | ||
32 | +int isExpansion(D2CharHeader* c) { | ||
33 | + return c->charStatus & D2S_CHARSTATUS_EXPANSION; | ||
34 | +} | ||
35 | + | ||
36 | +int isLadder(D2CharHeader* c) { | ||
37 | + return c->charStatus & D2S_CHARSTATUS_LADDER; | ||
38 | +} | ||
0 | \ No newline at end of file | 39 | \ No newline at end of file |
d2char.h
0 โ 100644
1 | +++ a/d2char.h | ||
1 | +#ifndef D2CHAR_H | ||
2 | +#define D2CHAR_H | ||
3 | + | ||
4 | +#include <stdint.h> | ||
5 | +#include "d2strings.h" | ||
6 | + | ||
7 | +#define D2S_HEADER_LENGTH 765 | ||
8 | +#define D2S_SIGNATURE 0xAA55AA55 | ||
9 | +#define D2S_CHECKSUM_OFFSET 12 | ||
10 | +#define D2S_CHECKSUM_LENGTH 4 | ||
11 | +#define D2S_CHARNAME_LENGTH 16 | ||
12 | +#define D2S_HOTKEYS_LENGTH 64 | ||
13 | +#define D2S_CHAR_APPEARANCE_LENGTH 32 | ||
14 | +#define D2S_DIFFICULTY_LENGTH 3 | ||
15 | +#define D2S_QUESTS_LENGTH 298 | ||
16 | +#define D2S_WAYPOINTS_LENGTH 81 | ||
17 | +#define D2S_NPCDATA_LENGTH 51 | ||
18 | + | ||
19 | +#define D2S_CHARSTATUS_HARDCORE 0x04 | ||
20 | +#define D2S_CHARSTATUS_DIED 0x08 | ||
21 | +#define D2S_CHARSTATUS_EXPANSION 0x20 | ||
22 | +#define D2S_CHARSTATUS_LADDER 0x40 | ||
23 | + | ||
24 | +#define D2S_CHARPROGRESS_CLASSIC_TIER0 3 | ||
25 | +#define D2S_CHARPROGRESS_CLASSIC_TIER1 | ||
26 | +#define D2S_CHARPROGRESS_CLASSIC_TIER2 | ||
27 | +#define D2S_CHARPROGRESS_CLASSIC_TIER3 | ||
28 | +#define D2S_CHARPROGRESS_EXPANSION_TIER0 | ||
29 | +#define D2S_CHARPROGRESS_EXPANSION_TIER1 | ||
30 | +#define D2S_CHARPROGRESS_EXPANSION_TIER2 | ||
31 | +#define D2S_CHARPROGRESS_EXPANSION_TIER3 | ||
32 | + | ||
33 | +enum D2Version { | ||
34 | + VER_106 = 71, | ||
35 | + VER_107 = 87, | ||
36 | + VER_108XP = 87, | ||
37 | + VER_108 = 89, | ||
38 | + VER_109 = 92, | ||
39 | + VER_110 = 96 | ||
40 | +}; | ||
41 | + | ||
42 | +enum D2CharClass { | ||
43 | + D2S_CHARCLASS_AMAZON = 0x00, | ||
44 | + D2S_CHARCLASS_SORCERESS = 0x01, | ||
45 | + D2S_CHARCLASS_NECROMANCER = 0x02, | ||
46 | + D2S_CHARCLASS_PALADIN = 0x03, | ||
47 | + D2S_CHARCLASS_BARBARIAN = 0x04, | ||
48 | + D2S_CHARCLASS_DRUID = 0x05, | ||
49 | + D2S_CHARCLASS_ASSASSIN = 0x06 | ||
50 | +}; | ||
51 | + | ||
52 | +typedef struct __attribute__((packed)){ | ||
53 | + uint32_t signature; | ||
54 | + uint32_t versionID; | ||
55 | + uint32_t fileSize; | ||
56 | + uint32_t checksum; | ||
57 | + uint32_t activeWeapon; // TODO | ||
58 | + char name[D2S_CHARNAME_LENGTH]; | ||
59 | + uint8_t charStatus; | ||
60 | + uint8_t charProgress; | ||
61 | + uint16_t unknown1; // TODO | ||
62 | + uint8_t charClass; | ||
63 | + uint16_t unknown2; // TODO | ||
64 | + uint8_t charLevel; | ||
65 | + uint32_t unknown3; // TODO | ||
66 | + uint32_t lastPlayed; | ||
67 | + uint32_t unknown4; // TODO | ||
68 | + uint8_t hotkeys[D2S_HOTKEYS_LENGTH]; | ||
69 | + uint32_t leftAbility; | ||
70 | + uint32_t rightAbility; | ||
71 | + uint32_t leftAbilityAlt; | ||
72 | + uint32_t rightAbilityAlt; | ||
73 | + uint8_t charAppearance[D2S_CHAR_APPEARANCE_LENGTH]; | ||
74 | + uint8_t difficulty[D2S_DIFFICULTY_LENGTH]; | ||
75 | + uint32_t mapID; | ||
76 | + uint16_t unknown5; | ||
77 | + uint16_t mercenaryStatus; | ||
78 | + uint32_t mercenarySeed; | ||
79 | + uint16_t mercenaryNameID; | ||
80 | + uint16_t mercenaryType; | ||
81 | + uint32_t mercenaryExp; | ||
82 | + uint8_t unknown6[144]; | ||
83 | + uint8_t questData[D2S_QUESTS_LENGTH]; | ||
84 | + uint8_t waypointData[D2S_WAYPOINTS_LENGTH]; | ||
85 | + uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO | ||
86 | +} D2CharHeader; | ||
87 | + | ||
88 | +uint32_t calcChecksum(D2CharHeader* c, void* charData); | ||
89 | +int checkChecksum(D2CharHeader* c, void* charData); | ||
90 | +int isHardcore(D2CharHeader* c); | ||
91 | +int hasDied(D2CharHeader* c); | ||
92 | +int isExpansion(D2CharHeader* c); | ||
93 | +int isLadder(D2CharHeader* c); | ||
94 | + | ||
95 | +#endif | ||
0 | \ No newline at end of file | 96 | \ No newline at end of file |
d2strings.h
0 โ 100644
1 | +++ a/d2strings.h | ||
1 | +#ifndef D2STRINGS_H | ||
2 | +#define D2STRINGS_H | ||
3 | + | ||
4 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_M = ""; | ||
5 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_M = "Sir"; | ||
6 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_M = "Lord"; | ||
7 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_M = "Baron"; | ||
8 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_HARDCORE_M = ""; | ||
9 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_M = "Count"; | ||
10 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_M = "Duke"; | ||
11 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_M = "King"; | ||
12 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_F = ""; | ||
13 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_F = "Dame"; | ||
14 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_F = "Lady"; | ||
15 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_F = "Baroness"; | ||
16 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER0_NAME_HARDCORE_F = ""; | ||
17 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_F = "Countess"; | ||
18 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_F = "Duchess"; | ||
19 | +const char* D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_F = "Queen"; | ||
20 | + | ||
21 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER0_NAME = ""; | ||
22 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER1_NAME = "Slayer"; | ||
23 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER2_NAME = "Champion"; | ||
24 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_M = "Patriarch"; | ||
25 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_F = "Matriarch"; | ||
26 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER0_NAME_HARDCORE = ""; | ||
27 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER1_NAME_HARDCORE = "Destroyer"; | ||
28 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER2_NAME_HARDCORE = "Conqueror"; | ||
29 | +const char* D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_HARDCORE = "Guardian"; | ||
30 | + | ||
31 | +#endif | ||
0 | \ No newline at end of file | 32 | \ No newline at end of file |