static int d2charinfo_init(t_d2charinfo_file * chardata, char const * account, char const * charname, unsigned char classs, unsigned short status) { unsigned int i; time_t now; now=time(NULL); bn_int_set(&chardata->header.magicword,D2CHARINFO_MAGICWORD); bn_int_set(&chardata->header.version,D2CHARINFO_VERSION); bn_int_set(&chardata->header.create_time,now); bn_int_set(&chardata->header.last_time,now); bn_int_set(&chardata->header.total_play_time,0); memset(chardata->header.charname, 0,MAX_CHARNAME_LEN); strncpy(chardata->header.charname,charname,MAX_CHARNAME_LEN); memset(chardata->header.account, 0,MAX_ACCTNAME_LEN); strncpy(chardata->header.account,account,MAX_ACCTNAME_LEN); memset(chardata->header.realmname, 0,MAX_REALMNAME_LEN); strncpy(chardata->header.realmname,prefs_get_realmname(),MAX_REALMNAME_LEN); bn_int_set(&chardata->header.checksum,0); for (i=0; i<NELEMS(chardata->header.reserved); i++) { bn_int_set(&chardata->header.reserved[i],0); } bn_int_set(&chardata->summary.charlevel,1); bn_int_set(&chardata->summary.experience,0); bn_int_set(&chardata->summary.charclass,classs); bn_int_set(&chardata->summary.charstatus,status); memset(chardata->portrait.gfx,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.gfx)); memset(chardata->portrait.color,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.color)); memset(chardata->portrait.u2,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.u2)); memset(chardata->portrait.u1,D2CHARINFO_PORTRAIT_MASK,sizeof(chardata->portrait.u1)); memset(chardata->pad,0,sizeof(chardata->pad)); bn_short_set(&chardata->portrait.header,D2CHARINFO_PORTRAIT_HEADER); bn_byte_set(&chardata->portrait.status,status|D2CHARINFO_PORTRAIT_MASK); bn_byte_set(&chardata->portrait.classs,classs+1); bn_byte_set(&chardata->portrait.level,1); if (charstatus_get_ladder(status)) bn_byte_set(&chardata->portrait.ladder, 1); else bn_byte_set(&chardata->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE); bn_byte_set(&chardata->portrait.end,'\0'); memset(chardata->pad,0,sizeof(chardata->pad)); return 0; }
int main(int argc, char **argv) { FILE *fp; unsigned int checksum; unsigned int size; unsigned char status; if (argc!=2) { printf("%s <charsave>\n", argv[0]); return 0; } fp = fopen(argv[1], "rb+"); if (!fp) { printf("failed open file\n"); return -1; } size = fread(buf, 1, sizeof(buf), fp); if (!feof(fp)) { printf("error reading file\n"); fclose(fp); return -2; } if (buf[D2CHARSAVE_VERSION_OFFSET]<0x5c) { printf("wrong version number\n"); fclose(fp); return -3; } status = buf[D2CHARSAVE_STATUS_OFFSET_109]; charstatus_switch_ladder(status); buf[D2CHARSAVE_STATUS_OFFSET_109] = status; checksum = d2charsave_checksum(buf, size, D2CHARSAVE_CHECKSUM_OFFSET); *((unsigned int*)(buf+D2CHARSAVE_CHECKSUM_OFFSET)) = checksum; fseek(fp, 0, SEEK_SET); if (fwrite(buf, 1, size, fp)!=size) { printf("error writing save file\n"); fclose(fp); return -4; } fclose(fp); if (charstatus_get_ladder(status)) printf("set to LADDER char.\n"); else printf("set to none-LADDER char.\n"); return 0; }
extern unsigned int d2charinfo_get_ladder(t_d2charinfo_summary const * charinfo) { ASSERT(charinfo,0); return charstatus_get_ladder(bn_int_get(charinfo->charstatus)); }
extern int d2charinfo_load(char const * account, char const * charname, t_d2charinfo_file * data) { char * file; int size, ladder_time; if (d2char_check_charname(charname)<0) { eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname); return -1; } if (d2char_check_acctname(account)<0) { eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account); return -1; } file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1); d2char_get_infofile_name(file,account,charname); size=sizeof(t_d2charinfo_file); if (file_read(file,data,&size)<0) { eventlog(eventlog_level_error,__FUNCTION__,"error loading character file %s",file); xfree(file); return -1; } if (size!=sizeof(t_d2charinfo_file)) { eventlog(eventlog_level_error,__FUNCTION__,"got bad charinfo file %s (length %d)",charname,size); xfree(file); return -1; } d2char_portrait_init(&data->portrait); if (d2charinfo_check(data) < 0) { xfree(file); return -1; } if (!(charstatus_get_ladder(bn_int_get(data->summary.charstatus)))) { bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE); xfree(file); return 0; } ladder_time = prefs_get_ladder_start_time(); if ((ladder_time > 0) && bn_int_get(data->header.create_time) < ladder_time) { char buffer[MAX_SAVEFILE_SIZE]; unsigned int status_offset; unsigned char status; unsigned int charstatus; unsigned int size; unsigned int version; unsigned int checksum; FILE * fp; eventlog(eventlog_level_info,__FUNCTION__,"%s(*%s) was created in old ladder season, set to non-ladder", charname, account); if (!(fp=fopen(file,"wb"))) { eventlog(eventlog_level_error,__FUNCTION__,"charinfo file \"%s\" does not exist for account \"%s\"",file,account); xfree(file); return 0; } xfree(file); charstatus = bn_int_get(data->summary.charstatus); charstatus_set_ladder(charstatus, 0); bn_int_set(&data->summary.charstatus, charstatus); status=bn_byte_get(data->portrait.status); charstatus_set_ladder(status,0); bn_byte_set(&data->portrait.status,status); bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE); if (fwrite(data,1,sizeof(*data),fp)!=sizeof(*data)) { eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno)); fclose(fp); return 0; } fclose(fp); file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1); d2char_get_savefile_name(file,charname); if (!(fp=fopen(file,"rb+"))) { eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno)); xfree(file); return 0; } xfree(file); size=fread(buffer,1,sizeof(buffer),fp); if (!feof(fp)) { eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno)); fclose(fp); return 0; } version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET); if (version>=0x5C) { status_offset=D2CHARSAVE_STATUS_OFFSET_109; } else { status_offset=D2CHARSAVE_STATUS_OFFSET; } status=bn_byte_get(buffer+status_offset); charstatus_set_ladder(status,0); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */ bn_byte_set((bn_byte *)(buffer+status_offset),status); if (version>=0x5C) { checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET); bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum); } fseek(fp,0,SEEK_SET); if (fwrite(buffer,1,size,fp)!=size) { eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno)); fclose(fp); return 0; } fclose(fp); } else { bn_byte_set(&data->portrait.ladder, 1); xfree(file); } return 0; }