📄 d2ladder.c
字号:
ldata=xmalloc(number*sizeof(*ldata)); info=xmalloc(number * sizeof(*info)); memset(info,0,number * sizeof(*info)); fseek(fdladder,bn_int_get(lhead[laddertype].offset),SEEK_SET); readlen=fread(ldata,1,number*sizeof(*ldata),fdladder); if (readlen<=0) { eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno)); xfree(ldata); xfree(info); continue; } d2ladder->info=info; d2ladder->len=number; for (i=0; i< number; i++) { if (!ldata[i].charname[0]) continue; temp.experience=bn_int_get(ldata[i].experience); temp.status=bn_short_get(ldata[i].status); temp.level=bn_byte_get(ldata[i].level); temp.class=bn_byte_get(ldata[i].class); strncpy(temp.charname,ldata[i].charname,sizeof(info[i].charname)); if (d2ladder_update_info_and_pos(d2ladder,&temp, d2ladder_find_char_all(d2ladder,&temp), d2ladder_find_pos(d2ladder,&temp))==1) { d2ladder_change_count++; } } xfree(ldata); } leftsize-=blocksize; xfree(lhead); fclose(fdladder); return 0;}extern int d2dbs_d2ladder_destroy(void){ unsigned int i; t_d2ladder * d2ladder; d2ladder_saveladder(); for (i=0;i<d2ladder_maxtype;i++) { d2ladder=d2ladderlist_find_type(i); if(d2ladder) { if(d2ladder->info) xfree(d2ladder->info); d2ladder->info=NULL; d2ladder->len=0; } } d2ladderlist_destroy(); if (d2ladder_ladder_file) { xfree(d2ladder_ladder_file); d2ladder_ladder_file=NULL; } if (d2ladder_backup_file) { xfree(d2ladder_backup_file); d2ladder_backup_file=NULL; } return 0;}int d2ladderlist_destroy(void){ t_d2ladder * d2ladder; t_elem * elem; if (!d2ladder_list) return -1; LIST_TRAVERSE(d2ladder_list,elem) { if (!(d2ladder=elem_get_data(elem))) continue; xfree(d2ladder); list_remove_elem(d2ladder_list,&elem); } list_destroy(d2ladder_list); return 0;}int d2ladder_empty(void){ unsigned int i; t_d2ladder * d2ladder; for (i=0;i<d2ladder_maxtype;i++) { d2ladder=d2ladderlist_find_type(i); if(d2ladder) { memset(d2ladder->info,0,d2ladder->len * sizeof(*d2ladder->info)); } } return 0;}const char * get_prefix(int type, int status, int class){ int difficulty; static char prefix [4][4][2][16] = {{{"",""},{"",""},{"",""},{"",""}}, {{"Count" ,"Countess"} , {"Sir","Dame"}, {"Destroyer","Destroyer"} , {"Slayer","Slayer"}}, {{"Duke" ,"Duchess"} , {"Lord","Lady"}, {"Conqueror","Conqueror"} , {"Champion","Champion"}}, {{"King" ,"Queen"} , {"Baron","Baroness"}, {"Guardian","Guardian"} , {"Patriarch","Matriarch"}}}; static int sex[11] = {0,1,1,0,0,0,0,1,0,0,0}; difficulty = ((status >> 0x08) & 0x0f) / 5; return prefix[difficulty][type][sex[class]];}int d2ladder_print_XML(FILE *ladderstrm){ // modified version of d2ladder_print - changes done by jfro with a little help of aaron t_d2ladder * d2ladder; t_d2ladder_info * ldata; int overalltype,classtype; unsigned int i,type; char laddermode[4][20]={"Hardcore", "Standard","Expansion HC","Expansion" }; char charclass[11][12]={"OverAll", "Amazon", "Sorceress", "Necromancer", "Paladin",\ "Barbarian", "Druid", "Assassin", "","",""} ; fprintf(ladderstrm,"<?xml version=\"1.0\"?>\n<D2_ladders>\n"); for(type=0; type <d2ladder_maxtype; type++) { d2ladder=d2ladderlist_find_type(type); if (!d2ladder) continue; if(d2ladder->len<=0) continue; ldata=d2ladder->info; overalltype=0; classtype=0; if(type<= D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1) { overalltype=0 ; classtype=type-D2LADDER_HC_OVERALL; } else if(type >= D2LADDER_STD_OVERALL && type<= D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1) { overalltype=1; classtype=type-D2LADDER_STD_OVERALL; } else if(type >= D2LADDER_EXP_HC_OVERALL && type<= D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1) { overalltype=2; classtype=type-D2LADDER_EXP_HC_OVERALL; } else if(type >= D2LADDER_EXP_STD_OVERALL && type<= D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1) { overalltype=3; classtype=type-D2LADDER_EXP_STD_OVERALL ; } fprintf(ladderstrm,"<ladder>\n\t<type>%d</type>\n\t<mode>%s</mode>\n\t<class>%s</class>\n", type,laddermode[overalltype],charclass[classtype]); for(i=0; i<d2ladder->len; i++) { if ((ldata[i].charname != NULL) && (ldata[i].charname[0] != '\0')) { fprintf(ladderstrm,"\t<char>\n\t\t<rank>%2d</rank>\n\t\t<name>%s</name>\n\t\t<level>%2d</level>\n", i+1,ldata[i].charname,ldata[i].level); fprintf(ladderstrm,"\t\t<experience>%u</experience>\n\t\t<class>%s</class>\n", ldata[i].experience,charclass[ldata[i].class+1]); fprintf(ladderstrm,"\t\t<prefix>%s</prefix>\n", get_prefix(overalltype,ldata[i].status,ldata[i].class+1)); if (((ldata[i].status) & (D2CHARINFO_STATUS_FLAG_DEAD | D2CHARINFO_STATUS_FLAG_HARDCORE)) == (D2CHARINFO_STATUS_FLAG_DEAD | D2CHARINFO_STATUS_FLAG_HARDCORE)) fprintf(ladderstrm,"\t\t<status>dead</status>\n\t</char>\n"); else fprintf(ladderstrm,"\t\t<status>alive</status>\n\t</char>\n"); } } fprintf(ladderstrm,"</ladder>\n"); fflush(ladderstrm); } fprintf(ladderstrm,"</D2_ladders>\n"); return 0;}extern int d2ladder_saveladder(void){ t_d2ladderfile_ladderindex lhead[D2LADDER_MAXTYPE]; t_d2ladderfile_header fileheader; FILE * fdladder; int start; unsigned int i,j, number; t_d2ladder * d2ladder; t_d2ladderfile_ladderinfo * ldata; char * XMLfilename; FILE * XMLfile;/* if(!d2ladder_change_count) { eventlog(eventlog_level_debug,__FUNCTION__,"ladder data unchanged, skip saving"); return 0; }*/ start=sizeof(fileheader)+sizeof(lhead); for(i=0;i<D2LADDER_MAXTYPE;i++) { d2ladder=d2ladderlist_find_type(i); bn_int_set(&lhead[i].type,d2ladder->type); bn_int_set(&lhead[i].offset,start); bn_int_set(&lhead[i].number,d2ladder->len); start+=d2ladder->len*sizeof(*ldata); } if (!d2ladder_ladder_file) return -1; if (!d2ladder_backup_file) return -1; if(d2ladder_checksum_check()==1) { eventlog(eventlog_level_info,__FUNCTION__,"backup ladder file"); if (p_rename(d2ladder_ladder_file,d2ladder_backup_file)==-1) { eventlog(eventlog_level_warn,__FUNCTION__,"error rename %s to %s", d2ladder_ladder_file, d2ladder_backup_file); } } fdladder=fopen(d2ladder_ladder_file,"wb"); if(!fdladder) { eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file); return -1; } // aaron: add extra output for XML ladder here ---> if (d2dbs_prefs_get_XML_output_ladder()) { XMLfilename = xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+strlen(XMLname)+1); sprintf(XMLfilename,"%s/%s",d2dbs_prefs_get_ladder_dir(),XMLname); if (!(XMLfile = fopen(XMLfilename,"w"))) { eventlog(eventlog_level_error,__FUNCTION__,"could not open XML ladder file for output"); } else { d2ladder_print_XML(XMLfile); fclose(XMLfile); xfree(XMLfilename); } } // <--- bn_int_set(&fileheader.maxtype,d2ladder_maxtype); bn_int_set(&fileheader.checksum,0); fwrite(&fileheader,1,sizeof(fileheader),fdladder); fwrite(lhead,1,sizeof(lhead),fdladder); for(i=0;i<d2ladder_maxtype;i++) { number=bn_int_get(lhead[i].number); if(number<=0) continue; d2ladder=d2ladderlist_find_type(i); ldata=xmalloc(number * sizeof(*ldata)); memset(ldata,0,number * sizeof(*ldata)); for (j=0; j< number; j++) { bn_int_set(&ldata[j].experience,d2ladder->info[j].experience); bn_short_set(&ldata[j].status, d2ladder->info[j].status); bn_byte_set(&ldata[j].level, d2ladder->info[j].level); bn_byte_set(&ldata[j].class, d2ladder->info[j].class); strncpy(ldata[j].charname,d2ladder->info[j].charname,sizeof(ldata[j].charname)); } fwrite(ldata,1,number*sizeof(*ldata),fdladder); xfree(ldata); } fclose(fdladder); d2ladder_checksum_set(); eventlog(eventlog_level_info,__FUNCTION__,"ladder file saved (%d changes)",d2ladder_change_count); d2ladder_change_count=0; return 0;}int d2ladder_print(FILE *ladderstrm){ t_d2ladder * d2ladder; t_d2ladder_info * ldata; unsigned int i,type; int overalltype,classtype; char laddermode[4][20]={"Hardcore", "Standard","Expansion HC","Expansion" }; char charclass[11][12]={"OverAll", "Amazon", "Sorceress", "Necromancer", "Paladin",\ "Barbarian", "Druid", "Assassin", "","",""} ; for(type=0; type <d2ladder_maxtype; type++) { d2ladder=d2ladderlist_find_type(type); if (!d2ladder) continue; if(d2ladder->len<=0) continue; ldata=d2ladder->info; overalltype=0; classtype=0; if(type <= D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1) { overalltype=0 ; classtype=type-D2LADDER_HC_OVERALL; } else if (type >= D2LADDER_STD_OVERALL && type<= D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1) { overalltype=1; classtype=type-D2LADDER_STD_OVERALL; } else if (type >= D2LADDER_EXP_HC_OVERALL && type<= D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1) { overalltype=2; classtype=type-D2LADDER_EXP_HC_OVERALL; } else if (type >= D2LADDER_EXP_STD_OVERALL && type<= D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1) { overalltype=3; classtype=type- D2LADDER_EXP_STD_OVERALL ; } fprintf(ladderstrm,"ladder type %d %s %s\n",type,laddermode[overalltype],charclass[classtype]); fprintf(ladderstrm,"************************************************************************\n"); fprintf(ladderstrm,"No character name level exp status title class \n"); for(i=0; i<d2ladder->len; i++) { fprintf(ladderstrm,"NO.%2d %-16s %2d %10d %2X %1X %s\n", i+1, ldata[i].charname, ldata[i].level, ldata[i].experience, ldata[i].status, 1, charclass[ldata[i].class+1]); } fprintf(ladderstrm,"************************************************************************\n"); fflush(ladderstrm); } return 0;}int d2ladder_checksum(unsigned char const * data, unsigned int len,unsigned int offset){ int checksum; unsigned int i; unsigned int ch; if (!data) return 0; checksum=0; for (i=0; i<len; i++) { ch=data[i]; if (i>=offset && i<offset+sizeof(int)) ch=0; ch+=(checksum<0); checksum=2*checksum+ch; } return checksum;}int d2ladder_checksum_set(void){ FILE * fdladder; off_t filesize; int curlen,readlen,len; unsigned char * buffer; bn_int checksum; if (!d2ladder_ladder_file) return -1; fdladder=fopen(d2ladder_ladder_file,"r+b"); if(!fdladder) { eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file); return -1; } fseek(fdladder,0,SEEK_END); filesize=ftell(fdladder); rewind(fdladder); if(filesize==(off_t)-1) { eventlog(eventlog_level_error,__FUNCTION__,"lseek() error in ladder file %s",d2ladder_ladder_file); fclose(fdladder); return -1; } if(filesize<(signed)sizeof(t_d2ladderfile_header)) { eventlog(eventlog_level_error,__FUNCTION__,"ladder file size error :%s",d2ladder_ladder_file); fclose(fdladder); return -1; } buffer=xmalloc(filesize); curlen=0; while(curlen<filesize) { if(filesize-curlen > 2000) len = 2000; else len = filesize-curlen; readlen=fread(buffer+curlen,1,len,fdladder); if (readlen<=0) { xfree(buffer); fclose(fdladder); eventlog(eventlog_level_error,__FUNCTION__,"got bad save file or read error(read:%s)",pstrerror(errno)); return -1; } curlen+=readlen; } bn_int_set(&checksum,d2ladder_checksum(buffer,filesize,LADDERFILE_CHECKSUM_OFFSET)); fseek(fdladder,LADDERFILE_CHECKSUM_OFFSET,SEEK_SET); fwrite(&checksum,1,sizeof(checksum),fdladder); xfree(buffer); fclose(fdladder); return 0;}int d2ladder_checksum_check(void){ FILE * fdladder; off_t filesize; int curlen,readlen,len; unsigned char * buffer; int checksum,oldchecksum; t_d2ladderfile_header * header; if (!d2ladder_ladder_file) return -1; fdladder=fopen(d2ladder_ladder_file,"rb"); if(!fdladder) { eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file); return -1; } fseek(fdladder,0,SEEK_END); filesize=ftell(fdladder); rewind(fdladder); if(filesize==(off_t)-1) { eventlog(eventlog_level_error,__FUNCTION__,"lseek() error in ladder file %s",d2ladder_ladder_file); fclose(fdladder); return -1; } if(filesize<(signed)sizeof(t_d2ladderfile_header)) { eventlog(eventlog_level_error,__FUNCTION__,"ladder file size error :%s",d2ladder_ladder_file); fclose(fdladder); return -1; } buffer=xmalloc(filesize); header=(t_d2ladderfile_header *)buffer; curlen=0; while(curlen<filesize) { if(filesize-curlen > 2000) len = 2000; else len = filesize-curlen; readlen=fread(buffer+curlen,1,len,fdladder); if (readlen<=0) { xfree(buffer); fclose(fdladder); eventlog(eventlog_level_error,__FUNCTION__,"got bad save file or read error(read:%s)",pstrerror(errno)); return -1; } curlen+=readlen; } fclose(fdladder); oldchecksum=bn_int_get(header->checksum); checksum=d2ladder_checksum(buffer,filesize,LADDERFILE_CHECKSUM_OFFSET); xfree(buffer); if(oldchecksum==checksum) { eventlog(eventlog_level_info,__FUNCTION__,"ladder file check pass (checksum=0x%X)",checksum); return 1; } else { eventlog(eventlog_level_debug,__FUNCTION__,"ladder file checksum mismatch 0x%X - 0x%X",oldchecksum, checksum); return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -