]> git.pond.sub.org Git - empserver/blob - src/lib/commands/xdump.c
(xdump): New command xdump (experimental).
[empserver] / src / lib / commands / xdump.c
1 #include <stddef.h>
2 #include "misc.h"
3 #include "file.h"
4 #include "match.h"
5 #include "nsc.h"
6
7 /*
8  * Dump everything under the sun
9  *
10  * Static game data (configuration):
11  * - Item characteristics: ichr[]
12  * - Land unit characteristics: lchr[]
13  * - Nuke characteristics: nchr[]
14  * - Plane characteristics: plchr[]
15  * - Product characteristics: pchr[]
16  * - Sector designation characteristics: dchr[]
17  * - Sector infrastructure characteristics: intrchr[]
18  * - Ship characteristics: mchr[]
19  * Less important:
20  * - News item characteristics: rpt[]
21  * - Treaty clause characteristics: tchr[]
22  * - Commands: coms[]
23  * - Options: Options[]
24  * - Configuration: configkeys[]
25  *
26  * Dynamic game data:
27  * - Sectors: EF_SECTOR, sect_ca[] (already have dump)
28  * - Land units: EF_LAND, land_ca[] (already have ldump)
29  * - Lost: EF_LOST, lost_ca[] (already have lost)
30  * - Nukes: EF_NUKE, nuke_ca[] (already have ndump)
31  * - Planes: EF_PLANE, plane_ca[] (already have pdump)
32  * - Ships: EF_SHIP, ship_ca[] (already have sdump)
33  * - News: EF_NEWS, news_ca[]
34  * - Treaties: EF_TREATY, treaty_ca[]
35  * - Power: EF_POWER
36  * - Nations: EF_NATION, nat_ca[]
37  * - Loans: EF_LOAN, loan_ca[]
38  * - Map: EF_MAP
39  * - Bmap: EF_BMAP
40  * - Market: EF_COMM, commodity_ca[]
41  */
42
43 static struct castr ichr_ca[] = {
44     {NSC_STRING, 0, 0, offsetof(struct ichrstr, i_name), "name"},
45     {NSC_INT, 0, 0, offsetof(struct ichrstr, i_mnem), "mnem"},
46     {NSC_INT, 0, 0, offsetof(struct ichrstr, i_vtype), "vtype"},
47     {NSC_INT, 0, 0, offsetof(struct ichrstr, i_value), "value"},
48     {NSC_INT, 0, 0, offsetof(struct ichrstr, i_sell), "sell"},
49     {NSC_INT, 0, 0, offsetof(struct ichrstr, i_lbs), "lbs"},
50     {NSC_INT, 0, NUMPKG, offsetof(struct ichrstr, i_pkg), "pkg"},
51     {NSC_NOTYPE, 0, 0, 0, NULL}
52 };
53
54 static struct castr mchr_ca[] = {
55     {NSC_STRING, 0, 0, offsetof(struct mchrstr, m_name), "name"},
56     {NSC_USHORT, 0, I_MAX+1, offsetof(struct mchrstr, m_item), "item"},
57     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_lcm), "lcm"},
58     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_hcm), "hcm"},
59     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_armor), "armor"},
60     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_speed), "speed"},
61     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_visib), "visib"},
62     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_vrnge), "vrnge"},
63     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_glim), "glim"},
64     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_nxlight), "nxlight"},
65     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_nchoppers), "nchoppers"},
66     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_fuelc), "fuelc"},
67     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_fuelu), "fuelu"},
68     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_tech), "tech"},
69     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_cost), "cost"},
70     {NSC_INT, 0, 0, offsetof(struct mchrstr, m_flags), "flags"},
71     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_nplanes), "nplanes"},
72     {NSC_UCHAR, 0, 0, offsetof(struct mchrstr, m_nland), "nland"},
73     {NSC_NOTYPE, 0, 0, 0, NULL}
74 };
75
76 static struct castr pchr_ca[] = {
77     {NSC_STRING, 0, 0, offsetof(struct pchrstr, p_name), "name"},
78     {NSC_STRING, 0, 0, offsetof(struct pchrstr, p_sname), "sname"},
79     {NSC_UCHAR, 0, MAXPRCON, offsetof(struct pchrstr, p_ctype), "ctype"},
80     {NSC_USHORT, 0, MAXPRCON, offsetof(struct pchrstr, p_camt), "camt"},
81     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_type), "type"},
82     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_level), "level"},
83     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_cost), "cost"},
84     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_nrndx), "nrndx"},
85     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_nrdep), "nrdep"},
86     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_nlndx), "nlndx"},
87     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_nlmin), "nlmin"},
88     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_nllag), "nllag"},
89     {NSC_INT, 0, 0, offsetof(struct pchrstr, p_effic), "effic"},
90     {NSC_NOTYPE, 0, 0, 0, NULL}
91 };
92
93 static struct castr plchr_ca[] = {
94     {NSC_STRING, 0, 0, offsetof(struct plchrstr, pl_name), "name"},
95     {NSC_STRING, 0, 0, offsetof(struct plchrstr, pl_planename), "planename"},
96     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_lcm), "lcm"},
97     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_hcm), "hcm"},
98     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_cost), "cost"},
99     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_tech), "tech"},
100     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_acc), "acc"},
101     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_load), "load"},
102     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_att), "att"},
103     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_def), "def"},
104     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_range), "range"},
105     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_crew), "crew"},
106     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_fuel), "fuel"},
107     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_stealth), "stealth"},
108     {NSC_INT, 0, 0, offsetof(struct plchrstr, pl_flags), "flags"},
109     {NSC_NOTYPE, 0, 0, 0, NULL}
110 };
111
112 static struct castr lchr_ca[] = {
113     {NSC_STRING, 0, 0, offsetof(struct lchrstr, l_name), "name"},
114     {NSC_USHORT, 0, I_MAX+1, offsetof(struct mchrstr, m_item), "item"},
115     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_lcm), "lcm"},
116     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_hcm), "hcm"},
117     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_gun), "gun"},
118     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_shell), "shell"},
119     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_tech), "tech"},
120     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_cost), "cost"},
121     {NSC_FLOAT, 0, 0, offsetof(struct lchrstr, l_att), "att"},
122     {NSC_FLOAT, 0, 0, offsetof(struct lchrstr, l_def), "def"},
123     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_vul), "vul"},
124     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_spd), "spd"},
125     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_vis), "vis"},
126     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_spy), "spy"},
127     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_rad), "rad"},
128     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_frg), "frg"},
129     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_acc), "acc"},
130     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_dam), "dam"},
131     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_ammo), "ammo"},
132     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_aaf), "aaf"},
133     {NSC_UCHAR, 0, 0, offsetof(struct lchrstr, l_fuelc), "fuelc"},
134     {NSC_UCHAR, 0, 0, offsetof(struct lchrstr, l_fuelu), "fuelu"},
135     {NSC_UCHAR, 0, 0, offsetof(struct lchrstr, l_nxlight), "nxlight"},
136     {NSC_UCHAR, 0, 0, offsetof(struct lchrstr, l_mxland), "mxland"},
137     {NSC_INT, 0, 0, offsetof(struct lchrstr, l_flags), "flags"},
138     {NSC_NOTYPE, 0, 0, 0, NULL}
139 };
140
141 static struct castr nchr_ca[] = {
142     {NSC_STRING, 0, 0, offsetof(struct nchrstr, n_name), "name"},
143     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_lcm), "lcm"},
144     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_hcm), "hcm"},
145     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_oil), "oil"},
146     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_rad), "rad"},
147     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_blast), "blast"},
148     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_dam), "dam"},
149     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_cost), "cost"},
150     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_tech), "tech"},
151     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_weight), "weight"},
152     {NSC_INT, 0, 0, offsetof(struct nchrstr, n_flags), "flags"},
153     {NSC_NOTYPE, 0, 0, 0, NULL}
154 };
155
156 struct camap {
157     char *name;
158     struct castr *ca;
159     void *chr;
160     size_t size;
161 };
162
163 static struct camap chr_camap[] = {
164     {"item", ichr_ca, ichr, sizeof(ichr[0])},
165     {"product", pchr_ca, pchr, sizeof(pchr[0])},
166     {"ship chr", mchr_ca, mchr, sizeof(mchr[0])},
167     {"plane chr", plchr_ca, plchr, sizeof(plchr[0])},
168     {"land chr", lchr_ca, lchr, sizeof(lchr[0])},
169     {"nuke chr", nchr_ca, nchr, sizeof(nchr[0])},
170     {NULL, NULL, NULL, 0}
171 };
172
173 static int
174 chridx_by_name(char *name)
175 {
176     return stmtch(name, chr_camap, offsetof(struct camap, name),
177                   sizeof(chr_camap[0]));
178 }
179
180 static struct valstr *
181 xdeval(struct valstr *val, nsc_type type, ptrdiff_t off, void *item, int idx)
182 {
183     val->val_type = type;
184     val->val_cat = NSC_OFF;
185     val->val_as_type = -1;
186     val->val_as.sym.off = off;
187     val->val_as.sym.idx = idx;
188     nstr_exec_val(val, player->cnum, item, 0);
189     return val;                 /* FIXME nstr_exec_val() should return VAL */
190 }
191
192 static char *
193 xdprval(struct valstr *val, char *sep)
194 {
195     char *s, *e;
196
197     switch (val->val_type) {
198     case NSC_LONG:
199         pr("%s%ld", sep, val->val_as.lng);
200         break;
201     case NSC_DOUBLE:
202         pr("%s%g", sep, val->val_as.dbl);
203         break;
204     case NSC_STRING:
205         pr("%s\"", sep);
206         s = val->val_as.str;
207         while (s && *s) {
208             for (e = s; *e != '"' && isprint(*e); ++e) ;
209             pr("%*s", e-s, s);
210             for (; *e && !isprint(*e); ++e) {
211                 pr("\\%3o", *e);
212             }
213             s = e;
214         }
215         prnf("\"");
216         break;
217     }
218     return " ";
219 }
220
221 static void
222 xdflds(struct castr ca[], void *item)
223 {
224     int i, j;
225     struct valstr val;
226     char *sep = "";
227
228     for (i = 0; ca[i].ca_name; ++i) {
229         if (ca[i].ca_flags & NSC_DEITY && !player->god)
230             continue;
231         j = 0;
232         do {
233             xdeval(&val, ca[i].ca_type, ca[i].ca_off, item, j);
234             sep = xdprval(&val, sep);
235         } while (++j < ca[i].ca_len);
236     }
237 }
238
239 static void
240 xdhdrs(struct castr ca[])
241 {
242     int i;
243     char *sep = "";
244
245     for (i = 0; ca[i].ca_name; ++i) {
246         if (ca[i].ca_flags & NSC_DEITY && !player->god)
247             continue;
248         pr("%s%s", sep, ca[i].ca_name);
249         if (ca[i].ca_len)
250             pr(" %d", ca[i].ca_len);
251         sep = " ";
252     }
253 }
254
255 static void
256 xdhdr(char *name, struct castr ca[])
257 {
258     prdate();
259     pr("DUMP %s %ld\n", name, (long)time(NULL));
260
261     xdhdrs(ca);
262     pr("\n");
263 }
264
265 static void
266 xdftr(int n)
267 {
268     pr("dumped %d\n", n);
269 }
270
271 static int
272 xditem(int type, char *arg)
273 {
274     struct castr *ca;
275     struct nstr_item ni;
276     int n;
277     s_char buf[2048];           /* FIXME buffer size? */
278
279     ca = ef_cadef(type);
280     if (!ca)
281         return RET_SYN;
282
283     if (!snxtitem(&ni, type, arg))
284         return RET_SYN;
285
286     xdhdr(ef_nameof(type), ca);
287
288     n = 0;
289     while (nxtitem(&ni, buf)) {
290         if (!player->owner)
291             continue;
292         ++n;
293         xdflds(ca, buf);
294         pr("\n");
295     }
296
297     xdftr(n);
298
299     return RET_OK;
300 }
301
302 static int
303 xdchr(int chridx)
304 {
305     struct camap *cm;
306     char *p;
307     struct valstr val;
308     int n;
309
310     if (chridx < 0)
311         return RET_SYN;
312     cm = &chr_camap[chridx];
313
314     xdhdr(cm->name, cm->ca);
315
316     n = 0;
317     for (p = cm->chr; ; p += cm->size) {
318         val.val_type = cm->ca[0].ca_type;
319         val.val_cat = NSC_OFF;
320         val.val_as_type = -1;
321         val.val_as.sym.off = cm->ca[0].ca_off;
322         val.val_as.sym.idx = 0;
323         nstr_exec_val(&val, player->cnum, p, NSC_STRING);
324         if (!val.val_as.str || !*val.val_as.str)
325             break;
326         ++n;
327         xdflds(cm->ca, p);
328         pr("\n");
329     }
330
331     xdftr(n);
332
333     return RET_OK;
334 }
335
336 int
337 xdump(void)
338 {
339     s_char *p;
340     char buf[1024];
341     int type;
342
343     p = getstarg(player->argp[1], "What? ", buf);
344     if (!p)
345         return RET_SYN;
346
347     type = ef_byname(p);
348     if (type >= 0) {
349         return xditem(type, player->argp[2]);
350     } else if (!strncmp(p, "chr", strlen(p)) && player->argp[2]) {
351         return xdchr(chridx_by_name(player->argp[2]));
352     }
353
354     return RET_SYN;
355 }