| 1 |
/*
|
| 2 |
* Copyright (C) 2001 sousou (liupeng.cs@263.net)
|
| 3 |
*
|
| 4 |
* This program is free software; you can redistribute it and/or
|
| 5 |
* modify it under the terms of the GNU General Public License
|
| 6 |
* as published by the Free Software Foundation; either version 2
|
| 7 |
* of the License, or (at your option) any later version.
|
| 8 |
*
|
| 9 |
* This program is distributed in the hope that it will be useful,
|
| 10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
* GNU General Public License for more details.
|
| 13 |
*
|
| 14 |
* You should have received a copy of the GNU General Public License
|
| 15 |
* along with this program; if not, write to the Free Software
|
| 16 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
| 17 |
*/
|
| 18 |
#include "common/setup_before.h"
|
| 19 |
#include "setup.h"
|
| 20 |
|
| 21 |
#ifdef HAVE_STDDEF_H
|
| 22 |
# include <stddef.h>
|
| 23 |
#else
|
| 24 |
# ifndef NULL
|
| 25 |
# define NULL ((void *)0)
|
| 26 |
# endif
|
| 27 |
#endif
|
| 28 |
#ifdef STDC_HEADERS
|
| 29 |
# include <stdlib.h>
|
| 30 |
#else
|
| 31 |
# ifdef HAVE_MALLOC_H
|
| 32 |
# include <malloc.h>
|
| 33 |
# endif
|
| 34 |
#endif
|
| 35 |
#include <stdio.h>
|
| 36 |
#include <errno.h>
|
| 37 |
#ifdef HAVE_STRING_H
|
| 38 |
# include <string.h>
|
| 39 |
#else
|
| 40 |
# ifdef HAVE_STRINGS_H
|
| 41 |
# include <strings.h>
|
| 42 |
# endif
|
| 43 |
# ifdef HAVE_MEMORY_H
|
| 44 |
# include <memory.h>
|
| 45 |
# endif
|
| 46 |
#endif
|
| 47 |
#ifdef HAVE_SYS_TYPES_H
|
| 48 |
# include <sys/types.h>
|
| 49 |
#endif
|
| 50 |
#ifdef HAVE_SYS_STAT_H
|
| 51 |
# include <sys/stat.h>
|
| 52 |
#endif
|
| 53 |
#ifdef HAVE_SYS_FILE_H
|
| 54 |
#include <sys/file.h>
|
| 55 |
#endif
|
| 56 |
#ifdef HAVE_FCNTL_H
|
| 57 |
# include <fcntl.h>
|
| 58 |
#else
|
| 59 |
# ifdef HAVE_SYS_FILE_H
|
| 60 |
# include <sys/file.h>
|
| 61 |
# endif
|
| 62 |
#endif
|
| 63 |
#ifdef HAVE_UNISTD_H
|
| 64 |
# include <unistd.h>
|
| 65 |
#endif
|
| 66 |
#include "compat/rename.h"
|
| 67 |
#include "d2ladder.h"
|
| 68 |
#include "prefs.h"
|
| 69 |
#include "common/tag.h"
|
| 70 |
#include "common/list.h"
|
| 71 |
#include "common/eventlog.h"
|
| 72 |
#include "compat/strncasecmp.h"
|
| 73 |
#include "compat/strerror.h"
|
| 74 |
#include "d2cs/d2charfile.h"
|
| 75 |
#include "common/xalloc.h"
|
| 76 |
#include "common/setup_after.h"
|
| 77 |
|
| 78 |
char * d2ladder_ladder_file = NULL;
|
| 79 |
char * d2ladder_backup_file = NULL;
|
| 80 |
|
| 81 |
t_d2ladderlist * d2ladder_list = NULL;
|
| 82 |
unsigned long d2ladder_maxtype;
|
| 83 |
int d2ladder_change_count=0;
|
| 84 |
int d2ladder_need_rebuild = 0;
|
| 85 |
char * XMLname = "d2ladder.xml";
|
| 86 |
|
| 87 |
|
| 88 |
int d2ladderlist_init(void);
|
| 89 |
int d2ladderlist_destroy(void);
|
| 90 |
int d2ladder_empty(void);
|
| 91 |
int d2ladder_initladderfile(void);
|
| 92 |
|
| 93 |
t_d2ladder * d2ladderlist_find_type(unsigned int type);
|
| 94 |
|
| 95 |
int d2ladder_check(void);
|
| 96 |
int d2ladder_readladder(void);
|
| 97 |
|
| 98 |
int d2ladder_insert(t_d2ladder * d2ladder,t_d2ladder_info * pcharladderinfo);
|
| 99 |
int d2ladder_find_char_all(t_d2ladder * d2ladder, t_d2ladder_info * info);
|
| 100 |
int d2ladder_find_pos(t_d2ladder * d2ladder, t_d2ladder_info * info);
|
| 101 |
int d2ladder_update_info_and_pos(t_d2ladder * d2ladder, t_d2ladder_info * info, int oldpos, int newpos);
|
| 102 |
int d2ladder_checksum(unsigned char const * data, unsigned int len,unsigned int offset);
|
| 103 |
int d2ladder_checksum_set(void);
|
| 104 |
int d2ladder_checksum_check(void);
|
| 105 |
|
| 106 |
|
| 107 |
extern int d2ladder_update(t_d2ladder_info * pcharladderinfo)
|
| 108 |
{
|
| 109 |
t_d2ladder * d2ladder;
|
| 110 |
unsigned short hardcore,expansion,status;
|
| 111 |
unsigned char class;
|
| 112 |
unsigned int ladder_overall_type,ladder_class_type;
|
| 113 |
|
| 114 |
if (!pcharladderinfo->charname[0]) return 0;
|
| 115 |
class=pcharladderinfo->class;
|
| 116 |
status=pcharladderinfo->status;
|
| 117 |
|
| 118 |
if (prefs_get_ladder_chars_only() && (!charstatus_get_ladder(status)))
|
| 119 |
return -1;
|
| 120 |
|
| 121 |
hardcore=charstatus_get_hardcore(status);
|
| 122 |
expansion=charstatus_get_expansion(status);
|
| 123 |
ladder_overall_type=0;
|
| 124 |
if (!expansion && class> D2CHAR_CLASS_MAX ) return -1;
|
| 125 |
if (expansion && class> D2CHAR_EXP_CLASS_MAX ) return -1;
|
| 126 |
if (hardcore && expansion) {
|
| 127 |
ladder_overall_type=D2LADDER_EXP_HC_OVERALL;
|
| 128 |
} else if (!hardcore && expansion) {
|
| 129 |
ladder_overall_type=D2LADDER_EXP_STD_OVERALL;
|
| 130 |
} else if (hardcore && !expansion) {
|
| 131 |
ladder_overall_type=D2LADDER_HC_OVERALL;
|
| 132 |
} else if (!hardcore && !expansion) {
|
| 133 |
ladder_overall_type=D2LADDER_STD_OVERALL;
|
| 134 |
}
|
| 135 |
|
| 136 |
ladder_class_type=ladder_overall_type + class+1;
|
| 137 |
|
| 138 |
d2ladder=d2ladderlist_find_type(ladder_overall_type);
|
| 139 |
if(d2ladder_insert(d2ladder,pcharladderinfo)==1) {
|
| 140 |
d2ladder_change_count++;
|
| 141 |
}
|
| 142 |
|
| 143 |
d2ladder=d2ladderlist_find_type(ladder_class_type);
|
| 144 |
if(d2ladder_insert(d2ladder,pcharladderinfo)==1) {
|
| 145 |
d2ladder_change_count++;
|
| 146 |
}
|
| 147 |
return 0;
|
| 148 |
}
|
| 149 |
|
| 150 |
int d2ladder_initladderfile(void)
|
| 151 |
{
|
| 152 |
FILE * fdladder;
|
| 153 |
t_d2ladderfile_ladderindex lhead[D2LADDER_MAXTYPE];
|
| 154 |
t_d2ladderfile_header fileheader;
|
| 155 |
int start;
|
| 156 |
unsigned long maxtype;
|
| 157 |
t_d2ladderfile_ladderinfo emptydata;
|
| 158 |
unsigned int i,j, number;
|
| 159 |
|
| 160 |
maxtype=D2LADDER_MAXTYPE;
|
| 161 |
start=sizeof(t_d2ladderfile_header)+sizeof(lhead);
|
| 162 |
for(i=0;i<D2LADDER_MAXTYPE;i++) {
|
| 163 |
bn_int_set(&lhead[i].type,i);
|
| 164 |
bn_int_set(&lhead[i].offset,start);
|
| 165 |
if( i==D2LADDER_HC_OVERALL ||
|
| 166 |
i==D2LADDER_STD_OVERALL ||
|
| 167 |
i==D2LADDER_EXP_HC_OVERALL ||
|
| 168 |
i==D2LADDER_EXP_STD_OVERALL) {
|
| 169 |
number=D2LADDER_OVERALL_MAXNUM;
|
| 170 |
} else if((i>D2LADDER_HC_OVERALL && i<=D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1) ||
|
| 171 |
(i>D2LADDER_STD_OVERALL && i<=D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1) ||
|
| 172 |
(i>D2LADDER_EXP_HC_OVERALL && i<=D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1) ||
|
| 173 |
(i>D2LADDER_EXP_STD_OVERALL && i<=D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1)) {
|
| 174 |
number=D2LADDER_MAXNUM;
|
| 175 |
} else {
|
| 176 |
number=0;
|
| 177 |
}
|
| 178 |
bn_int_set(&lhead[i].number,number);
|
| 179 |
start += number*sizeof(emptydata);
|
| 180 |
}
|
| 181 |
memset(&emptydata,0,sizeof(emptydata));
|
| 182 |
if (!d2ladder_ladder_file) return -1;
|
| 183 |
fdladder=fopen(d2ladder_ladder_file,"wb");
|
| 184 |
if(fdladder) {
|
| 185 |
bn_int_set(&fileheader.maxtype,maxtype);
|
| 186 |
bn_int_set(&fileheader.checksum,0);
|
| 187 |
fwrite(&fileheader,1,sizeof(fileheader),fdladder);
|
| 188 |
fwrite(lhead,1,sizeof(lhead),fdladder);
|
| 189 |
for(i=0;i<maxtype;i++) {
|
| 190 |
for(j=0;j<bn_int_get(lhead[i].number);j++) {
|
| 191 |
fwrite(&emptydata,1,sizeof(emptydata),fdladder);
|
| 192 |
}
|
| 193 |
}
|
| 194 |
fclose(fdladder);
|
| 195 |
d2ladder_checksum_set();
|
| 196 |
}
|
| 197 |
else {
|
| 198 |
eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file);
|
| 199 |
return -1;
|
| 200 |
}
|
| 201 |
return 0;
|
| 202 |
}
|
| 203 |
|
| 204 |
int d2ladder_find_pos(t_d2ladder * d2ladder, t_d2ladder_info * info)
|
| 205 |
{
|
| 206 |
int i;
|
| 207 |
|
| 208 |
if (!d2ladder || !info) return -1;
|
| 209 |
|
| 210 |
// only allow if the experience threshold is reached
|
| 211 |
if (info->experience < prefs_get_ladderupdate_threshold()) return -1;
|
| 212 |
|
| 213 |
i=d2ladder->len;
|
| 214 |
while (i--) {
|
| 215 |
if (d2ladder->info[i].experience > info->experience) {
|
| 216 |
if (strncasecmp(d2ladder->info[i].charname,info->charname, MAX_CHARNAME_LEN)) {
|
| 217 |
i++;
|
| 218 |
}
|
| 219 |
break;
|
| 220 |
}
|
| 221 |
if (i<=0) break;
|
| 222 |
}
|
| 223 |
return i;
|
| 224 |
}
|
| 225 |
|
| 226 |
|
| 227 |
int d2ladder_insert(t_d2ladder * d2ladder,t_d2ladder_info * info)
|
| 228 |
{
|
| 229 |
int oldpos, newpos;
|
| 230 |
|
| 231 |
newpos=d2ladder_find_pos(d2ladder,info);
|
| 232 |
/* we currectly do nothing when character is being kick out of ladder for simple */
|
| 233 |
/*
|
| 234 |
if (newpos<0 || newpos >= d2ladder->len) return 0;
|
| 235 |
*/
|
| 236 |
oldpos=d2ladder_find_char_all(d2ladder,info);
|
| 237 |
return d2ladder_update_info_and_pos(d2ladder,info,oldpos,newpos);
|
| 238 |
}
|
| 239 |
|
| 240 |
int d2ladder_find_char_all(t_d2ladder * d2ladder, t_d2ladder_info * info)
|
| 241 |
{
|
| 242 |
int i;
|
| 243 |
t_d2ladder_info * ladderdata;
|
| 244 |
|
| 245 |
if (!d2ladder || !info) return -1;
|
| 246 |
ladderdata=d2ladder->info;
|
| 247 |
if (!ladderdata) return -1;
|
| 248 |
i=d2ladder->len;
|
| 249 |
while (i--) {
|
| 250 |
if (!strncasecmp(ladderdata[i].charname,info->charname,MAX_CHARNAME_LEN)) return i;
|
| 251 |
}
|
| 252 |
return -1;
|
| 253 |
}
|
| 254 |
|
| 255 |
int d2ladder_update_info_and_pos(t_d2ladder * d2ladder, t_d2ladder_info * info, int oldpos, int newpos)
|
| 256 |
{
|
| 257 |
int i;
|
| 258 |
int direction;
|
| 259 |
int outflag;
|
| 260 |
t_d2ladder_info * ladderdata;
|
| 261 |
|
| 262 |
if (!d2ladder || !info) return -1;
|
| 263 |
ladderdata=d2ladder->info;
|
| 264 |
if (!ladderdata) return -1;
|
| 265 |
|
| 266 |
/* character not in ladder before */
|
| 267 |
outflag=0;
|
| 268 |
if (oldpos < 0 || oldpos >= (signed)d2ladder->len) {
|
| 269 |
oldpos = d2ladder->len-1;
|
| 270 |
}
|
| 271 |
if (newpos < 0 || newpos >= (signed)d2ladder->len) {
|
| 272 |
newpos = d2ladder->len-1;
|
| 273 |
outflag = 1;
|
| 274 |
}
|
| 275 |
if ((oldpos == (signed)d2ladder->len -1) && outflag) {
|
| 276 |
return 0;
|
| 277 |
}
|
| 278 |
if (newpos > oldpos && !outflag ) newpos--;
|
| 279 |
direction = (newpos > oldpos)? 1: -1;
|
| 280 |
for (i=oldpos; i!=newpos; i+=direction) {
|
| 281 |
ladderdata[i] = ladderdata[i+direction];
|
| 282 |
}
|
| 283 |
ladderdata[i]=*info;
|
| 284 |
return 1;
|
| 285 |
}
|
| 286 |
|
| 287 |
|
| 288 |
extern int d2ladder_rebuild(void)
|
| 289 |
{
|
| 290 |
d2ladder_empty();
|
| 291 |
d2ladder_need_rebuild = 0;
|
| 292 |
return 0;
|
| 293 |
}
|
| 294 |
|
| 295 |
int d2ladder_check(void)
|
| 296 |
{
|
| 297 |
if (!d2ladder_ladder_file) return -1;
|
| 298 |
if (!d2ladder_backup_file) return -1;
|
| 299 |
if(d2ladder_checksum_check()!=1) {
|
| 300 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder file checksum error,try to use backup file");
|
| 301 |
if (p_rename(d2ladder_backup_file,d2ladder_ladder_file)==-1) {
|
| 302 |
eventlog(eventlog_level_error,__FUNCTION__,"error rename %s to %s", d2ladder_backup_file,d2ladder_ladder_file);
|
| 303 |
}
|
| 304 |
if(d2ladder_checksum_check()!=1) {
|
| 305 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder backup file checksum error,rebuild ladder");
|
| 306 |
if (d2ladder_initladderfile()<0) return -1;
|
| 307 |
else {
|
| 308 |
d2ladder_need_rebuild=1;
|
| 309 |
return 0;
|
| 310 |
}
|
| 311 |
}
|
| 312 |
}
|
| 313 |
return 1;
|
| 314 |
}
|
| 315 |
|
| 316 |
|
| 317 |
t_d2ladder * d2ladderlist_find_type(unsigned int type)
|
| 318 |
{
|
| 319 |
t_d2ladder * d2ladder;
|
| 320 |
t_elem const * elem;
|
| 321 |
|
| 322 |
if (!d2ladder_list) {
|
| 323 |
eventlog(eventlog_level_error,__FUNCTION__,"got NULL d2ladder_list");
|
| 324 |
return NULL;
|
| 325 |
}
|
| 326 |
|
| 327 |
LIST_TRAVERSE_CONST(d2ladder_list,elem)
|
| 328 |
{
|
| 329 |
if (!(d2ladder=elem_get_data(elem))) continue;
|
| 330 |
if (d2ladder->type==type) return d2ladder;
|
| 331 |
}
|
| 332 |
eventlog(eventlog_level_error,__FUNCTION__,"could not find type %d in d2ladder_list",type);
|
| 333 |
return NULL;
|
| 334 |
}
|
| 335 |
|
| 336 |
extern int d2dbs_d2ladder_init(void)
|
| 337 |
{
|
| 338 |
d2ladder_change_count=0;
|
| 339 |
d2ladder_maxtype=0;
|
| 340 |
d2ladder_ladder_file=xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+
|
| 341 |
strlen(LADDER_FILE_PREFIX)+1+strlen(CLIENTTAG_DIABLO2DV)+1+10);
|
| 342 |
d2ladder_backup_file=xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+
|
| 343 |
strlen(LADDER_BACKUP_PREFIX)+1+strlen(CLIENTTAG_DIABLO2DV)+1+10);
|
| 344 |
sprintf(d2ladder_ladder_file,"%s/%s.%s",d2dbs_prefs_get_ladder_dir(),\
|
| 345 |
LADDER_FILE_PREFIX,CLIENTTAG_DIABLO2DV);
|
| 346 |
|
| 347 |
sprintf(d2ladder_backup_file,"%s/%s.%s",d2dbs_prefs_get_ladder_dir(),\
|
| 348 |
LADDER_BACKUP_PREFIX,CLIENTTAG_DIABLO2DV);
|
| 349 |
|
| 350 |
if (d2ladderlist_init()<0) {
|
| 351 |
return -1;
|
| 352 |
}
|
| 353 |
if(d2ladder_check()<0) {
|
| 354 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder file checking error");
|
| 355 |
return -1;
|
| 356 |
}
|
| 357 |
if (d2ladder_readladder()<0) {
|
| 358 |
return -1;
|
| 359 |
}
|
| 360 |
if (d2ladder_need_rebuild) d2ladder_rebuild();
|
| 361 |
d2ladder_saveladder();
|
| 362 |
return 0;
|
| 363 |
}
|
| 364 |
|
| 365 |
int d2ladderlist_init(void)
|
| 366 |
{
|
| 367 |
t_d2ladder * d2ladder;
|
| 368 |
unsigned int i;
|
| 369 |
|
| 370 |
|
| 371 |
if (!d2ladder_ladder_file) return -1;
|
| 372 |
d2ladder_list=list_create();
|
| 373 |
d2ladder_maxtype=D2LADDER_MAXTYPE;
|
| 374 |
for (i=0;i<d2ladder_maxtype;i++) {
|
| 375 |
d2ladder=xmalloc(sizeof(t_d2ladder));
|
| 376 |
d2ladder->type=i;
|
| 377 |
d2ladder->info=NULL;
|
| 378 |
d2ladder->len=0;
|
| 379 |
list_append_data(d2ladder_list,d2ladder);
|
| 380 |
}
|
| 381 |
return 0;
|
| 382 |
}
|
| 383 |
|
| 384 |
int d2ladder_readladder(void)
|
| 385 |
{
|
| 386 |
t_d2ladder * d2ladder;
|
| 387 |
t_d2ladderfile_header fileheader;
|
| 388 |
FILE * fdladder;
|
| 389 |
t_d2ladderfile_ladderindex * lhead;
|
| 390 |
t_d2ladderfile_ladderinfo * ldata;
|
| 391 |
t_d2ladder_info * info;
|
| 392 |
t_d2ladder_info temp;
|
| 393 |
long leftsize,blocksize;
|
| 394 |
unsigned int laddertype;
|
| 395 |
unsigned int tempmaxtype;
|
| 396 |
int readlen;
|
| 397 |
unsigned int i, number;
|
| 398 |
|
| 399 |
if (!d2ladder_ladder_file) return -1;
|
| 400 |
fdladder=fopen(d2ladder_ladder_file,"rb");
|
| 401 |
if(!fdladder) {
|
| 402 |
eventlog(eventlog_level_error,__FUNCTION__,"canot open ladder file");
|
| 403 |
return -1;
|
| 404 |
}
|
| 405 |
|
| 406 |
fseek(fdladder,0,SEEK_END);
|
| 407 |
leftsize=ftell(fdladder);
|
| 408 |
rewind(fdladder);
|
| 409 |
|
| 410 |
blocksize=sizeof(fileheader) ;
|
| 411 |
if (leftsize<blocksize) {
|
| 412 |
eventlog(eventlog_level_error,__FUNCTION__,"file size error");
|
| 413 |
fclose(fdladder);
|
| 414 |
return -1;
|
| 415 |
}
|
| 416 |
|
| 417 |
readlen=fread(&fileheader,1,sizeof(fileheader),fdladder);
|
| 418 |
if (readlen<=0) {
|
| 419 |
eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno));
|
| 420 |
fclose(fdladder);
|
| 421 |
return -1;
|
| 422 |
}
|
| 423 |
tempmaxtype=bn_int_get(fileheader.maxtype);
|
| 424 |
leftsize-=blocksize;
|
| 425 |
|
| 426 |
if(tempmaxtype>D2LADDER_MAXTYPE) {
|
| 427 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder type > D2LADDER_MAXTYPE error");
|
| 428 |
fclose(fdladder);
|
| 429 |
return -1;
|
| 430 |
}
|
| 431 |
d2ladder_maxtype=tempmaxtype;
|
| 432 |
|
| 433 |
blocksize=d2ladder_maxtype*sizeof(*lhead);
|
| 434 |
if (leftsize < blocksize ) {
|
| 435 |
eventlog(eventlog_level_error,__FUNCTION__,"file size error");
|
| 436 |
fclose(fdladder);
|
| 437 |
return -1;
|
| 438 |
}
|
| 439 |
|
| 440 |
lhead=xmalloc(blocksize);
|
| 441 |
readlen=fread(lhead,1,d2ladder_maxtype*sizeof(*lhead),fdladder);
|
| 442 |
if (readlen<=0) {
|
| 443 |
eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno));
|
| 444 |
xfree(lhead);
|
| 445 |
fclose(fdladder);
|
| 446 |
return -1;
|
| 447 |
}
|
| 448 |
leftsize-=blocksize;
|
| 449 |
|
| 450 |
blocksize=0;
|
| 451 |
for(i=0;i<d2ladder_maxtype;i++) {
|
| 452 |
blocksize+=bn_int_get(lhead[i].number)*sizeof(*ldata);
|
| 453 |
}
|
| 454 |
if (leftsize < blocksize ) {
|
| 455 |
eventlog(eventlog_level_error,__FUNCTION__,"file size error");
|
| 456 |
xfree(lhead);
|
| 457 |
fclose(fdladder);
|
| 458 |
return -1;
|
| 459 |
}
|
| 460 |
|
| 461 |
for(laddertype=0;laddertype<d2ladder_maxtype;laddertype++) {
|
| 462 |
number= bn_int_get(lhead[laddertype].number);
|
| 463 |
if(number<=0) continue;
|
| 464 |
d2ladder=d2ladderlist_find_type(laddertype);
|
| 465 |
if (!d2ladder) {
|
| 466 |
eventlog(eventlog_level_error,__FUNCTION__,"could not find ladder type %d",laddertype);
|
| 467 |
continue;
|
| 468 |
}
|
| 469 |
ldata=xmalloc(number*sizeof(*ldata));
|
| 470 |
info=xmalloc(number * sizeof(*info));
|
| 471 |
memset(info,0,number * sizeof(*info));
|
| 472 |
fseek(fdladder,bn_int_get(lhead[laddertype].offset),SEEK_SET);
|
| 473 |
readlen=fread(ldata,1,number*sizeof(*ldata),fdladder);
|
| 474 |
if (readlen<=0) {
|
| 475 |
eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,pstrerror(errno));
|
| 476 |
xfree(ldata);
|
| 477 |
xfree(info);
|
| 478 |
continue;
|
| 479 |
}
|
| 480 |
d2ladder->info=info;
|
| 481 |
d2ladder->len=number;
|
| 482 |
for (i=0; i< number; i++) {
|
| 483 |
if (!ldata[i].charname[0]) continue;
|
| 484 |
temp.experience=bn_int_get(ldata[i].experience);
|
| 485 |
temp.status=bn_short_get(ldata[i].status);
|
| 486 |
temp.level=bn_byte_get(ldata[i].level);
|
| 487 |
temp.class=bn_byte_get(ldata[i].class);
|
| 488 |
strncpy(temp.charname,ldata[i].charname,sizeof(info[i].charname));
|
| 489 |
if (d2ladder_update_info_and_pos(d2ladder,&temp,
|
| 490 |
d2ladder_find_char_all(d2ladder,&temp),
|
| 491 |
d2ladder_find_pos(d2ladder,&temp))==1) {
|
| 492 |
d2ladder_change_count++;
|
| 493 |
}
|
| 494 |
}
|
| 495 |
xfree(ldata);
|
| 496 |
}
|
| 497 |
leftsize-=blocksize;
|
| 498 |
|
| 499 |
xfree(lhead);
|
| 500 |
fclose(fdladder);
|
| 501 |
return 0;
|
| 502 |
}
|
| 503 |
|
| 504 |
extern int d2dbs_d2ladder_destroy(void)
|
| 505 |
{
|
| 506 |
unsigned int i;
|
| 507 |
t_d2ladder * d2ladder;
|
| 508 |
|
| 509 |
d2ladder_saveladder();
|
| 510 |
for (i=0;i<d2ladder_maxtype;i++) {
|
| 511 |
d2ladder=d2ladderlist_find_type(i);
|
| 512 |
if(d2ladder)
|
| 513 |
{
|
| 514 |
if(d2ladder->info)
|
| 515 |
xfree(d2ladder->info);
|
| 516 |
d2ladder->info=NULL;
|
| 517 |
d2ladder->len=0;
|
| 518 |
}
|
| 519 |
}
|
| 520 |
d2ladderlist_destroy();
|
| 521 |
if (d2ladder_ladder_file) {
|
| 522 |
xfree(d2ladder_ladder_file);
|
| 523 |
d2ladder_ladder_file=NULL;
|
| 524 |
}
|
| 525 |
if (d2ladder_backup_file) {
|
| 526 |
xfree(d2ladder_backup_file);
|
| 527 |
d2ladder_backup_file=NULL;
|
| 528 |
}
|
| 529 |
return 0;
|
| 530 |
}
|
| 531 |
|
| 532 |
int d2ladderlist_destroy(void)
|
| 533 |
{
|
| 534 |
t_d2ladder * d2ladder;
|
| 535 |
t_elem * elem;
|
| 536 |
|
| 537 |
if (!d2ladder_list) return -1;
|
| 538 |
LIST_TRAVERSE(d2ladder_list,elem)
|
| 539 |
{
|
| 540 |
if (!(d2ladder=elem_get_data(elem))) continue;
|
| 541 |
xfree(d2ladder);
|
| 542 |
list_remove_elem(d2ladder_list,&elem);
|
| 543 |
}
|
| 544 |
list_destroy(d2ladder_list);
|
| 545 |
return 0;
|
| 546 |
}
|
| 547 |
|
| 548 |
int d2ladder_empty(void)
|
| 549 |
{
|
| 550 |
unsigned int i;
|
| 551 |
t_d2ladder * d2ladder;
|
| 552 |
|
| 553 |
for (i=0;i<d2ladder_maxtype;i++) {
|
| 554 |
d2ladder=d2ladderlist_find_type(i);
|
| 555 |
if(d2ladder) {
|
| 556 |
memset(d2ladder->info,0,d2ladder->len * sizeof(*d2ladder->info));
|
| 557 |
}
|
| 558 |
}
|
| 559 |
return 0;
|
| 560 |
}
|
| 561 |
|
| 562 |
const char * get_prefix(int type, int status, int class)
|
| 563 |
{
|
| 564 |
int difficulty;
|
| 565 |
static char prefix [4][4][2][16] =
|
| 566 |
{{{"",""},{"",""},{"",""},{"",""}},
|
| 567 |
|
| 568 |
{{"Count" ,"Countess"} , {"Sir","Dame"},
|
| 569 |
{"Destroyer","Destroyer"} , {"Slayer","Slayer"}},
|
| 570 |
|
| 571 |
{{"Duke" ,"Duchess"} , {"Lord","Lady"},
|
| 572 |
{"Conqueror","Conqueror"} , {"Champion","Champion"}},
|
| 573 |
|
| 574 |
{{"King" ,"Queen"} , {"Baron","Baroness"},
|
| 575 |
{"Guardian","Guardian"} , {"Patriarch","Matriarch"}}};
|
| 576 |
|
| 577 |
static int sex[11] = {0,1,1,0,0,0,0,1,0,0,0};
|
| 578 |
|
| 579 |
difficulty = ((status >> 0x08) & 0x0f) / 5;
|
| 580 |
|
| 581 |
|
| 582 |
return prefix[difficulty][type][sex[class]];
|
| 583 |
}
|
| 584 |
|
| 585 |
int d2ladder_print_XML(FILE *ladderstrm)
|
| 586 |
{
|
| 587 |
// modified version of d2ladder_print - changes done by jfro with a little help of aaron
|
| 588 |
t_d2ladder * d2ladder;
|
| 589 |
t_d2ladder_info * ldata;
|
| 590 |
int overalltype,classtype;
|
| 591 |
unsigned int i,type;
|
| 592 |
char laddermode[4][20]={"Hardcore", "Standard","Expansion HC","Expansion" };
|
| 593 |
char charclass[11][12]={"OverAll", "Amazon", "Sorceress", "Necromancer", "Paladin",\
|
| 594 |
"Barbarian", "Druid", "Assassin", "","",""} ;
|
| 595 |
|
| 596 |
fprintf(ladderstrm,"<?xml version=\"1.0\"?>\n<D2_ladders>\n");
|
| 597 |
for(type=0; type <d2ladder_maxtype; type++) {
|
| 598 |
d2ladder=d2ladderlist_find_type(type);
|
| 599 |
if (!d2ladder)
|
| 600 |
continue;
|
| 601 |
if(d2ladder->len<=0)
|
| 602 |
continue;
|
| 603 |
ldata=d2ladder->info;
|
| 604 |
|
| 605 |
overalltype=0;
|
| 606 |
classtype=0;
|
| 607 |
|
| 608 |
if(type<= D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1)
|
| 609 |
{
|
| 610 |
overalltype=0 ;
|
| 611 |
classtype=type-D2LADDER_HC_OVERALL;
|
| 612 |
}
|
| 613 |
else if(type >= D2LADDER_STD_OVERALL && type<= D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1)
|
| 614 |
{
|
| 615 |
overalltype=1;
|
| 616 |
classtype=type-D2LADDER_STD_OVERALL;
|
| 617 |
}
|
| 618 |
else if(type >= D2LADDER_EXP_HC_OVERALL && type<= D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1)
|
| 619 |
{
|
| 620 |
overalltype=2;
|
| 621 |
classtype=type-D2LADDER_EXP_HC_OVERALL;
|
| 622 |
}
|
| 623 |
else if(type >= D2LADDER_EXP_STD_OVERALL && type<= D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1)
|
| 624 |
{
|
| 625 |
overalltype=3;
|
| 626 |
classtype=type-D2LADDER_EXP_STD_OVERALL ;
|
| 627 |
}
|
| 628 |
|
| 629 |
fprintf(ladderstrm,"<ladder>\n\t<type>%d</type>\n\t<mode>%s</mode>\n\t<class>%s</class>\n",
|
| 630 |
type,laddermode[overalltype],charclass[classtype]);
|
| 631 |
for(i=0; i<d2ladder->len; i++)
|
| 632 |
{
|
| 633 |
if ((ldata[i].charname != NULL) && (ldata[i].charname[0] != '\0'))
|
| 634 |
{
|
| 635 |
fprintf(ladderstrm,"\t<char>\n\t\t<rank>%2d</rank>\n\t\t<name>%s</name>\n\t\t<level>%2d</level>\n",
|
| 636 |
i+1,ldata[i].charname,ldata[i].level);
|
| 637 |
fprintf(ladderstrm,"\t\t<experience>%u</experience>\n\t\t<class>%s</class>\n",
|
| 638 |
ldata[i].experience,charclass[ldata[i].class+1]);
|
| 639 |
fprintf(ladderstrm,"\t\t<prefix>%s</prefix>\n",
|
| 640 |
get_prefix(overalltype,ldata[i].status,ldata[i].class+1));
|
| 641 |
if (((ldata[i].status) & (D2CHARINFO_STATUS_FLAG_DEAD | D2CHARINFO_STATUS_FLAG_HARDCORE)) ==
|
| 642 |
(D2CHARINFO_STATUS_FLAG_DEAD | D2CHARINFO_STATUS_FLAG_HARDCORE))
|
| 643 |
fprintf(ladderstrm,"\t\t<status>dead</status>\n\t</char>\n");
|
| 644 |
else
|
| 645 |
fprintf(ladderstrm,"\t\t<status>alive</status>\n\t</char>\n");
|
| 646 |
}
|
| 647 |
}
|
| 648 |
fprintf(ladderstrm,"</ladder>\n");
|
| 649 |
fflush(ladderstrm);
|
| 650 |
}
|
| 651 |
fprintf(ladderstrm,"</D2_ladders>\n");
|
| 652 |
return 0;
|
| 653 |
}
|
| 654 |
|
| 655 |
extern int d2ladder_saveladder(void)
|
| 656 |
{
|
| 657 |
t_d2ladderfile_ladderindex lhead[D2LADDER_MAXTYPE];
|
| 658 |
t_d2ladderfile_header fileheader;
|
| 659 |
FILE * fdladder;
|
| 660 |
int start;
|
| 661 |
unsigned int i,j, number;
|
| 662 |
t_d2ladder * d2ladder;
|
| 663 |
t_d2ladderfile_ladderinfo * ldata;
|
| 664 |
char * XMLfilename;
|
| 665 |
FILE * XMLfile;
|
| 666 |
|
| 667 |
/*
|
| 668 |
if(!d2ladder_change_count) {
|
| 669 |
eventlog(eventlog_level_debug,__FUNCTION__,"ladder data unchanged, skip saving");
|
| 670 |
return 0;
|
| 671 |
}
|
| 672 |
*/
|
| 673 |
start=sizeof(fileheader)+sizeof(lhead);
|
| 674 |
|
| 675 |
for(i=0;i<D2LADDER_MAXTYPE;i++) {
|
| 676 |
d2ladder=d2ladderlist_find_type(i);
|
| 677 |
bn_int_set(&lhead[i].type,d2ladder->type);
|
| 678 |
bn_int_set(&lhead[i].offset,start);
|
| 679 |
bn_int_set(&lhead[i].number,d2ladder->len);
|
| 680 |
start+=d2ladder->len*sizeof(*ldata);
|
| 681 |
}
|
| 682 |
|
| 683 |
if (!d2ladder_ladder_file) return -1;
|
| 684 |
if (!d2ladder_backup_file) return -1;
|
| 685 |
|
| 686 |
if(d2ladder_checksum_check()==1) {
|
| 687 |
eventlog(eventlog_level_info,__FUNCTION__,"backup ladder file");
|
| 688 |
if (p_rename(d2ladder_ladder_file,d2ladder_backup_file)==-1) {
|
| 689 |
eventlog(eventlog_level_warn,__FUNCTION__,"error rename %s to %s", d2ladder_ladder_file, d2ladder_backup_file);
|
| 690 |
}
|
| 691 |
}
|
| 692 |
|
| 693 |
fdladder=fopen(d2ladder_ladder_file,"wb");
|
| 694 |
if(!fdladder) {
|
| 695 |
eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file);
|
| 696 |
return -1;
|
| 697 |
}
|
| 698 |
|
| 699 |
// aaron: add extra output for XML ladder here --->
|
| 700 |
if (d2dbs_prefs_get_XML_output_ladder())
|
| 701 |
{
|
| 702 |
XMLfilename = xmalloc(strlen(d2dbs_prefs_get_ladder_dir())+1+strlen(XMLname)+1);
|
| 703 |
sprintf(XMLfilename,"%s/%s",d2dbs_prefs_get_ladder_dir(),XMLname);
|
| 704 |
if (!(XMLfile = fopen(XMLfilename,"w")))
|
| 705 |
{
|
| 706 |
eventlog(eventlog_level_error,__FUNCTION__,"could not open XML ladder file for output");
|
| 707 |
}
|
| 708 |
else
|
| 709 |
{
|
| 710 |
d2ladder_print_XML(XMLfile);
|
| 711 |
fclose(XMLfile);
|
| 712 |
xfree(XMLfilename);
|
| 713 |
}
|
| 714 |
}
|
| 715 |
|
| 716 |
// <---
|
| 717 |
|
| 718 |
bn_int_set(&fileheader.maxtype,d2ladder_maxtype);
|
| 719 |
bn_int_set(&fileheader.checksum,0);
|
| 720 |
fwrite(&fileheader,1,sizeof(fileheader),fdladder);
|
| 721 |
fwrite(lhead,1,sizeof(lhead),fdladder);
|
| 722 |
for(i=0;i<d2ladder_maxtype;i++) {
|
| 723 |
number=bn_int_get(lhead[i].number);
|
| 724 |
if(number<=0) continue;
|
| 725 |
d2ladder=d2ladderlist_find_type(i);
|
| 726 |
ldata=xmalloc(number * sizeof(*ldata));
|
| 727 |
memset(ldata,0,number * sizeof(*ldata));
|
| 728 |
for (j=0; j< number; j++) {
|
| 729 |
bn_int_set(&ldata[j].experience,d2ladder->info[j].experience);
|
| 730 |
bn_short_set(&ldata[j].status, d2ladder->info[j].status);
|
| 731 |
bn_byte_set(&ldata[j].level, d2ladder->info[j].level);
|
| 732 |
bn_byte_set(&ldata[j].class, d2ladder->info[j].class);
|
| 733 |
strncpy(ldata[j].charname,d2ladder->info[j].charname,sizeof(ldata[j].charname));
|
| 734 |
}
|
| 735 |
fwrite(ldata,1,number*sizeof(*ldata),fdladder);
|
| 736 |
xfree(ldata);
|
| 737 |
}
|
| 738 |
fclose(fdladder);
|
| 739 |
d2ladder_checksum_set();
|
| 740 |
eventlog(eventlog_level_info,__FUNCTION__,"ladder file saved (%d changes)",d2ladder_change_count);
|
| 741 |
d2ladder_change_count=0;
|
| 742 |
return 0;
|
| 743 |
}
|
| 744 |
|
| 745 |
int d2ladder_print(FILE *ladderstrm)
|
| 746 |
{
|
| 747 |
t_d2ladder * d2ladder;
|
| 748 |
t_d2ladder_info * ldata;
|
| 749 |
unsigned int i,type;
|
| 750 |
int overalltype,classtype;
|
| 751 |
char laddermode[4][20]={"Hardcore", "Standard","Expansion HC","Expansion" };
|
| 752 |
char charclass[11][12]={"OverAll", "Amazon", "Sorceress", "Necromancer", "Paladin",\
|
| 753 |
"Barbarian", "Druid", "Assassin", "","",""} ;
|
| 754 |
|
| 755 |
for(type=0; type <d2ladder_maxtype; type++) {
|
| 756 |
d2ladder=d2ladderlist_find_type(type);
|
| 757 |
if (!d2ladder)
|
| 758 |
continue;
|
| 759 |
if(d2ladder->len<=0)
|
| 760 |
continue;
|
| 761 |
ldata=d2ladder->info;
|
| 762 |
|
| 763 |
overalltype=0;
|
| 764 |
classtype=0;
|
| 765 |
|
| 766 |
if(type <= D2LADDER_HC_OVERALL+D2CHAR_CLASS_MAX +1)
|
| 767 |
{
|
| 768 |
overalltype=0 ;
|
| 769 |
classtype=type-D2LADDER_HC_OVERALL;
|
| 770 |
}
|
| 771 |
else if (type >= D2LADDER_STD_OVERALL && type<= D2LADDER_STD_OVERALL+D2CHAR_CLASS_MAX +1)
|
| 772 |
{
|
| 773 |
overalltype=1;
|
| 774 |
classtype=type-D2LADDER_STD_OVERALL;
|
| 775 |
}
|
| 776 |
else if (type >= D2LADDER_EXP_HC_OVERALL && type<= D2LADDER_EXP_HC_OVERALL+D2CHAR_EXP_CLASS_MAX +1)
|
| 777 |
{
|
| 778 |
overalltype=2;
|
| 779 |
classtype=type-D2LADDER_EXP_HC_OVERALL;
|
| 780 |
}
|
| 781 |
else if (type >= D2LADDER_EXP_STD_OVERALL && type<= D2LADDER_EXP_STD_OVERALL+D2CHAR_EXP_CLASS_MAX +1)
|
| 782 |
{
|
| 783 |
overalltype=3;
|
| 784 |
classtype=type- D2LADDER_EXP_STD_OVERALL ;
|
| 785 |
}
|
| 786 |
|
| 787 |
fprintf(ladderstrm,"ladder type %d %s %s\n",type,laddermode[overalltype],charclass[classtype]);
|
| 788 |
fprintf(ladderstrm,"************************************************************************\n");
|
| 789 |
fprintf(ladderstrm,"No character name level exp status title class \n");
|
| 790 |
for(i=0; i<d2ladder->len; i++)
|
| 791 |
{
|
| 792 |
fprintf(ladderstrm,"NO.%2d %-16s %2d %10d %2X %1X %s\n",
|
| 793 |
i+1,
|
| 794 |
ldata[i].charname,
|
| 795 |
ldata[i].level,
|
| 796 |
ldata[i].experience,
|
| 797 |
ldata[i].status,
|
| 798 |
1,
|
| 799 |
charclass[ldata[i].class+1]);
|
| 800 |
}
|
| 801 |
fprintf(ladderstrm,"************************************************************************\n");
|
| 802 |
fflush(ladderstrm);
|
| 803 |
}
|
| 804 |
return 0;
|
| 805 |
}
|
| 806 |
|
| 807 |
int d2ladder_checksum(unsigned char const * data, unsigned int len,unsigned int offset)
|
| 808 |
{
|
| 809 |
int checksum;
|
| 810 |
unsigned int i;
|
| 811 |
unsigned int ch;
|
| 812 |
|
| 813 |
if (!data) return 0;
|
| 814 |
checksum=0;
|
| 815 |
for (i=0; i<len; i++) {
|
| 816 |
ch=data[i];
|
| 817 |
if (i>=offset && i<offset+sizeof(int)) ch=0;
|
| 818 |
ch+=(checksum<0);
|
| 819 |
checksum=2*checksum+ch;
|
| 820 |
}
|
| 821 |
return checksum;
|
| 822 |
}
|
| 823 |
|
| 824 |
int d2ladder_checksum_set(void)
|
| 825 |
{
|
| 826 |
FILE * fdladder;
|
| 827 |
off_t filesize;
|
| 828 |
int curlen,readlen,len;
|
| 829 |
unsigned char * buffer;
|
| 830 |
bn_int checksum;
|
| 831 |
|
| 832 |
if (!d2ladder_ladder_file) return -1;
|
| 833 |
fdladder=fopen(d2ladder_ladder_file,"r+b");
|
| 834 |
if(!fdladder) {
|
| 835 |
eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file);
|
| 836 |
return -1;
|
| 837 |
}
|
| 838 |
fseek(fdladder,0,SEEK_END);
|
| 839 |
filesize=ftell(fdladder);
|
| 840 |
rewind(fdladder);
|
| 841 |
if(filesize==(off_t)-1) {
|
| 842 |
eventlog(eventlog_level_error,__FUNCTION__,"lseek() error in ladder file %s",d2ladder_ladder_file);
|
| 843 |
fclose(fdladder);
|
| 844 |
return -1;
|
| 845 |
}
|
| 846 |
if(filesize<(signed)sizeof(t_d2ladderfile_header)) {
|
| 847 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder file size error :%s",d2ladder_ladder_file);
|
| 848 |
fclose(fdladder);
|
| 849 |
return -1;
|
| 850 |
}
|
| 851 |
buffer=xmalloc(filesize);
|
| 852 |
|
| 853 |
curlen=0;
|
| 854 |
while(curlen<filesize) {
|
| 855 |
if(filesize-curlen > 2000)
|
| 856 |
len = 2000;
|
| 857 |
else
|
| 858 |
len = filesize-curlen;
|
| 859 |
readlen=fread(buffer+curlen,1,len,fdladder);
|
| 860 |
if (readlen<=0) {
|
| 861 |
xfree(buffer);
|
| 862 |
fclose(fdladder);
|
| 863 |
eventlog(eventlog_level_error,__FUNCTION__,"got bad save file or read error(read:%s)",pstrerror(errno));
|
| 864 |
return -1;
|
| 865 |
}
|
| 866 |
curlen+=readlen;
|
| 867 |
}
|
| 868 |
|
| 869 |
bn_int_set(&checksum,d2ladder_checksum(buffer,filesize,LADDERFILE_CHECKSUM_OFFSET));
|
| 870 |
fseek(fdladder,LADDERFILE_CHECKSUM_OFFSET,SEEK_SET);
|
| 871 |
fwrite(&checksum,1,sizeof(checksum),fdladder);
|
| 872 |
xfree(buffer);
|
| 873 |
fclose(fdladder);
|
| 874 |
return 0;
|
| 875 |
}
|
| 876 |
|
| 877 |
int d2ladder_checksum_check(void)
|
| 878 |
{
|
| 879 |
FILE * fdladder;
|
| 880 |
off_t filesize;
|
| 881 |
int curlen,readlen,len;
|
| 882 |
unsigned char * buffer;
|
| 883 |
int checksum,oldchecksum;
|
| 884 |
t_d2ladderfile_header * header;
|
| 885 |
|
| 886 |
if (!d2ladder_ladder_file) return -1;
|
| 887 |
fdladder=fopen(d2ladder_ladder_file,"rb");
|
| 888 |
if(!fdladder) {
|
| 889 |
eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file);
|
| 890 |
return -1;
|
| 891 |
}
|
| 892 |
fseek(fdladder,0,SEEK_END);
|
| 893 |
filesize=ftell(fdladder);
|
| 894 |
rewind(fdladder);
|
| 895 |
if(filesize==(off_t)-1) {
|
| 896 |
eventlog(eventlog_level_error,__FUNCTION__,"lseek() error in ladder file %s",d2ladder_ladder_file);
|
| 897 |
fclose(fdladder);
|
| 898 |
return -1;
|
| 899 |
}
|
| 900 |
if(filesize<(signed)sizeof(t_d2ladderfile_header)) {
|
| 901 |
eventlog(eventlog_level_error,__FUNCTION__,"ladder file size error :%s",d2ladder_ladder_file);
|
| 902 |
fclose(fdladder);
|
| 903 |
return -1;
|
| 904 |
}
|
| 905 |
buffer=xmalloc(filesize);
|
| 906 |
header=(t_d2ladderfile_header *)buffer;
|
| 907 |
curlen=0;
|
| 908 |
while(curlen<filesize) {
|
| 909 |
if(filesize-curlen > 2000)
|
| 910 |
len = 2000;
|
| 911 |
else
|
| 912 |
len = filesize-curlen;
|
| 913 |
readlen=fread(buffer+curlen,1,len,fdladder);
|
| 914 |
if (readlen<=0) {
|
| 915 |
xfree(buffer);
|
| 916 |
fclose(fdladder);
|
| 917 |
eventlog(eventlog_level_error,__FUNCTION__,"got bad save file or read error(read:%s)",pstrerror(errno));
|
| 918 |
return -1;
|
| 919 |
}
|
| 920 |
curlen+=readlen;
|
| 921 |
}
|
| 922 |
fclose(fdladder);
|
| 923 |
|
| 924 |
oldchecksum=bn_int_get(header->checksum);
|
| 925 |
checksum=d2ladder_checksum(buffer,filesize,LADDERFILE_CHECKSUM_OFFSET);
|
| 926 |
xfree(buffer);
|
| 927 |
|
| 928 |
if(oldchecksum==checksum) {
|
| 929 |
eventlog(eventlog_level_info,__FUNCTION__,"ladder file check pass (checksum=0x%X)",checksum);
|
| 930 |
return 1;
|
| 931 |
} else {
|
| 932 |
eventlog(eventlog_level_debug,__FUNCTION__,"ladder file checksum mismatch 0x%X - 0x%X",oldchecksum, checksum);
|
| 933 |
return 0;
|
| 934 |
}
|
| 935 |
}
|