root/src/char/int_status.c @ 18

Revision 1, 5.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/db.h"
6#include "../common/lock.h"
7#include "../common/malloc.h"
8#include "../common/showmsg.h"
9#include "int_status.h"
10
11#include <stdio.h>
12
13// Contains all the status change data in-memory. [Skotlex]
14static DBMap* scdata_db = NULL; // int char_id -> struct scdata*
15char scdata_txt[1024]="save/scdata.txt"; //By [Skotlex]
16
17#ifdef ENABLE_SC_SAVING
18static void* create_scdata(DBKey key, va_list args)
19{
20        struct scdata *data;
21        data = (struct scdata*)aCalloc(1, sizeof(struct scdata));
22        data->account_id = va_arg(args, int);
23        data->char_id = key.i;
24        return data;
25}
26
27/*==========================================
28 * Loads status change data of the player given. [Skotlex]
29 *------------------------------------------*/
30struct scdata* status_search_scdata(int aid, int cid)
31{
32        return (struct scdata*)scdata_db->ensure(scdata_db, i2key(cid), create_scdata, aid);
33}
34
35/*==========================================
36 * Deletes status change data of the player given. [Skotlex]
37 * Should be invoked after the data of said player was successfully loaded.
38 *------------------------------------------*/
39void status_delete_scdata(int aid, int cid)
40{
41        struct scdata* scdata = (struct scdata*)idb_remove(scdata_db, cid);
42        if (scdata)
43        {
44                if (scdata->data)
45                        aFree(scdata->data);
46                aFree(scdata);
47        }
48}
49
50
51static void inter_status_tostr(char* line, struct scdata *sc_data)
52{
53        int i, len;
54
55        len = sprintf(line, "%d,%d,%d\t", sc_data->account_id, sc_data->char_id, sc_data->count);
56        for(i = 0; i < sc_data->count; i++) {
57                len += sprintf(line + len, "%d,%d,%d,%d,%d,%d\t", sc_data->data[i].type, sc_data->data[i].tick,
58                        sc_data->data[i].val1, sc_data->data[i].val2, sc_data->data[i].val3, sc_data->data[i].val4);
59        }
60        return;
61}
62
63static int inter_scdata_fromstr(char *line, struct scdata *sc_data)
64{
65        int i, len, next;
66       
67        if (sscanf(line,"%d,%d,%d\t%n",&sc_data->account_id, &sc_data->char_id, &sc_data->count, &next) < 3)
68                return 0;
69
70        if (sc_data->count < 1)
71                return 0;
72       
73        sc_data->data = (struct status_change_data*)aCalloc(sc_data->count, sizeof (struct status_change_data));
74
75        for (i = 0; i < sc_data->count; i++)
76        {
77                if (sscanf(line + next, "%hu,%d,%d,%d,%d,%d\t%n", &sc_data->data[i].type, &sc_data->data[i].tick,
78                        &sc_data->data[i].val1, &sc_data->data[i].val2, &sc_data->data[i].val3, &sc_data->data[i].val4, &len) < 6)
79                {
80                        aFree(sc_data->data);
81                        return 0;
82                }
83                next+=len;
84        }
85        return 1;
86}
87/*==========================================
88 * Loads all scdata from the given filename.
89 *------------------------------------------*/
90void status_load_scdata(const char* filename)
91{
92        FILE *fp;
93        int sd_count=0, sc_count=0;
94        char line[8192];
95        struct scdata *sc;
96
97        if ((fp = fopen(filename, "r")) == NULL) {
98                ShowError("status_load_scdata: Cannot open file %s!\n", filename);
99                return;
100        }
101
102        while(fgets(line, sizeof(line), fp))
103        {
104                sc = (struct scdata*)aCalloc(1, sizeof(struct scdata));
105                if (inter_scdata_fromstr(line, sc)) {
106                        sd_count++;
107                        sc_count+= sc->count;
108                        sc = (struct scdata*)idb_put(scdata_db, sc->char_id, sc);
109                        if (sc) {
110                                ShowError("Duplicate entry in %s for character %d\n", filename, sc->char_id);
111                                if (sc->data) aFree(sc->data);
112                                aFree(sc);
113                        }
114                } else {
115                        ShowError("status_load_scdata: Broken line data: %s\n", line);
116                        aFree(sc);
117                }
118        }
119        fclose(fp);
120        ShowStatus("Loaded %d saved status changes for %d characters.\n", sc_count, sd_count);
121}
122
123static int inter_status_save_sub(DBKey key, void *data, va_list ap) {
124        char line[8192];
125        struct scdata * sc_data;
126        FILE *fp;
127
128        sc_data = (struct scdata *)data;
129        if (sc_data->count < 1)
130                return 0;
131       
132        fp = va_arg(ap, FILE *);
133        inter_status_tostr(line, sc_data);
134        fprintf(fp, "%s\n", line);
135        return 0;
136}
137
138/*==========================================
139 * Saves all scdata to the given filename.
140 *------------------------------------------*/
141void inter_status_save()
142{
143        FILE *fp;
144        int lock;
145
146        if ((fp = lock_fopen(scdata_txt, &lock)) == NULL) {
147                ShowError("int_status: can't write [%s] !!! data is lost !!!\n", scdata_txt);
148                return;
149        }
150        scdata_db->foreach(scdata_db, inter_status_save_sub, fp);
151        lock_fclose(fp,scdata_txt, &lock);
152}
153
154/*==========================================
155 * Initializes db.
156 *------------------------------------------*/
157void status_init()
158{
159        scdata_db = idb_alloc(DB_OPT_BASE);
160        status_load_scdata(scdata_txt);
161}
162
163/*==========================================
164 * Frees up memory.
165 *------------------------------------------*/
166static int scdata_db_final(DBKey k,void *d,va_list ap)
167{
168        struct scdata *data = (struct scdata*)d;
169        if (data->data)
170                aFree(data->data);
171        aFree(data);
172        return 0;
173}
174
175/*==========================================
176 * Final cleanup.
177 *------------------------------------------*/
178void status_final(void)
179{
180        scdata_db->destroy(scdata_db, scdata_db_final);
181}
182
183#endif //ENABLE_SC_SAVING
Note: See TracBrowser for help on using the browser.