/[LeafOK_CVS]/pvpgn-1.7.4/src/d2cs/d2charfile.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/d2cs/d2charfile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.1 /*
2     * Copyright (C) 2000,2001 Onlyer (onlyer@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     #include <stdio.h>
29     #include <ctype.h>
30     #ifdef HAVE_STRING_H
31     # include <string.h>
32     #else
33     # ifdef HAVE_STRINGS_H
34     # include <strings.h>
35     # endif
36     # ifdef HAVE_MEMORY_H
37     # include <memory.h>
38     # endif
39     #endif
40     #ifdef STDC_HEADERS
41     # include <stdlib.h>
42     #else
43     # ifdef HAVE_MALLOC_H
44     # include <malloc.h>
45     # endif
46     #endif
47     #include "compat/memset.h"
48     #include "compat/memcpy.h"
49     #include <errno.h>
50     #include "compat/strerror.h"
51     #ifdef HAVE_UNISTD_H
52     # include <unistd.h>
53     #endif
54     #include "compat/access.h"
55     #ifdef TIME_WITH_SYS_TIME
56     # include <time.h>
57     # include <sys/time.h>
58     #else
59     # ifdef HAVE_SYS_TIME_H
60     # include <sys/time.h>
61     # else
62     # include <time.h>
63     # endif
64     #endif
65     #ifdef HAVE_SYS_STAT_H
66     # include <sys/stat.h>
67     #endif
68    
69     #include "d2charfile.h"
70     #include "prefs.h"
71     #include "xstring.h"
72     #include "common/bn_type.h"
73     #include "common/eventlog.h"
74     #include "common/d2char_checksum.h"
75     #include "common/xalloc.h"
76     #include "common/setup_after.h"
77    
78     static int d2charsave_init(void * buffer,char const * charname,unsigned char class,unsigned short status);
79     static int d2charinfo_init(t_d2charinfo_file * chardata, char const * account, char const * charname,
80     unsigned char class, unsigned short status);
81    
82     static int d2charsave_init(void * buffer,char const * charname,unsigned char class,unsigned short status)
83     {
84     ASSERT(buffer,-1);
85     ASSERT(charname,-1);
86     bn_byte_set((bn_byte *)((char *)buffer+D2CHARSAVE_CLASS_OFFSET), class);
87     bn_short_set((bn_short *)((char *)buffer+D2CHARSAVE_STATUS_OFFSET),status);
88     strncpy((char *)buffer+D2CHARSAVE_CHARNAME_OFFSET,charname,MAX_CHARNAME_LEN);
89     return 0;
90     }
91    
92    
93     static int d2charinfo_init(t_d2charinfo_file * chardata, char const * account, char const * charname,
94     unsigned char class, unsigned short status)
95     {
96     unsigned int i;
97     time_t now;
98    
99     now=time(NULL);
100     bn_int_set(&chardata->header.magicword,D2CHARINFO_MAGICWORD);
101     bn_int_set(&chardata->header.version,D2CHARINFO_VERSION);
102     bn_int_set(&chardata->header.create_time,now);
103     bn_int_set(&chardata->header.last_time,now);
104     bn_int_set(&chardata->header.total_play_time,0);
105    
106     memset(chardata->header.charname, 0,MAX_CHARNAME_LEN);
107     strncpy(chardata->header.charname,charname,MAX_CHARNAME_LEN);
108     memset(chardata->header.account, 0,MAX_ACCTNAME_LEN);
109     strncpy(chardata->header.account,account,MAX_ACCTNAME_LEN);
110     memset(chardata->header.realmname, 0,MAX_REALMNAME_LEN);
111     strncpy(chardata->header.realmname,prefs_get_realmname(),MAX_REALMNAME_LEN);
112     bn_int_set(&chardata->header.checksum,0);
113     for (i=0; i<NELEMS(chardata->header.reserved); i++) {
114     bn_int_set(&chardata->header.reserved[i],0);
115     }
116     bn_int_set(&chardata->summary.charlevel,1);
117     bn_int_set(&chardata->summary.experience,0);
118     bn_int_set(&chardata->summary.charclass,class);
119     bn_int_set(&chardata->summary.charstatus,status);
120    
121     memset(chardata->portrait.gfx,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.gfx));
122     memset(chardata->portrait.color,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.color));
123     memset(chardata->portrait.u2,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.u2));
124     memset(chardata->portrait.u1,D2CHARINFO_PORTRAIT_MASK,sizeof(chardata->portrait.u1));
125     memset(chardata->pad,0,sizeof(chardata->pad));
126    
127     bn_short_set(&chardata->portrait.header,D2CHARINFO_PORTRAIT_HEADER);
128     bn_byte_set(&chardata->portrait.status,status|D2CHARINFO_PORTRAIT_MASK);
129     bn_byte_set(&chardata->portrait.class,class+1);
130     bn_byte_set(&chardata->portrait.level,1);
131     if (charstatus_get_ladder(status))
132     bn_byte_set(&chardata->portrait.ladder, 1);
133     else
134     bn_byte_set(&chardata->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
135     bn_byte_set(&chardata->portrait.end,'\0');
136    
137     memset(chardata->pad,0,sizeof(chardata->pad));
138    
139     return 0;
140     }
141    
142    
143     extern int d2char_create(char const * account, char const * charname, unsigned char class, unsigned short status)
144     {
145     t_d2charinfo_file chardata;
146     char * savefile, * infofile;
147     char buffer[1024];
148     unsigned int size;
149     int ladder_time, now;
150     FILE * fp;
151    
152    
153     ASSERT(account,-1);
154     ASSERT(charname,-1);
155     if (class>D2CHAR_MAX_CLASS) class=0;
156     status &= D2CHARINFO_STATUS_FLAG_INIT_MASK;
157     charstatus_set_init(status,1);
158    
159     /* We need to make sure we are creating the correct character (Classic or Expansion)
160     for the type of game server we are running. If lod_realm = 1 then only Expansion
161     characters can be created and if set to 0 then only Classic character can
162     be created */
163    
164     if (!(prefs_get_lod_realm() == 2)) {
165     if (prefs_get_lod_realm() && ((status & 0x20) != 0x20)) {
166     eventlog(eventlog_level_warn,__FUNCTION__,"This Realm is for LOD Characters Only");
167     return -1;
168     }
169     if (!prefs_get_lod_realm() && ((status & 0x20) != 0x0)) {
170     eventlog(eventlog_level_warn,__FUNCTION__,"This Realm is for Classic Characters Only");
171     return -1;
172     }
173     }
174    
175     /* Once correct type of character is varified then continue with creation of character */
176    
177     if (!prefs_allow_newchar()) {
178     eventlog(eventlog_level_warn,__FUNCTION__,"creation of new character is disabled");
179     return -1;
180     }
181     if (d2char_check_charname(charname)<0) {
182     eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
183     return -1;
184     }
185     if (d2char_check_acctname(account)<0) {
186     eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
187     return -1;
188     }
189     size=sizeof(buffer);
190     if (file_read(prefs_get_charsave_newbie(), buffer, &size)<0) {
191     eventlog(eventlog_level_error,__FUNCTION__,"error loading newbie save file");
192     return -1;
193     }
194     if (size>=sizeof(buffer)) {
195     eventlog(eventlog_level_error,__FUNCTION__,"newbie save file \"%s\" is corrupt (length %lu, expected <%lu)",prefs_get_charsave_newbie(),(unsigned long)size,(unsigned long)sizeof(buffer));
196     return -1;
197     }
198    
199     savefile=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
200     d2char_get_savefile_name(savefile,charname);
201     if ((fp=fopen(savefile,"rb"))) {
202     eventlog(eventlog_level_warn,__FUNCTION__,"character save file \"%s\" for \"%s\" already exist",savefile,charname);
203     fclose(fp);
204     xfree(savefile);
205     return -1;
206     }
207    
208     infofile=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
209     d2char_get_infofile_name(infofile,account,charname);
210    
211     now = time(NULL);
212     ladder_time = prefs_get_ladder_start_time();
213     if ((ladder_time > 0) && (now < ladder_time))
214     charstatus_set_ladder(status, 0);
215    
216     d2charsave_init(buffer,charname,class,status);
217     d2charinfo_init(&chardata,account,charname,class,status);
218    
219     if (file_write(infofile,&chardata,sizeof(chardata))<0) {
220     eventlog(eventlog_level_error,__FUNCTION__,"error writing info file \"%s\"",infofile);
221     remove(infofile);
222     xfree(infofile);
223     xfree(savefile);
224     return -1;
225     }
226    
227     if (file_write(savefile,buffer,size)<0) {
228     eventlog(eventlog_level_error,__FUNCTION__,"error writing save file \"%s\"",savefile);
229     remove(infofile);
230     remove(savefile);
231     xfree(savefile);
232     xfree(infofile);
233     return -1;
234     }
235     xfree(savefile);
236     xfree(infofile);
237     eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) class %d status 0x%X created",charname,account,class,status);
238     return 0;
239     }
240    
241    
242     extern int d2char_find(char const * account, char const * charname)
243     {
244     char * file;
245     FILE * fp;
246    
247     ASSERT(account,-1);
248     ASSERT(charname,-1);
249     file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
250     d2char_get_infofile_name(file,account,charname);
251     fp=fopen(file,"rb");
252     xfree(file);
253     if (fp) {
254     fclose(fp);
255     return 0;
256     }
257     return -1;
258     }
259    
260    
261     extern int d2char_convert(char const * account, char const * charname)
262     {
263     FILE * fp;
264     char * file;
265     unsigned char buffer[MAX_SAVEFILE_SIZE];
266     unsigned int status_offset;
267     unsigned char status;
268     unsigned int charstatus;
269     t_d2charinfo_file charinfo;
270     unsigned int size;
271     unsigned int version;
272     unsigned int checksum;
273    
274     ASSERT(account,-1);
275     ASSERT(charname,-1);
276    
277     /* Playing with a expanstion char on a classic realm
278     will cause the game server to crash, therefore
279     I recommed setting allow_convert = 0 in the d2cs.conf
280     We need to do this to prevent creating classic char
281     and converting to expantion on a classic realm.
282     LOD Char must be created on LOD realm */
283    
284     if (!prefs_get_allow_convert()) {
285     eventlog(eventlog_level_info,__FUNCTION__,"Convert char has been disabled");
286     return -1;
287     }
288    
289     /* Procedure is stopped here and returned if
290     allow_convet = 0 in d2cs.conf */
291    
292     if (d2char_check_charname(charname)<0) {
293     eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
294     return -1;
295     }
296     if (d2char_check_acctname(account)<0) {
297     eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
298     return -1;
299     }
300     file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
301     d2char_get_infofile_name(file,account,charname);
302     if (!(fp=fopen(file,"rb+"))) {
303     eventlog(eventlog_level_error,__FUNCTION__,"unable to open charinfo file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
304     xfree(file);
305     return -1;
306     }
307     xfree(file);
308     if (fread(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
309     eventlog(eventlog_level_error,__FUNCTION__,"error reading charinfo file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
310     fclose(fp);
311     return -1;
312     }
313     charstatus=bn_int_get(charinfo.summary.charstatus);
314     charstatus_set_expansion(charstatus,1);
315     bn_int_set(&charinfo.summary.charstatus,charstatus);
316    
317     status=bn_byte_get(charinfo.portrait.status);
318     charstatus_set_expansion(status,1);
319     bn_byte_set(&charinfo.portrait.status,status);
320    
321     fseek(fp,0,SEEK_SET); /* FIXME: check return */
322     if (fwrite(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
323     eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
324     fclose(fp);
325     return -1;
326     }
327     if (fclose(fp)<0) {
328     eventlog(eventlog_level_error,__FUNCTION__,"could not close charinfo file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
329     return -1;
330     }
331    
332     file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
333     d2char_get_savefile_name(file,charname);
334     if (!(fp=fopen(file,"rb+"))) {
335     eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
336     xfree(file);
337     return -1;
338     }
339     xfree(file);
340     size=fread(buffer,1,sizeof(buffer),fp);
341     if (!feof(fp)) {
342     eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
343     fclose(fp);
344     return -1;
345     }
346     version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
347     if (version>=0x0000005C) {
348     status_offset=D2CHARSAVE_STATUS_OFFSET_109;
349     } else {
350     status_offset=D2CHARSAVE_STATUS_OFFSET;
351     }
352     status=bn_byte_get(buffer+status_offset);
353     charstatus_set_expansion(status,1);
354     bn_byte_set((bn_byte *)(buffer+status_offset),status); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
355     if (version>=0x0000005C) {
356     checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
357     bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
358     }
359     fseek(fp,0,SEEK_SET); /* FIXME: check return */
360     if (fwrite(buffer,1,size,fp)!=size) {
361     eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
362     fclose(fp);
363     return -1;
364     }
365     if (fclose(fp)<0) {
366     eventlog(eventlog_level_error,__FUNCTION__,"could not close charsave file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
367     return -1;
368     }
369     eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) converted to expansion",charname,account);
370     return 0;
371     }
372    
373    
374     extern int d2char_delete(char const * account, char const * charname)
375     {
376     char * file;
377    
378     ASSERT(account,-1);
379     ASSERT(charname,-1);
380     if (d2char_check_charname(charname)<0) {
381     eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
382     return -1;
383     }
384     if (d2char_check_acctname(account)<0) {
385     eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
386     return -1;
387     }
388    
389     /* charsave file */
390     file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
391     d2char_get_infofile_name(file,account,charname);
392     if (remove(file)<0) {
393     eventlog(eventlog_level_error,__FUNCTION__,"failed to delete charinfo file \"%s\" (remove: %s)",file,pstrerror(errno));
394     xfree(file);
395     return -1;
396     }
397     xfree(file);
398    
399     /* charinfo file */
400     file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
401     d2char_get_savefile_name(file,charname);
402     if (remove(file)<0) {
403     eventlog(eventlog_level_error,__FUNCTION__,"failed to delete charsave file \"%s\" (remove: %s)",file,pstrerror(errno));
404     }
405     xfree(file);
406    
407     /* bak charsave file */
408     file=xmalloc(strlen(prefs_get_bak_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
409     d2char_get_bak_infofile_name(file,account,charname);
410     if (access(file, F_OK) == 0) {
411     if (remove(file)<0) {
412     eventlog(eventlog_level_error,__FUNCTION__,"failed to delete bak charinfo file \"%s\" (remove: %s)",file,pstrerror(errno));
413     }
414     }
415     xfree(file);
416    
417     /* bak charinfo file */
418     file=xmalloc(strlen(prefs_get_bak_charsave_dir())+1+strlen(charname)+1);
419     d2char_get_bak_savefile_name(file,charname);
420     if (access(file, F_OK) == 0) {
421     if (remove(file)<0) {
422     eventlog(eventlog_level_error,__FUNCTION__,"failed to delete bak charsave file \"%s\" (remove: %s)",file,pstrerror(errno));
423     }
424     }
425     xfree(file);
426    
427     eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) deleted",charname,account);
428     return 0;
429     }
430    
431    
432     extern int d2char_get_summary(char const * account, char const * charname,t_d2charinfo_summary * charinfo)
433     {
434     t_d2charinfo_file data;
435    
436     ASSERT(account,-1);
437     ASSERT(charname,-1);
438     ASSERT(charinfo,-1);
439     if (d2charinfo_load(account, charname, &data)<0) {
440     eventlog(eventlog_level_error,__FUNCTION__,"error loading character %s(*%s)",charname,account);
441     return -1;
442     }
443     memcpy(charinfo,&data.summary,sizeof(data.summary));
444     eventlog(eventlog_level_info,__FUNCTION__,"character %s difficulty %d expansion %d hardcore %d dead %d loaded",charname,
445     d2charinfo_get_difficulty(charinfo), d2charinfo_get_expansion(charinfo),
446     d2charinfo_get_hardcore(charinfo),d2charinfo_get_dead(charinfo));
447     return 0;
448     }
449    
450    
451     extern int d2charinfo_load(char const * account, char const * charname, t_d2charinfo_file * data)
452     {
453     char * file;
454     int size, ladder_time;
455    
456     if (d2char_check_charname(charname)<0) {
457     eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
458     return -1;
459     }
460     if (d2char_check_acctname(account)<0) {
461     eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
462     return -1;
463     }
464     file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
465     d2char_get_infofile_name(file,account,charname);
466     size=sizeof(t_d2charinfo_file);
467     if (file_read(file,data,&size)<0) {
468     eventlog(eventlog_level_error,__FUNCTION__,"error loading character file %s",file);
469     xfree(file);
470     return -1;
471     }
472     if (size!=sizeof(t_d2charinfo_file)) {
473     eventlog(eventlog_level_error,__FUNCTION__,"got bad charinfo file %s (length %d)",charname,size);
474     xfree(file);
475     return -1;
476     }
477     d2char_portrait_init(&data->portrait);
478     if (d2charinfo_check(data) < 0) {
479     xfree(file);
480     return -1;
481     }
482     if (!(charstatus_get_ladder(bn_int_get(data->summary.charstatus)))) {
483     bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
484     xfree(file);
485     return 0;
486     }
487     ladder_time = prefs_get_ladder_start_time();
488     if ((ladder_time > 0) && bn_int_get(data->header.create_time) < ladder_time) {
489     char buffer[MAX_SAVEFILE_SIZE];
490     unsigned int status_offset;
491     unsigned char status;
492     unsigned int charstatus;
493     unsigned int size;
494     unsigned int version;
495     unsigned int checksum;
496     FILE * fp;
497    
498     eventlog(eventlog_level_info,__FUNCTION__,"%s(*%s) was created in old ladder season, set to non-ladder", charname, account);
499     if (!(fp=fopen(file,"wb"))) {
500     eventlog(eventlog_level_error,__FUNCTION__,"charinfo file \"%s\" does not exist for account \"%s\"",file,account);
501     xfree(file);
502     return 0;
503     }
504     xfree(file);
505     charstatus = bn_int_get(data->summary.charstatus);
506     charstatus_set_ladder(charstatus, 0);
507     bn_int_set(&data->summary.charstatus, charstatus);
508    
509     status=bn_byte_get(data->portrait.status);
510     charstatus_set_ladder(status,0);
511     bn_byte_set(&data->portrait.status,status);
512     bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
513    
514     if (fwrite(data,1,sizeof(*data),fp)!=sizeof(*data)) {
515     eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
516     fclose(fp);
517     return 0;
518     }
519     fclose(fp);
520    
521     file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
522     d2char_get_savefile_name(file,charname);
523    
524     if (!(fp=fopen(file,"rb+"))) {
525     eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
526     xfree(file);
527     return 0;
528     }
529     xfree(file);
530     size=fread(buffer,1,sizeof(buffer),fp);
531     if (!feof(fp)) {
532     eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
533     fclose(fp);
534     return 0;
535     }
536     version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
537     if (version>=0x5C) {
538     status_offset=D2CHARSAVE_STATUS_OFFSET_109;
539     } else {
540     status_offset=D2CHARSAVE_STATUS_OFFSET;
541     }
542     status=bn_byte_get(buffer+status_offset);
543     charstatus_set_ladder(status,0);
544     /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
545     bn_byte_set((bn_byte *)(buffer+status_offset),status);
546     if (version>=0x5C) {
547     checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
548     bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum);
549     }
550     fseek(fp,0,SEEK_SET);
551     if (fwrite(buffer,1,size,fp)!=size) {
552     eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
553     fclose(fp);
554     return 0;
555     }
556     fclose(fp);
557     } else {
558     bn_byte_set(&data->portrait.ladder, 1);
559     xfree(file);
560     }
561     return 0;
562     }
563    
564     extern int d2charinfo_check(t_d2charinfo_file * data)
565     {
566     ASSERT(data,-1);
567     if (bn_int_get(data->header.magicword) != D2CHARINFO_MAGICWORD) {
568     eventlog(eventlog_level_error,__FUNCTION__,"info data check failed (header 0x%08X)",bn_int_get(data->header.magicword));
569     return -1;
570     }
571     if (bn_int_get(data->header.version) != D2CHARINFO_VERSION) {
572     eventlog(eventlog_level_error,__FUNCTION__,"info data check failed (version 0x%08X)",bn_int_get(data->header.version));
573     return -1;
574     }
575     return 0;
576     }
577    
578    
579     extern int d2char_portrait_init(t_d2charinfo_portrait * portrait)
580     {
581     unsigned int i;
582     unsigned char * p;
583    
584     p=(unsigned char *)portrait;
585     for (i=0; i<sizeof(t_d2charinfo_portrait); i++) {
586     if (!p[i]) p[i]=D2CHARINFO_PORTRAIT_PADBYTE;
587     }
588     p[i-1]='\0';
589     return 0;
590     }
591    
592    
593     extern int d2char_get_portrait(char const * account,char const * charname, t_d2charinfo_portrait * portrait)
594     {
595     t_d2charinfo_file data;
596    
597     ASSERT(charname,-1);
598     ASSERT(account,-1);
599     ASSERT(portrait,-1);
600     if (d2charinfo_load(account, charname, &data)<0) {
601     eventlog(eventlog_level_error,__FUNCTION__,"error loading character %s(*%s)",charname,account);
602     return -1;
603     }
604     strcpy((char *)portrait,(char *)&data.portrait);
605     return 0;
606     }
607    
608    
609     extern int d2char_check_charname(char const * name)
610     {
611     unsigned int i;
612     unsigned char ch;
613    
614     if (!name) return -1;
615     if (!isalpha((int)name[0])) return -1;
616    
617     for (i=1; i<=MAX_CHARNAME_LEN; i++) {
618     ch=name[i];
619     if (ch=='\0') break;
620     if (isalpha(ch)) continue;
621     if (ch=='-') continue;
622     if (ch=='_') continue;
623     if (ch=='.') continue;
624     return -1;
625     }
626     if (i >= MIN_NAME_LEN || i<= MAX_CHARNAME_LEN) return 0;
627     return -1;
628     }
629    
630    
631     extern int d2char_check_acctname(char const * name)
632     {
633     unsigned int i;
634     unsigned char ch;
635    
636     if (!name) return -1;
637     if (!isalnum((int)name[0])) return -1;
638    
639     for (i=1; i<=MAX_CHARNAME_LEN; i++) {
640     ch=name[i];
641     if (ch=='\0') break;
642     if (isalnum(ch)) continue;
643     if (strchr(prefs_get_d2cs_account_allowed_symbols(),ch)) continue;
644     return -1;
645     }
646     if (i >= MIN_NAME_LEN || i<= MAX_ACCTNAME_LEN) return 0;
647     return -1;
648     }
649    
650    
651     extern int d2char_get_savefile_name(char * filename, char const * charname)
652     {
653     char tmpchar[MAX_CHARNAME_LEN];
654    
655     ASSERT(filename,-1);
656     ASSERT(charname,-1);
657     strncpy(tmpchar,charname,sizeof(tmpchar));
658     tmpchar[sizeof(tmpchar)-1]='\0';
659     strtolower(tmpchar);
660     sprintf(filename,"%s/%s",prefs_get_charsave_dir(),tmpchar);
661     return 0;
662     }
663    
664    
665     extern int d2char_get_bak_savefile_name(char * filename, char const * charname)
666     {
667     char tmpchar[MAX_CHARNAME_LEN];
668    
669     ASSERT(filename,-1);
670     ASSERT(charname,-1);
671     strncpy(tmpchar,charname,sizeof(tmpchar));
672     tmpchar[sizeof(tmpchar)-1]='\0';
673     strtolower(tmpchar);
674     sprintf(filename,"%s/%s",prefs_get_bak_charsave_dir(),tmpchar);
675     return 0;
676     }
677    
678    
679     extern int d2char_get_infodir_name(char * filename, char const * account)
680     {
681     char tmpacct[MAX_ACCTNAME_LEN];
682    
683     ASSERT(filename,-1);
684     ASSERT(account,-1);
685    
686     strncpy(tmpacct,account,sizeof(tmpacct));
687     tmpacct[sizeof(tmpacct)-1]='\0';
688     strtolower(tmpacct);
689     sprintf(filename,"%s/%s",prefs_get_charinfo_dir(),tmpacct);
690     return 0;
691     }
692    
693    
694     extern int d2char_get_infofile_name(char * filename, char const * account, char const * charname)
695     {
696     char tmpchar[MAX_CHARNAME_LEN];
697     char tmpacct[MAX_ACCTNAME_LEN];
698    
699     ASSERT(filename,-1);
700     ASSERT(account,-1);
701     ASSERT(charname,-1);
702     strncpy(tmpchar,charname,sizeof(tmpchar));
703     tmpchar[sizeof(tmpchar)-1]='\0';
704     strtolower(tmpchar);
705    
706     strncpy(tmpacct,account,sizeof(tmpacct));
707     tmpchar[sizeof(tmpacct)-1]='\0';
708     strtolower(tmpacct);
709     sprintf(filename,"%s/%s/%s",prefs_get_charinfo_dir(),tmpacct,tmpchar);
710     return 0;
711     }
712    
713    
714     extern int d2char_get_bak_infofile_name(char * filename, char const * account, char const * charname)
715     {
716     char tmpchar[MAX_CHARNAME_LEN];
717     char tmpacct[MAX_ACCTNAME_LEN];
718    
719     ASSERT(filename,-1);
720     ASSERT(account,-1);
721     ASSERT(charname,-1);
722     strncpy(tmpchar,charname,sizeof(tmpchar));
723     tmpchar[sizeof(tmpchar)-1]='\0';
724     strtolower(tmpchar);
725    
726     strncpy(tmpacct,account,sizeof(tmpacct));
727     tmpchar[sizeof(tmpacct)-1]='\0';
728     strtolower(tmpacct);
729     sprintf(filename,"%s/%s/%s",prefs_get_bak_charinfo_dir(),tmpacct,tmpchar);
730     return 0;
731     }
732    
733    
734     extern unsigned int d2charinfo_get_ladder(t_d2charinfo_summary const * charinfo)
735     {
736     ASSERT(charinfo,0);
737     return charstatus_get_ladder(bn_int_get(charinfo->charstatus));
738     }
739    
740     extern unsigned int d2charinfo_get_expansion(t_d2charinfo_summary const * charinfo)
741     {
742     ASSERT(charinfo,0);
743     return charstatus_get_expansion(bn_int_get(charinfo->charstatus));
744     }
745    
746    
747     extern unsigned int d2charinfo_get_level(t_d2charinfo_summary const * charinfo)
748     {
749     ASSERT(charinfo,0);
750     return bn_int_get(charinfo->charlevel);
751     }
752    
753    
754     extern unsigned int d2charinfo_get_class(t_d2charinfo_summary const * charinfo)
755     {
756     ASSERT(charinfo,0);
757     return bn_int_get(charinfo->charclass);
758     }
759    
760    
761     extern unsigned int d2charinfo_get_hardcore(t_d2charinfo_summary const * charinfo)
762     {
763     ASSERT(charinfo,0);
764     return charstatus_get_hardcore(bn_int_get(charinfo->charstatus));
765     }
766    
767    
768     extern unsigned int d2charinfo_get_dead(t_d2charinfo_summary const * charinfo)
769     {
770     ASSERT(charinfo,0);
771     return charstatus_get_dead(bn_int_get(charinfo->charstatus));
772     }
773    
774    
775     extern unsigned int d2charinfo_get_difficulty(t_d2charinfo_summary const * charinfo)
776     {
777     unsigned int difficulty;
778    
779     ASSERT(charinfo,0);
780     if (d2charinfo_get_expansion(charinfo)) {
781     difficulty=charstatus_get_difficulty_expansion(bn_int_get(charinfo->charstatus));
782     } else {
783     difficulty=charstatus_get_difficulty(bn_int_get(charinfo->charstatus));
784     }
785     if (difficulty>2) difficulty=2;
786     return difficulty;
787     }
788    
789     /* those functions should move to util.c */
790     extern int file_read(char const * filename, void * data, unsigned int * size)
791     {
792     FILE * fp;
793     unsigned int n;
794    
795     ASSERT(filename,-1);
796     ASSERT(data,-1);
797     ASSERT(size,-1);
798     if (!(fp=fopen(filename,"rb"))) {
799     eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
800     return -1;
801     }
802    
803     fseek(fp,0,SEEK_END); /* FIXME: check return value */
804     n=ftell(fp);
805     n=min(*size,n);
806     rewind(fp); /* FIXME: check return value */
807    
808     if (fread(data,1,n,fp)!=n) {
809     eventlog(eventlog_level_error,__FUNCTION__,"error reading file \"%s\" (fread: %s)",filename,pstrerror(errno));
810     fclose(fp);
811     return -1;
812     }
813     if (fclose(fp)<0) {
814     eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (fclose: %s)",filename,pstrerror(errno));
815     return -1;
816     }
817     *size=n;
818     return 0;
819     }
820    
821    
822     extern int file_write(char const * filename, void * data, unsigned int size)
823     {
824     FILE * fp;
825    
826     ASSERT(filename,-1);
827     ASSERT(data,-1);
828     ASSERT(size,-1);
829     if (!(fp=fopen(filename,"wb"))) {
830     eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for writing (fopen: %s)",filename,pstrerror(errno));
831     return -1;
832     }
833     if (fwrite(data,1,size,fp)!=size) {
834     eventlog(eventlog_level_error,__FUNCTION__,"error writing file \"%s\" (fwrite: %s)",filename,pstrerror(errno));
835     fclose(fp);
836     return -1;
837     }
838     if (fclose(fp)<0) {
839     eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after writing (fclose: %s)",filename,pstrerror(errno));
840     return -1;
841     }
842     return 0;
843     }

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