root/src/char/int_pet.c @ 23

Revision 1, 8.5 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 "char.h"
11#include "inter.h"
12#include "int_pet.h"
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18char pet_txt[1024]="save/pet.txt";
19
20#ifndef TXT_SQL_CONVERT
21static DBMap* pet_db; // int pet_id -> struct s_pet*
22static int pet_newid = 100;
23
24int inter_pet_tostr(char *str,struct s_pet *p)
25{
26        int len;
27
28        if(p->hungry < 0)
29                p->hungry = 0;
30        else if(p->hungry > 100)
31                p->hungry = 100;
32        if(p->intimate < 0)
33                p->intimate = 0;
34        else if(p->intimate > 1000)
35                p->intimate = 1000;
36
37        len=sprintf(str,"%d,%d,%s\t%d,%d,%d,%d,%d,%d,%d,%d,%d",
38                p->pet_id,p->class_,p->name,p->account_id,p->char_id,p->level,p->egg_id,
39                p->equip,p->intimate,p->hungry,p->rename_flag,p->incuvate);
40
41        return 0;
42}
43#endif //TXT_SQL_CONVERT
44int inter_pet_fromstr(char *str,struct s_pet *p)
45{
46        int s;
47        int tmp_int[16];
48        char tmp_str[256];
49
50        memset(p,0,sizeof(struct s_pet));
51
52        s=sscanf(str,"%d,%d,%[^\t]\t%d,%d,%d,%d,%d,%d,%d,%d,%d",&tmp_int[0],&tmp_int[1],tmp_str,&tmp_int[2],
53                &tmp_int[3],&tmp_int[4],&tmp_int[5],&tmp_int[6],&tmp_int[7],&tmp_int[8],&tmp_int[9],&tmp_int[10]);
54
55        if(s!=12)
56                return 1;
57
58        p->pet_id = tmp_int[0];
59        p->class_ = tmp_int[1];
60        memcpy(p->name,tmp_str,NAME_LENGTH);
61        p->account_id = tmp_int[2];
62        p->char_id = tmp_int[3];
63        p->level = tmp_int[4];
64        p->egg_id = tmp_int[5];
65        p->equip = tmp_int[6];
66        p->intimate = tmp_int[7];
67        p->hungry = tmp_int[8];
68        p->rename_flag = tmp_int[9];
69        p->incuvate = tmp_int[10];
70
71        if(p->hungry < 0)
72                p->hungry = 0;
73        else if(p->hungry > 100)
74                p->hungry = 100;
75        if(p->intimate < 0)
76                p->intimate = 0;
77        else if(p->intimate > 1000)
78                p->intimate = 1000;
79
80        return 0;
81}
82#ifndef TXT_SQL_CONVERT
83int inter_pet_init()
84{
85        char line[8192];
86        struct s_pet *p;
87        FILE *fp;
88        int c=0;
89
90        pet_db= idb_alloc(DB_OPT_RELEASE_DATA);
91
92        if( (fp=fopen(pet_txt,"r"))==NULL )
93                return 1;
94        while(fgets(line, sizeof(line), fp))
95        {
96                p = (struct s_pet*)aCalloc(sizeof(struct s_pet), 1);
97                if(p==NULL){
98                        ShowFatalError("int_pet: out of memory!\n");
99                        exit(EXIT_FAILURE);
100                }
101                memset(p,0,sizeof(struct s_pet));
102                if(inter_pet_fromstr(line,p)==0 && p->pet_id>0){
103                        if( p->pet_id >= pet_newid)
104                                pet_newid=p->pet_id+1;
105                        idb_put(pet_db,p->pet_id,p);
106                }else{
107                        ShowError("int_pet: broken data [%s] line %d\n",pet_txt,c);
108                        aFree(p);
109                }
110                c++;
111        }
112        fclose(fp);
113        return 0;
114}
115
116void inter_pet_final()
117{
118        pet_db->destroy(pet_db, NULL);
119        return;
120}
121
122int inter_pet_save_sub(DBKey key,void *data,va_list ap)
123{
124        char line[8192];
125        FILE *fp;
126        inter_pet_tostr(line,(struct s_pet *)data);
127        fp=va_arg(ap,FILE *);
128        fprintf(fp,"%s\n",line);
129        return 0;
130}
131
132int inter_pet_save()
133{
134        FILE *fp;
135        int lock;
136        if( (fp=lock_fopen(pet_txt,&lock))==NULL ){
137                ShowError("int_pet: can't write [%s] !!! data is lost !!!\n",pet_txt);
138                return 1;
139        }
140        pet_db->foreach(pet_db,inter_pet_save_sub,fp);
141        lock_fclose(fp,pet_txt,&lock);
142        return 0;
143}
144
145int inter_pet_delete(int pet_id)
146{
147        struct s_pet *p;
148        p = (struct s_pet*)idb_get(pet_db,pet_id);
149        if( p == NULL)
150                return 1;
151        else {
152                idb_remove(pet_db,pet_id);
153                ShowInfo("Deleted pet (pet_id: %d)\n",pet_id);
154        }
155        return 0;
156}
157
158int mapif_pet_created(int fd,int account_id,struct s_pet *p)
159{
160        WFIFOHEAD(fd, 11);
161        WFIFOW(fd,0)=0x3880;
162        WFIFOL(fd,2)=account_id;
163        if(p!=NULL){
164                WFIFOB(fd,6)=0;
165                WFIFOL(fd,7)=p->pet_id;
166                ShowInfo("Created pet (%d - %s)\n",p->pet_id,p->name);
167        }else{
168                WFIFOB(fd,6)=1;
169                WFIFOL(fd,7)=0;
170        }
171        WFIFOSET(fd,11);
172
173        return 0;
174}
175
176int mapif_pet_info(int fd,int account_id,struct s_pet *p)
177{
178        WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
179        WFIFOW(fd,0)=0x3881;
180        WFIFOW(fd,2)=sizeof(struct s_pet) + 9;
181        WFIFOL(fd,4)=account_id;
182        WFIFOB(fd,8)=0;
183        memcpy(WFIFOP(fd,9),p,sizeof(struct s_pet));
184        WFIFOSET(fd,WFIFOW(fd,2));
185
186        return 0;
187}
188
189int mapif_pet_noinfo(int fd,int account_id)
190{
191        WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
192        WFIFOW(fd,0)=0x3881;
193        WFIFOW(fd,2)=sizeof(struct s_pet) + 9;
194        WFIFOL(fd,4)=account_id;
195        WFIFOB(fd,8)=1;
196        memset(WFIFOP(fd,9),0,sizeof(struct s_pet));
197        WFIFOSET(fd,WFIFOW(fd,2));
198
199        return 0;
200}
201
202int mapif_save_pet_ack(int fd,int account_id,int flag)
203{
204        WFIFOHEAD(fd, 7);
205        WFIFOW(fd,0)=0x3882;
206        WFIFOL(fd,2)=account_id;
207        WFIFOB(fd,6)=flag;
208        WFIFOSET(fd,7);
209
210        return 0;
211}
212
213int mapif_delete_pet_ack(int fd,int flag)
214{
215        WFIFOHEAD(fd, 3);
216        WFIFOW(fd,0)=0x3883;
217        WFIFOB(fd,2)=flag;
218        WFIFOSET(fd,3);
219
220        return 0;
221}
222
223int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id,
224        short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
225{
226        struct s_pet *p;
227        p= (struct s_pet *) aCalloc(sizeof(struct s_pet), 1);
228        if(p==NULL){
229                ShowFatalError("int_pet: out of memory !\n");
230                mapif_pet_created(fd,account_id,NULL);
231                return 0;
232        }
233//      memset(p,0,sizeof(struct s_pet)); unnecessary after aCalloc [Skotlex]
234        p->pet_id = pet_newid++;
235        memcpy(p->name,pet_name,NAME_LENGTH);
236        if(incuvate == 1)
237                p->account_id = p->char_id = 0;
238        else {
239                p->account_id = account_id;
240                p->char_id = char_id;
241        }
242        p->class_ = pet_class;
243        p->level = pet_lv;
244        p->egg_id = pet_egg_id;
245        p->equip = pet_equip;
246        p->intimate = intimate;
247        p->hungry = hungry;
248        p->rename_flag = rename_flag;
249        p->incuvate = incuvate;
250
251        if(p->hungry < 0)
252                p->hungry = 0;
253        else if(p->hungry > 100)
254                p->hungry = 100;
255        if(p->intimate < 0)
256                p->intimate = 0;
257        else if(p->intimate > 1000)
258                p->intimate = 1000;
259
260        idb_put(pet_db,p->pet_id,p);
261
262        mapif_pet_created(fd,account_id,p);
263
264        return 0;
265}
266
267int mapif_load_pet(int fd,int account_id,int char_id,int pet_id)
268{
269        struct s_pet *p;
270        p = (struct s_pet*)idb_get(pet_db,pet_id);
271        if(p!=NULL) {
272                if(p->incuvate == 1) {
273                        p->account_id = p->char_id = 0;
274                        mapif_pet_info(fd,account_id,p);
275                }
276                else if(account_id == p->account_id && char_id == p->char_id)
277                        mapif_pet_info(fd,account_id,p);
278                else
279                        mapif_pet_noinfo(fd,account_id);
280        }
281        else
282                mapif_pet_noinfo(fd,account_id);
283
284        return 0;
285}
286
287static void* create_pet(DBKey key, va_list args) {
288        struct s_pet *p;
289        p=(struct s_pet *)aCalloc(sizeof(struct s_pet),1);
290        p->pet_id = key.i;
291        return p;
292}
293int mapif_save_pet(int fd,int account_id,struct s_pet *data)
294{
295        struct s_pet *p;
296        int pet_id, len;
297        RFIFOHEAD(fd);
298        len=RFIFOW(fd,2);
299       
300        if(sizeof(struct s_pet)!=len-8) {
301                ShowError("inter pet: data size error %d %d\n",sizeof(struct s_pet),len-8);
302        }
303        else{
304                pet_id = data->pet_id;
305                if (pet_id == 0)
306                        pet_id = data->pet_id = pet_newid++;
307                p = (struct s_pet*)idb_ensure(pet_db,pet_id,create_pet);
308                if(data->hungry < 0)
309                        data->hungry = 0;
310                else if(data->hungry > 100)
311                        data->hungry = 100;
312                if(data->intimate < 0)
313                        data->intimate = 0;
314                else if(data->intimate > 1000)
315                        data->intimate = 1000;
316                memcpy(p,data,sizeof(struct s_pet));
317                if(p->incuvate == 1)
318                        p->account_id = p->char_id = 0;
319
320                mapif_save_pet_ack(fd,account_id,0);
321        }
322
323        return 0;
324}
325
326int mapif_delete_pet(int fd,int pet_id)
327{
328        mapif_delete_pet_ack(fd,inter_pet_delete(pet_id));
329
330        return 0;
331}
332
333int mapif_parse_CreatePet(int fd)
334{
335        RFIFOHEAD(fd);
336        mapif_create_pet(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOW(fd,14),RFIFOW(fd,16),RFIFOW(fd,18),
337                RFIFOW(fd,20),RFIFOB(fd,22),RFIFOB(fd,23),(char*)RFIFOP(fd,24));
338        return 0;
339}
340
341int mapif_parse_LoadPet(int fd)
342{
343        RFIFOHEAD(fd);
344        mapif_load_pet(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
345        return 0;
346}
347
348int mapif_parse_SavePet(int fd)
349{
350        RFIFOHEAD(fd);
351        mapif_save_pet(fd,RFIFOL(fd,4),(struct s_pet *)RFIFOP(fd,8));
352        return 0;
353}
354
355int mapif_parse_DeletePet(int fd)
356{
357        RFIFOHEAD(fd);
358        mapif_delete_pet(fd,RFIFOL(fd,2));
359        return 0;
360}
361
362// map server ‚©‚ç‚̒ʐM
363// E‚PƒpƒPƒbƒg‚̂݉ðÍ‚·‚邱‚Æ
364// EƒpƒPƒbƒg’·ƒf[ƒ^‚Íinter.c‚ɃZƒbƒg‚µ‚Ä‚š‚­‚±‚Æ
365// EƒpƒPƒbƒg’·ƒ`ƒFƒbƒN‚âARFIFOSKIP‚͌Ăяo‚µŒ³‚ōs‚í‚ê‚é‚̂ōs‚Á‚Ă͂Ȃç‚È‚¢
366// EƒGƒ‰[‚È‚ç0(false)A‚»‚€‚łȂ¢‚È‚ç1(true)‚ð‚©‚Š‚³‚È‚¯‚ê‚΂Ȃç‚È‚¢
367int inter_pet_parse_frommap(int fd)
368{
369        RFIFOHEAD(fd);
370        switch(RFIFOW(fd,0)){
371        case 0x3080: mapif_parse_CreatePet(fd); break;
372        case 0x3081: mapif_parse_LoadPet(fd); break;
373        case 0x3082: mapif_parse_SavePet(fd); break;
374        case 0x3083: mapif_parse_DeletePet(fd); break;
375        default:
376                return 0;
377        }
378        return 1;
379}
380#endif //TXT_SQL_CONVERT
Note: See TracBrowser for help on using the browser.