/[LeafOK_CVS]/pvpgn-1.7.4/src/d2dbs/d2ladder.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/d2dbs/d2ladder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 sysadm 1.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     }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1