Commit f8fab420039a619e9f25498ca55cb995630dd759
1 parent
00938948
Added stat code
Showing
4 changed files
with
129 additions
and
34 deletions
d2char.c
@@ -227,14 +227,4 @@ int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty) { | @@ -227,14 +227,4 @@ int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty) { | ||
227 | } | 227 | } |
228 | c->charProgress = progress; | 228 | c->charProgress = progress; |
229 | return 0; | 229 | return 0; |
230 | -} | ||
231 | - | ||
232 | -int getAttribute(D2S_STAT attr) { | ||
233 | - // TODO implement | ||
234 | - return 0; | ||
235 | -} | ||
236 | - | ||
237 | -int setAttribute(D2S_STAT attr, unsigned int value) { | ||
238 | - // TODO implement | ||
239 | - return 0; | ||
240 | } | 230 | } |
241 | \ No newline at end of file | 231 | \ No newline at end of file |
d2char.h
@@ -55,25 +55,6 @@ typedef enum D2S_CHARCLASS { | @@ -55,25 +55,6 @@ typedef enum D2S_CHARCLASS { | ||
55 | D2S_CHARCLASS_ASSASSIN = 6 | 55 | D2S_CHARCLASS_ASSASSIN = 6 |
56 | } D2S_CHARCLASS; | 56 | } D2S_CHARCLASS; |
57 | 57 | ||
58 | -typedef enum D2S_STAT { | ||
59 | - D2S_STAT_STRENGTH = 0x00, | ||
60 | - D2S_STAT_ENERGY = 0x01, | ||
61 | - D2S_STAT_DEXTERITY = 0x02, | ||
62 | - D2S_STAT_VITALITY = 0x03, | ||
63 | - D2S_STAT_STATPTS = 0x04, | ||
64 | - D2S_STAT_SKILLPTS = 0x05, | ||
65 | - D2S_STAT_LIFE = 0x06, | ||
66 | - D2S_STAT_MAXLIFE = 0x07, | ||
67 | - D2S_STAT_MANA = 0x08, | ||
68 | - D2S_STAT_MAXMANA = 0x09, | ||
69 | - D2S_STAT_STAMINA = 0x0a, | ||
70 | - D2S_STAT_MAXSTAMINA = 0x0b, | ||
71 | - D2S_STAT_LEVEL = 0x0c, | ||
72 | - D2S_STAT_EXPERIENCE = 0x0d, | ||
73 | - D2S_STAT_GOLD = 0x0e, | ||
74 | - D2S_STAT_GOLDSTASH = 0x0f, | ||
75 | -} D2S_STAT; | ||
76 | - | ||
77 | typedef enum D2S_ACT { | 58 | typedef enum D2S_ACT { |
78 | D2S_ACT_UNKNOWN = -1, | 59 | D2S_ACT_UNKNOWN = -1, |
79 | D2S_ACT1 = 0, | 60 | D2S_ACT1 = 0, |
@@ -119,8 +100,6 @@ typedef struct __attribute__((packed)){ | @@ -119,8 +100,6 @@ typedef struct __attribute__((packed)){ | ||
119 | D2WaypointsData waypointsData; | 100 | D2WaypointsData waypointsData; |
120 | uint8_t unknown7; // TODO. Apparently this is always 0x01 | 101 | uint8_t unknown7; // TODO. Apparently this is always 0x01 |
121 | uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented | 102 | uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented |
122 | - // TODO Add stats | ||
123 | - // TODO Add skills | ||
124 | } D2CharHeader; | 103 | } D2CharHeader; |
125 | 104 | ||
126 | 105 | ||
@@ -161,7 +140,4 @@ D2S_ACT getCurrentAct(D2CharHeader* c); | @@ -161,7 +140,4 @@ D2S_ACT getCurrentAct(D2CharHeader* c); | ||
161 | void getProgress(D2CharHeader* c, D2S_ACT* act, D2S_DIFFICULTY* difficulty); | 140 | void getProgress(D2CharHeader* c, D2S_ACT* act, D2S_DIFFICULTY* difficulty); |
162 | int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty); | 141 | int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty); |
163 | 142 | ||
164 | -int getAttribute(D2S_STAT attr); | ||
165 | -int setAttribute(D2S_STAT attr, unsigned int value); | ||
166 | - | ||
167 | #endif | 143 | #endif |
168 | \ No newline at end of file | 144 | \ No newline at end of file |
d2stat.c
0 → 100644
1 | +#include "d2stat.h" | ||
2 | + | ||
3 | +#include <stdio.h> | ||
4 | +#include <string.h> | ||
5 | + | ||
6 | +// Internal function, gives the offset ***IN BITS, NOT BYTES*** of the specified stat | ||
7 | +unsigned long long int _searchStat(D2S_STAT stat, void* charData, size_t dataLen) { | ||
8 | + if(!strncmp(charData, D2S_STAT_HEADER, D2S_STAT_HEADER_LENGTH)) { | ||
9 | + fprintf(stderr,"libd2char error: Stat header not present in charData\n"); | ||
10 | + return 0; | ||
11 | + } | ||
12 | + unsigned long long int byteOffset = D2S_STAT_HEADER_LENGTH; | ||
13 | + unsigned long long int bitOffset = 0; | ||
14 | + while(byteOffset < dataLen) { | ||
15 | + uint16_t statID = 0; | ||
16 | + memcpy(&statID, charData + byteOffset, sizeof(statID)); | ||
17 | + statID >>= bitOffset; | ||
18 | + statID &= 0x1FF; | ||
19 | + if(statID == D2S_STAT_FOOTER) { | ||
20 | + break; | ||
21 | + } else if(statID == stat) { | ||
22 | + return (byteOffset * 8) + bitOffset; | ||
23 | + } | ||
24 | + byteOffset += statCost[statID] / 8; | ||
25 | + bitOffset += statCost[statID] % 8; | ||
26 | + } | ||
27 | + return 0; | ||
28 | +} | ||
29 | + | ||
30 | +int getStat(D2S_STAT stat, unsigned int* value, void* charData, size_t dataLen) { | ||
31 | + unsigned long long int statOffset = _searchStat(stat,charData,dataLen); | ||
32 | + if(!statOffset) { | ||
33 | + fprintf(stderr,"libd2char error: Unable to find attribute: %d\n", stat); | ||
34 | + return -1; | ||
35 | + } | ||
36 | + uint64_t statValue = 0; | ||
37 | + memcpy(&statValue, charData + (statOffset / 8), sizeof(statValue)); | ||
38 | + statValue >>= (statOffset % 8); | ||
39 | + statValue &= statCostMask[stat]; | ||
40 | + *value = (unsigned int)statValue; | ||
41 | + return 0; | ||
42 | +} | ||
43 | + | ||
44 | +int setStat(D2S_STAT stat, unsigned int value, void* charData, size_t dataLen) { | ||
45 | + unsigned long long int statOffset = _searchStat(stat,charData,dataLen); | ||
46 | + if(!statOffset) { | ||
47 | + fprintf(stderr,"libd2char error: Unable to find attribute: %d\n", stat); | ||
48 | + return -1; | ||
49 | + } | ||
50 | + uint64_t statValue = 0; | ||
51 | + memcpy(&statValue, charData + (statOffset / 8), sizeof(statValue)); | ||
52 | + statValue &= (~statCostMask[stat] << (statOffset % 8)); | ||
53 | + statValue |= (value << (statOffset % 8)); | ||
54 | + memcpy(charData + (statOffset / 8), &statValue, sizeof(statValue)); | ||
55 | + return 0; | ||
56 | +} | ||
0 | \ No newline at end of file | 57 | \ No newline at end of file |
d2stat.h
0 → 100644
1 | +#ifndef D2STAT_H | ||
2 | +#define D2STAT_H | ||
3 | + | ||
4 | +#include <stdint.h> | ||
5 | +#include <stdlib.h> | ||
6 | + | ||
7 | +#define D2S_STAT_HEADER "gf" | ||
8 | +#define D2S_STAT_HEADER_LENGTH 2 | ||
9 | +#define D2S_STAT_FOOTER 0x1FF | ||
10 | + | ||
11 | +typedef enum D2S_STAT { | ||
12 | + D2S_STAT_STRENGTH = 0x00, | ||
13 | + D2S_STAT_ENERGY = 0x01, | ||
14 | + D2S_STAT_DEXTERITY = 0x02, | ||
15 | + D2S_STAT_VITALITY = 0x03, | ||
16 | + D2S_STAT_STATPTS = 0x04, | ||
17 | + D2S_STAT_SKILLPTS = 0x05, | ||
18 | + D2S_STAT_LIFE = 0x06, | ||
19 | + D2S_STAT_MAXLIFE = 0x07, | ||
20 | + D2S_STAT_MANA = 0x08, | ||
21 | + D2S_STAT_MAXMANA = 0x09, | ||
22 | + D2S_STAT_STAMINA = 0x0a, | ||
23 | + D2S_STAT_MAXSTAMINA = 0x0b, | ||
24 | + D2S_STAT_LEVEL = 0x0c, | ||
25 | + D2S_STAT_EXPERIENCE = 0x0d, | ||
26 | + D2S_STAT_GOLD = 0x0e, | ||
27 | + D2S_STAT_GOLDSTASH = 0x0f, | ||
28 | +} D2S_STAT; | ||
29 | + | ||
30 | +// Internal use. Length of each stat in bits | ||
31 | +const int statCost[] = { | ||
32 | + 10, //D2S_STAT_STRENGTH | ||
33 | + 10, //D2S_STAT_ENERGY | ||
34 | + 10, //D2S_STAT_DEXTERITY | ||
35 | + 10, //D2S_STAT_VITALITY | ||
36 | + 10, //D2S_STAT_STATPTS | ||
37 | + 8, //D2S_STAT_SKILLPTS | ||
38 | + 21, //D2S_STAT_LIFE | ||
39 | + 21, //D2S_STAT_MAXLIFE | ||
40 | + 21, //D2S_STAT_MANA | ||
41 | + 21, //D2S_STAT_MAXMANA | ||
42 | + 21, //D2S_STAT_STAMINA | ||
43 | + 21, //D2S_STAT_MAXSTAMINA | ||
44 | + 7, //D2S_STAT_LEVEL | ||
45 | + 32, //D2S_STAT_EXPERIENCE | ||
46 | + 25, //D2S_STAT_GOLD | ||
47 | + 25 //D2S_STAT_GOLDSTASH | ||
48 | +}; | ||
49 | + | ||
50 | +// Internal use. Mask to apply to the bit offset (when properly shifted) to get the stat value | ||
51 | +const uint64_t statCostMask[] = { | ||
52 | + 0x00000000000003FF, //D2S_STAT_STRENGTH (10 bits) | ||
53 | + 0x00000000000003FF, //D2S_STAT_ENERGY (10 bits) | ||
54 | + 0x00000000000003FF, //D2S_STAT_DEXTERITY (10 bits) | ||
55 | + 0x00000000000003FF, //D2S_STAT_VITALITY (10 bits) | ||
56 | + 0x00000000000003FF, //D2S_STAT_STATPTS (10 bits) | ||
57 | + 0x00000000000000FF, //D2S_STAT_SKILLPTS (8 bits) | ||
58 | + 0x00000000001FFFFF, //D2S_STAT_LIFE (21 bits) | ||
59 | + 0x00000000001FFFFF, //D2S_STAT_MAXLIFE (21 bits) | ||
60 | + 0x00000000001FFFFF, //D2S_STAT_MANA (21 bits) | ||
61 | + 0x00000000001FFFFF, //D2S_STAT_MAXMANA (21 bits) | ||
62 | + 0x00000000001FFFFF, //D2S_STAT_STAMINA (21 bits) | ||
63 | + 0x00000000001FFFFF, //D2S_STAT_MAXSTAMINA (21 bits) | ||
64 | + 0x000000000000007F, //D2S_STAT_LEVEL (7 bits) | ||
65 | + 0x00000000FFFFFFFF, //D2S_STAT_EXPERIENCE (32 bits) | ||
66 | + 0x0000000001FFFFFF, //D2S_STAT_GOLD (25 bits) | ||
67 | + 0x0000000001FFFFFF //D2S_STAT_GOLDSTASH (25 bits) | ||
68 | +}; | ||
69 | + | ||
70 | +int getStat(D2S_STAT stat, unsigned int* value, void* charData, size_t dataLen); | ||
71 | +int setStat(D2S_STAT stat, unsigned int value, void* charData, size_t dataLen); | ||
72 | + | ||
73 | +#endif | ||
0 | \ No newline at end of file | 74 | \ No newline at end of file |