Commit f8fab420039a619e9f25498ca55cb995630dd759

Authored by Imanol-Mikel Barba Sabariego
1 parent 00938948

Added stat code

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