root/src/char/int_storage.c

Revision 1, 13.0 kB (checked in by jinshiro, 17 years ago)
Line 
1// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
2// For more information, see LICENCE in the main folder
3
4#include "../common/mmo.h"
5#include "../common/malloc.h"
6#include "../common/socket.h"
7#include "../common/db.h"
8#include "../common/lock.h"
9#include "../common/showmsg.h"
10#include "../common/utils.h"
11#include "char.h"
12#include "inter.h"
13#include "int_storage.h"
14#include "int_pet.h"
15#include "int_guild.h"
16
17#include <stdio.h>
18#include <string.h>
19#include <stdlib.h>
20
21// ƒtƒ@ƒCƒ‹–Œ‚̃fƒtƒHƒ‹ƒg
22// inter_config_read()‚ōĐݒ肳‚ê‚é
23char storage_txt[1024]="save/storage.txt";
24char guild_storage_txt[1024]="save/g_storage.txt";
25
26#ifndef TXT_SQL_CONVERT
27static DBMap* storage_db; // int account_id -> struct storage*
28static DBMap* guild_storage_db; // int guild_id -> struct guild_storage*
29
30// ‘qŒÉƒf[ƒ^‚ð•¶Žš—ñ‚ɕϊ·
31int storage_tostr(char *str,struct storage *p)
32{
33        int i,j,f=0;
34        char *str_p = str;
35        str_p += sprintf(str_p,"%d,%d\t",p->account_id,p->storage_amount);
36
37        for(i=0;i<MAX_STORAGE;i++)
38                if( (p->storage_[i].nameid) && (p->storage_[i].amount) ){
39                        str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d",
40                                p->storage_[i].id,p->storage_[i].nameid,p->storage_[i].amount,p->storage_[i].equip,
41                                p->storage_[i].identify,p->storage_[i].refine,p->storage_[i].attribute);
42                        for(j=0; j<MAX_SLOTS; j++)
43                                str_p += sprintf(str_p,",%d",p->storage_[i].card[j]);
44                        str_p += sprintf(str_p," ");
45                        f++;
46                }
47
48        *(str_p++)='\t';
49
50        *str_p='\0';
51        if(!f)
52                str[0]=0;
53        return 0;
54}
55#endif //TXT_SQL_CONVERT
56// •¶Žš—ñ‚ð‘qŒÉƒf[ƒ^‚ɕϊ·
57int storage_fromstr(char *str,struct storage *p)
58{
59        int tmp_int[256];
60        char tmp_str[256];
61        int set,next,len,i,j;
62
63        set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next);
64        p->storage_amount=tmp_int[1];
65
66        if(set!=2)
67                return 1;
68        if(str[next]=='\n' || str[next]=='\r')
69                return 0;
70        next++;
71        for(i=0;str[next] && str[next]!='\t' && i < MAX_STORAGE;i++){
72                if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d%[0-9,-]%n",
73                      &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
74                      &tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) == 8) {
75                        p->storage_[i].id = tmp_int[0];
76                        p->storage_[i].nameid = tmp_int[1];
77                        p->storage_[i].amount = tmp_int[2];
78                        p->storage_[i].equip = tmp_int[3];
79                        p->storage_[i].identify = tmp_int[4];
80                        p->storage_[i].refine = tmp_int[5];
81                        p->storage_[i].attribute = tmp_int[6];
82                       
83                        for(j = 0; j < MAX_SLOTS && tmp_str && sscanf(tmp_str, ",%d%[0-9,-]",&tmp_int[0], tmp_str) > 0; j++)
84                                p->storage_[i].card[j] = tmp_int[0];
85                       
86                        next += len;
87                        if (str[next] == ' ')
88                                next++;
89                }
90                else return 1;
91        }
92        if (i >= MAX_STORAGE && str[next] && str[next]!='\t')
93                ShowWarning("storage_fromstr: Found a storage line with more items than MAX_STORAGE (%d), remaining items have been discarded!\n", MAX_STORAGE);
94        return 0;
95}
96#ifndef TXT_SQL_CONVERT
97int guild_storage_tostr(char *str,struct guild_storage *p)
98{
99        int i,j,f=0;
100        char *str_p = str;
101        str_p+=sprintf(str,"%d,%d\t",p->guild_id,p->storage_amount);
102
103        for(i=0;i<MAX_GUILD_STORAGE;i++)
104                if( (p->storage_[i].nameid) && (p->storage_[i].amount) ){
105                        str_p += sprintf(str_p,"%d,%d,%d,%d,%d,%d,%d",
106                                p->storage_[i].id,p->storage_[i].nameid,p->storage_[i].amount,p->storage_[i].equip,
107                                p->storage_[i].identify,p->storage_[i].refine,p->storage_[i].attribute);
108                        for(j=0; j<MAX_SLOTS; j++)
109                                str_p += sprintf(str_p,",%d",p->storage_[i].card[j]);
110                        str_p += sprintf(str_p," ");
111                        f++;
112                }
113
114        *(str_p++)='\t';
115
116        *str_p='\0';
117        if(!f)
118                str[0]=0;
119        return 0;
120}
121#endif //TXT_SQL_CONVERT
122int guild_storage_fromstr(char *str,struct guild_storage *p)
123{
124        int tmp_int[256];
125        char tmp_str[256];
126        int set,next,len,i,j;
127
128        set=sscanf(str,"%d,%d%n",&tmp_int[0],&tmp_int[1],&next);
129        p->storage_amount=tmp_int[1];
130
131        if(set!=2)
132                return 1;
133        if(str[next]=='\n' || str[next]=='\r')
134                return 0;
135        next++;
136        for(i=0;str[next] && str[next]!='\t' && i < MAX_GUILD_STORAGE;i++){
137                if(sscanf(str + next, "%d,%d,%d,%d,%d,%d,%d%[0-9,-]%n",
138                        &tmp_int[0], &tmp_int[1], &tmp_int[2], &tmp_int[3],
139                        &tmp_int[4], &tmp_int[5], &tmp_int[6], tmp_str, &len) == 8)
140                {
141                        p->storage_[i].id = tmp_int[0];
142                        p->storage_[i].nameid = tmp_int[1];
143                        p->storage_[i].amount = tmp_int[2];
144                        p->storage_[i].equip = tmp_int[3];
145                        p->storage_[i].identify = tmp_int[4];
146                        p->storage_[i].refine = tmp_int[5];
147                        p->storage_[i].attribute = tmp_int[6];
148                        for(j = 0; j < MAX_SLOTS && tmp_str && sscanf(tmp_str, ",%d%[0-9,-]",&tmp_int[0], tmp_str) > 0; j++)
149                                p->storage_[i].card[j] = tmp_int[0];
150                        next += len;
151                        if (str[next] == ' ')
152                                next++;
153                }
154                else return 1;
155        }
156        if (i >= MAX_GUILD_STORAGE && str[next] && str[next]!='\t')
157                ShowWarning("guild_storage_fromstr: Found a storage line with more items than MAX_GUILD_STORAGE (%d), remaining items have been discarded!\n", MAX_GUILD_STORAGE);
158        return 0;
159}
160#ifndef TXT_SQL_CONVERT
161static void* create_storage(DBKey key, va_list args) {
162        struct storage *s;
163        s = (struct storage *) aCalloc(sizeof(struct storage), 1);
164        s->account_id=key.i;
165        return s;
166}
167
168// ƒAƒJƒEƒ“ƒg‚©‚ç‘qŒÉƒf[ƒ^ƒCƒ“ƒfƒbƒNƒX‚𓟂éiV‹K‘qŒÉ’ljÁ‰Â”\j
169struct storage *account2storage(int account_id)
170{
171        struct storage *s;
172        s = (struct storage*)idb_ensure(storage_db, account_id, create_storage);
173        return s;
174}
175
176static void* create_guildstorage(DBKey key, va_list args) {
177        struct guild_storage *gs = NULL;
178        gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1);
179        gs->guild_id=key.i;
180        return gs;
181}
182
183struct guild_storage *guild2storage(int guild_id)
184{
185        struct guild_storage *gs = NULL;
186        if(inter_guild_search(guild_id) != NULL)
187                gs = (struct guild_storage*)idb_ensure(guild_storage_db, guild_id, create_guildstorage);
188        return gs;
189}
190
191//---------------------------------------------------------
192// ‘qŒÉƒf[ƒ^‚ð“ǂݍž‚Þ
193int inter_storage_init()
194{
195        char line[65536];
196        int c=0,tmp_int;
197        struct storage *s;
198        struct guild_storage *gs;
199        FILE *fp;
200
201        storage_db = idb_alloc(DB_OPT_RELEASE_DATA);
202
203        fp=fopen(storage_txt,"r");
204        if(fp==NULL){
205                ShowError("can't read : %s\n",storage_txt);
206                return 1;
207        }
208        while(fgets(line, sizeof(line), fp))
209        {
210                sscanf(line,"%d",&tmp_int);
211                s = (struct storage*)aCalloc(sizeof(struct storage), 1);
212                if(s==NULL){
213                        ShowFatalError("int_storage: out of memory!\n");
214                        exit(EXIT_FAILURE);
215                }
216//              memset(s,0,sizeof(struct storage)); aCalloc does this...
217                s->account_id=tmp_int;
218                if(s->account_id > 0 && storage_fromstr(line,s) == 0) {
219                        idb_put(storage_db,s->account_id,s);
220                }
221                else{
222                        ShowError("int_storage: broken data [%s] line %d\n",storage_txt,c);
223                        aFree(s);
224                }
225                c++;
226        }
227        fclose(fp);
228
229        c = 0;
230        guild_storage_db = idb_alloc(DB_OPT_RELEASE_DATA);
231
232        fp=fopen(guild_storage_txt,"r");
233        if(fp==NULL){
234                ShowError("can't read : %s\n",guild_storage_txt);
235                return 1;
236        }
237        while(fgets(line, sizeof(line), fp))
238        {
239                sscanf(line,"%d",&tmp_int);
240                gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
241                if(gs==NULL){
242                        ShowFatalError("int_storage: out of memory!\n");
243                        exit(EXIT_FAILURE);
244                }
245//              memset(gs,0,sizeof(struct guild_storage)); aCalloc...
246                gs->guild_id=tmp_int;
247                if(gs->guild_id > 0 && guild_storage_fromstr(line,gs) == 0) {
248                        idb_put(guild_storage_db,gs->guild_id,gs);
249                }
250                else{
251                        ShowError("int_storage: broken data [%s] line %d\n",guild_storage_txt,c);
252                        aFree(gs);
253                }
254                c++;
255        }
256        fclose(fp);
257
258        return 0;
259}
260
261void inter_storage_final() {
262        storage_db->destroy(storage_db, NULL);
263        guild_storage_db->destroy(guild_storage_db, NULL);
264        return;
265}
266
267int inter_storage_save_sub(DBKey key,void *data,va_list ap)
268{
269        char line[65536];
270        FILE *fp;
271        storage_tostr(line,(struct storage *)data);
272        fp=va_arg(ap,FILE *);
273        if(*line)
274                fprintf(fp,"%s\n",line);
275        return 0;
276}
277//---------------------------------------------------------
278// ‘qŒÉƒf[ƒ^‚ð‘‚«ž‚Þ
279int inter_storage_save()
280{
281        FILE *fp;
282        int lock;
283        if( (fp=lock_fopen(storage_txt,&lock))==NULL ){
284                ShowError("int_storage: can't write [%s] !!! data is lost !!!\n",storage_txt);
285                return 1;
286        }
287        storage_db->foreach(storage_db,inter_storage_save_sub,fp);
288        lock_fclose(fp,storage_txt,&lock);
289        return 0;
290}
291
292int inter_guild_storage_save_sub(DBKey key,void *data,va_list ap)
293{
294        char line[65536];
295        FILE *fp;
296        if(inter_guild_search(((struct guild_storage *)data)->guild_id) != NULL) {
297                guild_storage_tostr(line,(struct guild_storage *)data);
298                fp=va_arg(ap,FILE *);
299                if(*line)
300                        fprintf(fp,"%s\n",line);
301        }
302        return 0;
303}
304//---------------------------------------------------------
305// ‘qŒÉƒf[ƒ^‚ð‘‚«ž‚Þ
306int inter_guild_storage_save()
307{
308        FILE *fp;
309        int  lock;
310        if( (fp=lock_fopen(guild_storage_txt,&lock))==NULL ){
311                ShowError("int_storage: can't write [%s] !!! data is lost !!!\n",guild_storage_txt);
312                return 1;
313        }
314        guild_storage_db->foreach(guild_storage_db,inter_guild_storage_save_sub,fp);
315        lock_fclose(fp,guild_storage_txt,&lock);
316        return 0;
317}
318
319// ‘qŒÉƒf[ƒ^íœ
320int inter_storage_delete(int account_id)
321{
322        struct storage *s = (struct storage*)idb_get(storage_db,account_id);
323        if(s) {
324                int i;
325                for(i=0;i<s->storage_amount;i++){
326                        if(s->storage_[i].card[0] == (short)0xff00)
327                                inter_pet_delete( MakeDWord(s->storage_[i].card[1],s->storage_[i].card[2]) );
328                }
329                idb_remove(storage_db,account_id);
330        }
331        return 0;
332}
333
334// ƒMƒ‹ƒh‘qŒÉƒf[ƒ^íœ
335int inter_guild_storage_delete(int guild_id)
336{
337        struct guild_storage *gs = (struct guild_storage*)idb_get(guild_storage_db,guild_id);
338        if(gs) {
339                int i;
340                for(i=0;i<gs->storage_amount;i++){
341                        if(gs->storage_[i].card[0] == (short)0xff00)
342                                inter_pet_delete( MakeDWord(gs->storage_[i].card[1],gs->storage_[i].card[2]) );
343                }
344                idb_remove(guild_storage_db,guild_id);
345        }
346        return 0;
347}
348
349//---------------------------------------------------------
350// map server‚ւ̒ʐM
351
352// ‘qŒÉƒf[ƒ^‚Ì‘—M
353int mapif_load_storage(int fd,int account_id)
354{
355        struct storage *s=account2storage(account_id);
356        WFIFOHEAD(fd, sizeof(struct storage)+8);
357        WFIFOW(fd,0)=0x3810;
358        WFIFOW(fd,2)=sizeof(struct storage)+8;
359        WFIFOL(fd,4)=account_id;
360        memcpy(WFIFOP(fd,8),s,sizeof(struct storage));
361        WFIFOSET(fd,WFIFOW(fd,2));
362        return 0;
363}
364// ‘qŒÉƒf[ƒ^•Û‘¶Š®—¹‘—M
365int mapif_save_storage_ack(int fd,int account_id)
366{
367        WFIFOHEAD(fd, 7);
368        WFIFOW(fd,0)=0x3811;
369        WFIFOL(fd,2)=account_id;
370        WFIFOB(fd,6)=0;
371        WFIFOSET(fd,7);
372        return 0;
373}
374
375int mapif_load_guild_storage(int fd,int account_id,int guild_id)
376{
377        struct guild_storage *gs=guild2storage(guild_id);
378        WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
379        WFIFOW(fd,0)=0x3818;
380        if(gs) {
381                WFIFOW(fd,2)=sizeof(struct guild_storage)+12;
382                WFIFOL(fd,4)=account_id;
383                WFIFOL(fd,8)=guild_id;
384                memcpy(WFIFOP(fd,12),gs,sizeof(struct guild_storage));
385        }
386        else {
387                WFIFOW(fd,2)=12;
388                WFIFOL(fd,4)=account_id;
389                WFIFOL(fd,8)=0;
390        }
391        WFIFOSET(fd,WFIFOW(fd,2));
392
393        return 0;
394}
395int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
396{
397        WFIFOHEAD(fd, 11);
398        WFIFOW(fd,0)=0x3819;
399        WFIFOL(fd,2)=account_id;
400        WFIFOL(fd,6)=guild_id;
401        WFIFOB(fd,10)=fail;
402        WFIFOSET(fd,11);
403        return 0;
404}
405
406//---------------------------------------------------------
407// map server‚©‚ç‚̒ʐM
408
409// ‘qŒÉƒf[ƒ^—v‹ŽóM
410int mapif_parse_LoadStorage(int fd)
411{
412        RFIFOHEAD(fd);
413        mapif_load_storage(fd,RFIFOL(fd,2));
414        return 0;
415}
416// ‘qŒÉƒf[ƒ^ŽóM••Û‘¶
417int mapif_parse_SaveStorage(int fd)
418{
419        struct storage *s;
420        int account_id, len;
421        RFIFOHEAD(fd);
422        account_id=RFIFOL(fd,4);
423        len=RFIFOW(fd,2);
424        if(sizeof(struct storage)!=len-8){
425                ShowError("inter storage: data size error %d %d\n",sizeof(struct storage),len-8);
426        }
427        else {
428                s=account2storage(account_id);
429                memcpy(s,RFIFOP(fd,8),sizeof(struct storage));
430                mapif_save_storage_ack(fd,account_id);
431        }
432        return 0;
433}
434
435int mapif_parse_LoadGuildStorage(int fd)
436{
437        RFIFOHEAD(fd);
438        mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
439        return 0;
440}
441int mapif_parse_SaveGuildStorage(int fd)
442{
443        struct guild_storage *gs;
444        int guild_id, len;
445        RFIFOHEAD(fd);
446        guild_id=RFIFOL(fd,8);
447        len=RFIFOW(fd,2);
448        if(sizeof(struct guild_storage)!=len-12){
449                ShowError("inter storage: data size error %d %d\n",sizeof(struct guild_storage),len-12);
450        }
451        else {
452                gs=guild2storage(guild_id);
453                if(gs) {
454                        memcpy(gs,RFIFOP(fd,12),sizeof(struct guild_storage));
455                        mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,0);
456                }
457                else
458                        mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,1);
459        }
460        return 0;
461}
462
463// map server ‚©‚ç‚̒ʐM
464// E‚PƒpƒPƒbƒg‚̂݉ðÍ‚·‚邱‚Æ
465// EƒpƒPƒbƒg’·ƒf[ƒ^‚Íinter.c‚ɃZƒbƒg‚µ‚Ä‚š‚­‚±‚Æ
466// EƒpƒPƒbƒg’·ƒ`ƒFƒbƒN‚âARFIFOSKIP‚͌Ăяo‚µŒ³‚ōs‚í‚ê‚é‚̂ōs‚Á‚Ă͂Ȃç‚È‚¢
467// EƒGƒ‰[‚È‚ç0(false)A‚»‚€‚łȂ¢‚È‚ç1(true)‚ð‚©‚Š‚³‚È‚¯‚ê‚΂Ȃç‚È‚¢
468int inter_storage_parse_frommap(int fd)
469{
470        RFIFOHEAD(fd);
471        switch(RFIFOW(fd,0)){
472        case 0x3010: mapif_parse_LoadStorage(fd); break;
473        case 0x3011: mapif_parse_SaveStorage(fd); break;
474        case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
475        case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
476        default:
477                return 0;
478        }
479        return 1;
480}
481#endif //TXT_SQL_CONVERT
Note: See TracBrowser for help on using the browser.