📄 d2ladder.c
字号:
/* * Copyright (C) 2001 sousou (liupeng.cs@263.net) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "common/setup_before.h"#include "setup.h"#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#include <stdio.h>#include <errno.h>#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif# ifdef HAVE_MEMORY_H# include <memory.h># endif#endif#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_SYS_FILE_H#include <sys/file.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#else# ifdef HAVE_SYS_FILE_H# include <sys/file.h># endif#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include "compat/rename.h"#include "d2ladder.h"#include "prefs.h"#include "common/tag.h"#include "common/list.h"#include "common/eventlog.h"#include "compat/strncasecmp.h"#include "compat/strerror.h"#include "d2cs/d2charfile.h"#include "common/xalloc.h"#include "common/setup_after.h"char * d2ladder_ladder_file = NULL;char * d2ladder_backup_file = NULL;t_d2ladderlist * d2ladder_list = NULL;unsigned long d2ladder_maxtype;int d2ladder_change_count=0;int d2ladder_need_rebuild = 0;char * XMLname = "d2ladder.xml";int d2ladderlist_init(void);int d2ladderlist_destroy(void);int d2ladder_empty(void);int d2ladder_initladderfile(void);t_d2ladder * d2ladderlist_find_type(unsigned int type);int d2ladder_check(void);int d2ladder_readladder(void);int d2ladder_insert(t_d2ladder * d2ladder,t_d2ladder_info * pcharladderinfo);int d2ladder_find_char_all(t_d2ladder * d2ladder, t_d2ladder_info * info);int d2ladder_find_pos(t_d2ladder * d2ladder, t_d2ladder_info * info);int d2ladder_update_info_and_pos(t_d2ladder * d2ladder, t_d2ladder_info * info, int oldpos, int newpos);int d2ladder_checksum(unsigned char const * data, unsigned int len,unsigned int offset);int d2ladder_checksum_set(void);int d2ladder_checksum_check(void);extern int d2ladder_update(t_d2ladder_info * pcharladderinfo){ t_d2ladder * d2ladder; unsigned short hardcore,expansion,status; unsigned char class; unsigned int ladder_overall_type,ladder_class_type; if (!pcharladderinfo->charname[0]) return 0; class=pcharladderinfo->class; status=pcharladderinfo->status; if (prefs_get_ladder_chars_only() && (!charstatus_get_ladder(status))) return -1; hardcore=charstatus_get_hardcore(status); expansion=charstatus_get_expansion(status); ladder_overall_type=0; if (!expansion && class> D2CHAR_CLASS_MAX ) return -1; if (expansion && class> D2CHAR_EXP_CLASS_MAX ) return -1; if (hardcore && expansion) { ladder_overall_type=D2LADDER_EXP_HC_OVERALL; } else if (!hardcore && expansion) { ladder_overall_type=D2LADDER_EXP_STD_OVERALL; } else if (hardcore && !expansion) { ladder_overall_type=D2LADDER_HC_OVERALL; } else if (!hardcore && !expansion) { ladder_overall_type=D2LADDER_STD_OVERALL; } ladder_class_type=ladder_overall_type + class+1; d2ladder=d2ladderlist_find_type(ladder_overall_type); if(d2ladder_insert(d2ladder,pcharladderinfo)==1) { d2ladder_change_count++; } d2ladder=d2ladderlist_find_type(ladder_class_type); if(d2ladder_insert(d2ladder,pcharladderinfo)==1) { d2ladder_change_count++; } return 0;}int d2ladder_initladderfile(void){ FILE * fdladder; t_d2ladderfile_ladderindex lhead[D2LADDER_MAXTYPE]; t_d2ladderfile_header fileheader; int start; unsigned long maxtype; t_d2ladderfile_ladderinfo emptydata; unsigned int i,j, number; maxtype=D2LADDER_MAXTYPE; start=sizeof(t_d2ladderfile_header)+sizeof(lhead); for(i=0;i<D2LADDER_MAXTYPE;i++) { bn_int_set(&lhead[i].type,i); bn_int_set(&lhead[i].offset,start); if( i==D2LADDER_HC_OVERALL || i==D2LADDER_STD_OVERALL || i==D2LADDER_EXP_HC_OVERALL || i==D2LADDER_EXP_STD_OVERALL) { number=D2LADDER_OVERALL_MAXNUM; } else if((i>D2LADDER_HC_OVERALL && i<=D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1) || (i>D2LADDER_STD_OVERALL && i<=D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1) || (i>D2LADDER_EXP_HC_OVERALL && i<=D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1) || (i>D2LADDER_EXP_STD_OVERALL && i<=D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1)) { number=D2LADDER_MAXNUM; } else { number=0; } bn_int_set(&lhead[i].number,number); start += number*sizeof(emptydata); } memset(&emptydata,0,sizeof(emptydata)); if (!d2ladder_ladder_file) return -1; fdladder=fopen(d2ladder_ladder_file,"wb"); if(fdladder) { bn_int_set(&fileheader.maxtype,maxtype); bn_int_set(&fileheader.checksum,0); fwrite(&fileheader,1,sizeof(fileheader),fdladder); fwrite(lhead,1,sizeof(lhead),fdladder); for(i=0;i<maxtype;i++) { for(j=0;j<bn_int_get(lhead[i].number);j++) { fwrite(&emptydata,1,sizeof(emptydata),fdladder); } } fclose(fdladder); d2ladder_checksum_set(); } else { eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file); return -1; } return 0;}int d2ladder_find_pos(t_d2ladder * d2ladder, t_d2ladder_info * info){ int i; if (!d2ladder || !info) return -1; // only allow if the experience threshold is reached if (info->experience < prefs_get_ladderupdate_threshold()) return -1; i=d2ladder->len; while (i--) { if (d2ladder->info[i].experience > info->experience) { if (strncasecmp(d2ladder->info[i].charname,info->charname, MAX_CHARNAME_LEN)) { i++; } break; } if (i<=0) break; } return i;}int d2ladder_insert(t_d2ladder * d2ladder,t_d2ladder_info * info){ int oldpos, newpos; newpos=d2ladder_find_pos(d2ladder,info); /* we currectly do nothing when character is being kick out of ladder for simple */ /* if (newpos<0 || newpos >= d2ladder->len) return 0; */ oldpos=d2ladder_find_char_all(d2ladder,info); return d2ladder_update_info_and_pos(d2ladder,info,oldpos,newpos);}int d2ladder_find_char_all(t_d2ladder * d2ladder, t_d2ladder_info * info){ int i; t_d2ladder_info * ladderdata; if (!d2ladder || !info) return -1; ladderdata=d2ladder->info; if (!ladderdata) return -1; i=d2ladder->len; while (i--) { if (!strncasecmp(ladderdata[i].charname,info->charname,MAX_CHARNAME_LEN)) return i; } return -1;}int d2ladder_update_info_and_pos(t_d2ladder * d2ladder, t_d2ladder_info * info, int oldpos, int newpos){ int i; int direction; int outflag; t_d2ladder_info * ladderdata; if (!d2ladder || !info) return -1; ladderdata=d2ladder->info; if (!ladderdata) return -1; /* character not in ladder before */ outflag=0; if (oldpos < 0 || oldpos >= (signed)d2ladder->len) { oldpos = d2ladder->len-1; } if (newpos < 0 || newpos >= (signed)d2ladder->len) { newpos = d2ladder->len-1; outflag = 1; } if ((oldpos == (signed)d2ladder->len -1) && outflag) { return 0; } if (newpos > oldpos && !outflag ) newpos--; direction = (newpos > oldpos)? 1: -1; for (i=oldpos; i!=newpos; i+=direction) { ladderdata[i] = ladderdata[i+direction]; } ladderdata[i]=*info; return 1;}extern int d2ladder_rebuild(void){ d2ladder_empty(); d2ladder_need_rebuild = 0; return 0;}int d2ladder_check(void){ if (!d2ladder_ladder_file) return -1; if (!d2ladder_backup_file) return -1; if(d2ladder_checksum_check()!=1) { eventlog(eventlog_level_error,__FUNCTION__,"ladder file checksum error,try to use backup file"); if (p_rename(d2ladder_backup_file,d2ladder_ladder_file)==-1) { eventlog(eventlog_level_error,__FUNCTION__,"error rename %s to %s", d2ladder_backup_file,d2ladder_ladder_file); } if(d2ladder_checksum_check()!=1) { eventlog(eventlog_level_error,__FUNCTION__,"ladder backup file checksum error,rebuild ladder"); if (d2ladder_initladderfile()<0) return -1; else { d2ladder_need_rebuild=1; return 0; } } } return 1;}t_d2ladder * d2ladderlist_find_type(unsigned int type){ t_d2ladder * d2ladder; t_elem const * elem; if (!d2ladder_list) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL d2ladder_list"); return NULL; } LIST_TRAVERSE_CONST(d2ladder_list,elem) { if (!(d2ladder=elem_get_data(elem))) continue; if (d2ladder->type==type) return d2ladder; } eventlog(eventlog_level_error,__FUNCTION__,"could not find type %d in d2ladder_list",type); return NULL;}extern int d2dbs_d2ladder_init(void){ d2ladder_change_count=0; d2ladder_maxtype=0; d2ladder_ladder_file=xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+ strlen(LADDER_FILE_PREFIX)+1+strlen(CLIENTTAG_DIABLO2DV)+1+10); d2ladder_backup_file=xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+ strlen(LADDER_BACKUP_PREFIX)+1+strlen(CLIENTTAG_DIABLO2DV)+1+10); sprintf(d2ladder_ladder_file,"%s/%s.%s",d2dbs_prefs_get_ladder_dir(),\ LADDER_FILE_PREFIX,CLIENTTAG_DIABLO2DV); sprintf(d2ladder_backup_file,"%s/%s.%s",d2dbs_prefs_get_ladder_dir(),\ LADDER_BACKUP_PREFIX,CLIENTTAG_DIABLO2DV); if (d2ladderlist_init()<0) { return -1; } if(d2ladder_check()<0) { eventlog(eventlog_level_error,__FUNCTION__,"ladder file checking error"); return -1; } if (d2ladder_readladder()<0) { return -1; } if (d2ladder_need_rebuild) d2ladder_rebuild(); d2ladder_saveladder(); return 0;}int d2ladderlist_init(void){ t_d2ladder * d2ladder; unsigned int i; if (!d2ladder_ladder_file) return -1; d2ladder_list=list_create(); d2ladder_maxtype=D2LADDER_MAXTYPE; for (i=0;i<d2ladder_maxtype;i++) { d2ladder=xmalloc(sizeof(t_d2ladder)); d2ladder->type=i; d2ladder->info=NULL; d2ladder->len=0; list_append_data(d2ladder_list,d2ladder); } return 0;}int d2ladder_readladder(void){ t_d2ladder * d2ladder; t_d2ladderfile_header fileheader; FILE * fdladder; t_d2ladderfile_ladderindex * lhead; t_d2ladderfile_ladderinfo * ldata; t_d2ladder_info * info; t_d2ladder_info temp; long leftsize,blocksize; unsigned int laddertype; unsigned int tempmaxtype; int readlen; unsigned int i, number; if (!d2ladder_ladder_file) return -1; fdladder=fopen(d2ladder_ladder_file,"rb"); if(!fdladder) { eventlog(eventlog_level_error,__FUNCTION__,"canot open ladder file"); return -1; } fseek(fdladder,0,SEEK_END); leftsize=ftell(fdladder); rewind(fdladder); blocksize=sizeof(fileheader) ; if (leftsize<blocksize) { eventlog(eventlog_level_error,__FUNCTION__,"file size error"); fclose(fdladder); return -1; } readlen=fread(&fileheader,1,sizeof(fileheader),fdladder); if (readlen<=0) { eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno)); fclose(fdladder); return -1; } tempmaxtype=bn_int_get(fileheader.maxtype); leftsize-=blocksize; if(tempmaxtype>D2LADDER_MAXTYPE) { eventlog(eventlog_level_error,__FUNCTION__,"ladder type > D2LADDER_MAXTYPE error"); fclose(fdladder); return -1; } d2ladder_maxtype=tempmaxtype; blocksize=d2ladder_maxtype*sizeof(*lhead); if (leftsize < blocksize ) { eventlog(eventlog_level_error,__FUNCTION__,"file size error"); fclose(fdladder); return -1; } lhead=xmalloc(blocksize); readlen=fread(lhead,1,d2ladder_maxtype*sizeof(*lhead),fdladder); if (readlen<=0) { eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno)); xfree(lhead); fclose(fdladder); return -1; } leftsize-=blocksize; blocksize=0; for(i=0;i<d2ladder_maxtype;i++) { blocksize+=bn_int_get(lhead[i].number)*sizeof(*ldata); } if (leftsize < blocksize ) { eventlog(eventlog_level_error,__FUNCTION__,"file size error"); xfree(lhead); fclose(fdladder); return -1; } for(laddertype=0;laddertype<d2ladder_maxtype;laddertype++) { number= bn_int_get(lhead[laddertype].number); if(number<=0) continue; d2ladder=d2ladderlist_find_type(laddertype); if (!d2ladder) { eventlog(eventlog_level_error,__FUNCTION__,"could not find ladder type %d",laddertype); continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -