root/src/char/int_homun.c @ 5

Revision 1, 8.9 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_homun.h"
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18char homun_txt[1024]="save/homun.txt";
19
20static DBMap* homun_db; // int hom_id -> struct s_homunculus*
21static int homun_newid = 100;
22
23int inter_homun_tostr(char *str,struct s_homunculus *p)
24{
25        int i;
26
27        str+=sprintf(str,"%d,%d\t%s\t%d,%d,%d,%d,%d,"
28                "%u,%d,%d,%d,"
29                "%u,%d,%d,"
30                "%d,%d,%d,%d,%d,%d\t",
31                p->hom_id, p->class_, p->name,
32                p->char_id, p->hp, p->max_hp, p->sp, p->max_sp,
33                p->intimacy, p->hunger, p->skillpts, p->level,
34                p->exp, p->rename_flag, p->vaporize,
35                p->str, p->agi, p->vit, p->int_, p->dex, p->luk);
36
37        for (i = 0; i < MAX_HOMUNSKILL; i++)
38        {
39                if (p->hskill[i].id && !p->hskill[i].flag)
40                        str+=sprintf(str,"%d,%d,", p->hskill[i].id, p->hskill[i].lv);
41        }
42
43        return 0;
44}
45
46int inter_homun_fromstr(char *str,struct s_homunculus *p)
47{
48        int i, next, len;
49        int tmp_int[25];
50        unsigned int tmp_uint[5];
51        char tmp_str[256];
52
53        memset(p,0,sizeof(struct s_homunculus));
54
55        i=sscanf(str,"%d,%d\t%127[^\t]\t%d,%d,%d,%d,%d,"
56                "%u,%d,%d,%d,"
57                "%u,%d,%d,"
58                "%d,%d,%d,%d,%d,%d\t%n",
59                &tmp_int[0],&tmp_int[1],tmp_str,
60                &tmp_int[2],&tmp_int[3],&tmp_int[4],&tmp_int[5],&tmp_int[6],
61                &tmp_uint[0],&tmp_int[7],&tmp_int[8],&tmp_int[9],
62                &tmp_uint[1],&tmp_int[10],&tmp_int[11],
63                &tmp_int[12],&tmp_int[13],&tmp_int[14],&tmp_int[15],&tmp_int[16],&tmp_int[17],
64                &next);
65
66        if(i!=21)
67                return 1;
68
69        p->hom_id = tmp_int[0];
70        p->class_ = tmp_int[1];
71        memcpy(p->name, tmp_str, NAME_LENGTH);
72
73        p->char_id = tmp_int[2];
74        p->hp = tmp_int[3];
75        p->max_hp = tmp_int[4];
76        p->sp = tmp_int[5];
77        p->max_sp = tmp_int[6];
78
79        p->intimacy = tmp_uint[0];
80        p->hunger = tmp_int[7];
81        p->skillpts = tmp_int[8];
82        p->level = tmp_int[9];
83
84        p->exp = tmp_uint[1];
85        p->rename_flag = tmp_int[10];
86        p->vaporize = tmp_int[11];
87
88        p->str = tmp_int[12];
89        p->agi = tmp_int[13];
90        p->vit = tmp_int[14];
91        p->int_= tmp_int[15];
92        p->dex = tmp_int[16];
93        p->luk = tmp_int[17];
94
95        //Read skills.
96        while(str[next] && str[next] != '\n' && str[next] != '\r') {
97                if (sscanf(str+next, "%d,%d,%n", &tmp_int[0], &tmp_int[1], &len) != 2)
98                        return 2;
99
100                if (tmp_int[0] >= HM_SKILLBASE && tmp_int[0] < HM_SKILLBASE+MAX_HOMUNSKILL)
101                {
102                        i = tmp_int[0] - HM_SKILLBASE;
103                        p->hskill[i].id = tmp_int[0];
104                        p->hskill[i].lv = tmp_int[1];
105                } else
106                        ShowError("Read Homun: Unsupported Skill ID %d for homunculus (Homun ID=%d)\n", tmp_int[0], p->hom_id);
107                next += len;
108                if (str[next] == ' ')
109                        next++;
110        }
111        return 0;
112}
113
114int inter_homun_init()
115{
116        char line[8192];
117        struct s_homunculus *p;
118        FILE *fp;
119        int c=0;
120
121        homun_db= idb_alloc(DB_OPT_RELEASE_DATA);
122
123        if( (fp=fopen(homun_txt,"r"))==NULL )
124                return 1;
125        while(fgets(line, sizeof(line), fp))
126        {
127                p = (struct s_homunculus*)aCalloc(sizeof(struct s_homunculus), 1);
128                if(p==NULL){
129                        ShowFatalError("int_homun: out of memory!\n");
130                        exit(EXIT_FAILURE);
131                }
132                if(inter_homun_fromstr(line,p)==0 && p->hom_id>0){
133                        if( p->hom_id >= homun_newid)
134                                homun_newid=p->hom_id+1;
135                        idb_put(homun_db,p->hom_id,p);
136                }else{
137                        ShowError("int_homun: broken data [%s] line %d\n",homun_txt,c);
138                        aFree(p);
139                }
140                c++;
141        }
142        fclose(fp);
143        return 0;
144}
145
146void inter_homun_final()
147{
148        homun_db->destroy(homun_db, NULL);
149        return;
150}
151
152int inter_homun_save_sub(DBKey key,void *data,va_list ap)
153{
154        char line[8192];
155        FILE *fp;
156        inter_homun_tostr(line,(struct s_homunculus *)data);
157        fp=va_arg(ap,FILE *);
158        fprintf(fp,"%s\n",line);
159        return 0;
160}
161
162int inter_homun_save()
163{
164        FILE *fp;
165        int lock;
166        if( (fp=lock_fopen(homun_txt,&lock))==NULL ){
167                ShowError("int_homun: can't write [%s] !!! data is lost !!!\n",homun_txt);
168                return 1;
169        }
170        homun_db->foreach(homun_db,inter_homun_save_sub,fp);
171        lock_fclose(fp,homun_txt,&lock);
172        return 0;
173}
174
175int inter_homun_delete(int hom_id)
176{
177        struct s_homunculus *p;
178        p = (struct s_homunculus*)idb_get(homun_db,hom_id);
179        if( p == NULL)
180                return 0;
181        idb_remove(homun_db,hom_id);
182        ShowInfo("Deleted homun (hom_id: %d)\n",hom_id);
183        return 1;
184}
185
186int mapif_homun_created(int fd,int account_id, struct s_homunculus *p)
187{
188        WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
189        WFIFOW(fd, 0) =0x3890;
190        WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
191        WFIFOL(fd,4) = account_id;
192        WFIFOB(fd,8)= p->hom_id?1:0;
193        memcpy(WFIFOP(fd,9), p, sizeof(struct s_homunculus));
194        WFIFOSET(fd, WFIFOW(fd,2));
195        return 0;
196}
197
198int mapif_homun_info(int fd,int account_id,struct s_homunculus *p)
199{
200        WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
201        WFIFOW(fd,0) = 0x3891;
202        WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
203        WFIFOL(fd,4) = account_id;
204        WFIFOB(fd,8) = 1; // account loaded with success
205
206        memcpy(WFIFOP(fd,9), p, sizeof(struct s_homunculus));
207        WFIFOSET(fd,WFIFOW(fd,2));
208        return 0;
209}
210
211int mapif_homun_noinfo(int fd,int account_id)
212{
213        WFIFOHEAD(fd,sizeof(struct s_homunculus) + 9);
214        WFIFOW(fd,0)=0x3891;
215        WFIFOW(fd,2)=sizeof(struct s_homunculus) + 9;
216        WFIFOL(fd,4)=account_id;
217        WFIFOB(fd,8)=0;
218        memset(WFIFOP(fd,9),0,sizeof(struct s_homunculus));
219        WFIFOSET(fd,WFIFOW(fd,2));
220
221        return 0;
222}
223
224int mapif_save_homun_ack(int fd,int account_id,int flag)
225{
226        WFIFOHEAD(fd, 7);
227        WFIFOW(fd,0)=0x3892;
228        WFIFOL(fd,2)=account_id;
229        WFIFOB(fd,6)=flag;
230        WFIFOSET(fd,7);
231        return 0;
232}
233
234int mapif_delete_homun_ack(int fd,int flag)
235{
236        WFIFOHEAD(fd, 3);
237        WFIFOW(fd,0)=0x3893;
238        WFIFOB(fd,2)=flag;
239        WFIFOSET(fd,3);
240        return 0;
241}
242
243int mapif_rename_homun_ack(int fd, int account_id, int char_id, int flag, char *name){
244        WFIFOHEAD(fd, NAME_LENGTH+12);
245        WFIFOW(fd, 0) =0x3894;
246        WFIFOL(fd, 2) =account_id;
247        WFIFOL(fd, 6) =char_id;
248        WFIFOB(fd, 10) =flag;
249        memcpy(WFIFOP(fd, 11), name, NAME_LENGTH);
250        WFIFOSET(fd, NAME_LENGTH+12);
251
252        return 0;
253}
254
255int mapif_create_homun(int fd)
256{
257        struct s_homunculus *p;
258        p= (struct s_homunculus *) aCalloc(sizeof(struct s_homunculus), 1);
259        if(p==NULL){
260                ShowFatalError("int_homun: out of memory !\n");
261                //Sending the received data will pass hom_id == 0 <- fail.
262                mapif_homun_created(fd,RFIFOL(fd,4),(struct s_homunculus*)RFIFOP(fd,8));
263                return 0;
264        }
265        memcpy(p, RFIFOP(fd,8), sizeof(struct s_homunculus));
266        p->hom_id = homun_newid++; //New ID
267        idb_put(homun_db,p->hom_id,p);
268        mapif_homun_created(fd,RFIFOL(fd,4),p);
269        return 0;
270}
271
272int mapif_load_homun(int fd)
273{
274        struct s_homunculus *p;
275        int account_id;
276        account_id = RFIFOL(fd,2);
277
278        p = (struct s_homunculus*)idb_get(homun_db,RFIFOL(fd,6));
279        if(p==NULL) {
280                mapif_homun_noinfo(fd,account_id);
281                return 0;
282        }
283        mapif_homun_info(fd,account_id,p);
284        return 0;
285}
286
287static void* create_homun(DBKey key, va_list args) {
288        struct s_homunculus *p;
289        p=(struct s_homunculus *)aCalloc(sizeof(struct s_homunculus),1);
290        p->hom_id = key.i;
291        return p;
292}
293int mapif_save_homun(int fd,int account_id,struct s_homunculus *data)
294{
295        struct s_homunculus *p;
296        int hom_id;
297       
298        if (data->hom_id == 0)
299                data->hom_id = homun_newid++;
300        hom_id = data->hom_id;
301        p = (struct s_homunculus*)idb_ensure(homun_db,hom_id,create_homun);
302        memcpy(p,data,sizeof(struct s_homunculus));
303        mapif_save_homun_ack(fd,account_id,1);
304        return 0;
305}
306
307int mapif_delete_homun(int fd,int hom_id)
308{
309        mapif_delete_homun_ack(fd,inter_homun_delete(hom_id));
310        return 0;
311}
312
313int mapif_rename_homun(int fd, int account_id, int char_id, char *name){
314        int i;
315
316        // Check Authorised letters/symbols in the name of the homun
317        if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
318                for (i = 0; i < NAME_LENGTH && name[i]; i++)
319                if (strchr(char_name_letters, name[i]) == NULL) {
320                        mapif_rename_homun_ack(fd, account_id, char_id, 0, name);
321                        return 0;
322                }
323        } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
324                for (i = 0; i < NAME_LENGTH && name[i]; i++)
325                if (strchr(char_name_letters, name[i]) != NULL) {
326                        mapif_rename_homun_ack(fd, account_id, char_id, 0, name);
327                        return 0;
328                }
329        }
330
331        mapif_rename_homun_ack(fd, account_id, char_id, 1, name);
332        return 0;
333}
334
335int mapif_parse_SaveHomun(int fd)
336{
337        mapif_save_homun(fd,RFIFOL(fd,4),(struct s_homunculus *)RFIFOP(fd,8));
338        return 0;
339}
340
341int mapif_parse_DeleteHomun(int fd)
342{
343        mapif_delete_homun(fd,RFIFOL(fd,2));
344        return 0;
345}
346
347int mapif_parse_RenameHomun(int fd)
348{
349        mapif_rename_homun(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), (char*)RFIFOP(fd, 10));
350        return 0;
351}
352
353int inter_homun_parse_frommap(int fd)
354{
355        switch(RFIFOW(fd,0)){
356        case 0x3090: mapif_create_homun(fd); break;
357        case 0x3091: mapif_load_homun(fd); break;
358        case 0x3092: mapif_parse_SaveHomun(fd); break;
359        case 0x3093: mapif_parse_DeleteHomun(fd); break;
360        case 0x3094: mapif_parse_RenameHomun(fd); break;
361        default:
362                return 0;
363        }
364        return 1;
365}
Note: See TracBrowser for help on using the browser.