00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include <config.h>
00077
00078 #include <ctype.h>
00079 #include <stddef.h>
00080 #include "commands.h"
00081 #include "empobj.h"
00082 #include "match.h"
00083 #include "news.h"
00084 #include "optlist.h"
00085 #include "treaty.h"
00086 #include "version.h"
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static struct valstr *
00097 xdeval(struct valstr *val,
00098 nsc_type type, void *ptr, ptrdiff_t off, int idx, int len)
00099 {
00100 val->val_type = type;
00101 val->val_cat = NSC_OFF;
00102 val->val_as.sym.off = off;
00103 val->val_as.sym.len = len;
00104 val->val_as.sym.idx = idx;
00105 nstr_exec_val(val, player->cnum, ptr, NSC_NOTYPE);
00106 return val;
00107 }
00108
00109
00110 static char *
00111 xdprval(struct valstr *val, char *sep)
00112 {
00113 unsigned char *s, *e, *l;
00114
00115 switch (val->val_type) {
00116 case NSC_LONG:
00117 pr("%s%ld", sep, val->val_as.lng);
00118 break;
00119 case NSC_DOUBLE:
00120 pr("%s%#g", sep, val->val_as.dbl);
00121 break;
00122 case NSC_STRING:
00123 s = (unsigned char *)val->val_as.str.base;
00124 if (s) {
00125 pr("%s\"", sep);
00126 l = s + val->val_as.str.maxsz;
00127
00128 for (;;) {
00129 for (e = s;
00130 e < l && *e != '"' && *e != '\\' && isgraph(*e);
00131 ++e)
00132 ;
00133 pr("%.*s", (int)(e-s), s);
00134 if (e < l && *e)
00135 pr("\\%03o", *e++);
00136 else
00137 break;
00138 s = e;
00139 }
00140 pr("\"");
00141 } else
00142 pr("%snil", sep);
00143 break;
00144 default:
00145 CANT_REACH();
00146 pr("0");
00147 }
00148 return " ";
00149 }
00150
00151
00152
00153
00154
00155
00156 static void
00157 xdflds(struct castr ca[], void *ptr)
00158 {
00159 int i, j, n;
00160 struct valstr val;
00161 char *sep = "";
00162
00163 for (i = 0; ca[i].ca_name; ++i) {
00164 if (ca[i].ca_flags & NSC_DEITY && !player->god)
00165 continue;
00166 if (ca[i].ca_flags & NSC_EXTRA)
00167 continue;
00168 n = ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0;
00169 j = 0;
00170 do {
00171 xdeval(&val, ca[i].ca_type, ptr, ca[i].ca_off, j, ca[i].ca_len);
00172 sep = xdprval(&val, sep);
00173 } while (++j < n);
00174 }
00175 }
00176
00177
00178
00179
00180
00181 static void
00182 xdhdr(char *name, int meta)
00183 {
00184 pr("XDUMP %s%s %ld\n", meta ? "meta " : "", name, (long)time(NULL));
00185 }
00186
00187
00188 static void
00189 xdftr(int n)
00190 {
00191 pr("/%d\n", n);
00192 }
00193
00194
00195
00196
00197
00198 static int
00199 xdvisible(int type, void *p)
00200 {
00201 struct empobj *gp = p;
00202 struct trtstr *tp = p;
00203 struct lonstr *lp = p;
00204 struct natstr *natp;
00205 int tlev;
00206
00207 switch (type) {
00208 case EF_SECTOR:
00209 case EF_REALM:
00210 return gp->own == player->cnum || player->god;
00211 case EF_SHIP:
00212 case EF_PLANE:
00213 case EF_LAND:
00214 case EF_NUKE:
00215 case EF_LOST:
00216 return gp->own != 0 && (gp->own == player->cnum || player->god);
00217 case EF_NATION:
00218 return ((struct natstr *)p)->nat_stat != STAT_UNUSED;
00219 case EF_COUNTRY:
00220 return gp->own == player->cnum;
00221 case EF_NEWS:
00222 return ((struct nwsstr *)p)->nws_vrb != 0
00223 && (!opt_HIDDEN || player->god);
00224 case EF_TREATY:
00225 return tp->trt_status != TS_FREE
00226 && (tp->trt_cna == player->cnum || tp->trt_cnb == player->cnum
00227 || player->god);
00228 case EF_LOAN:
00229 if (lp->l_status == LS_FREE)
00230 return 0;
00231 if (lp->l_status == LS_SIGNED)
00232 return 1;
00233 return lp->l_loner == player->cnum || lp->l_lonee == player->cnum
00234 || player->god;
00235 case EF_TRADE:
00236 case EF_COMM:
00237 return gp->own != 0;
00238 case EF_SHIP_CHR:
00239 tlev = ((struct mchrstr *)p)->m_tech;
00240 goto tech;
00241 case EF_PLANE_CHR:
00242 tlev = ((struct plchrstr *)p)->pl_tech;
00243 goto tech;
00244 case EF_LAND_CHR:
00245 tlev = ((struct lchrstr *)p)->l_tech;
00246 tech:
00247 natp = getnatp(player->cnum);
00248 return player->god || tlev <= (int)(1.25 * natp->nat_level[NAT_TLEV]);
00249 case EF_NUKE_CHR:
00250 tlev = ((struct nchrstr *)p)->n_tech;
00251 if (drnuke_const > MIN_DRNUKE_CONST) {
00252 natp = getnatp(player->cnum);
00253 if (tlev > (int)((int)(1.25 * natp->nat_level[NAT_RLEV])
00254 / drnuke_const))
00255 return player->god;
00256 }
00257 goto tech;
00258 case EF_NEWS_CHR:
00259 return ((struct rptstr *)p)->r_newspage != 0;
00260 case EF_TABLE:
00261 return ((struct empfile *)p)->cadef != NULL;
00262 default:
00263 return 1;
00264 }
00265 }
00266
00267
00268
00269
00270
00271 static int
00272 xditem(int type, char *arg)
00273 {
00274 struct castr *ca;
00275 struct nstr_item ni;
00276 int n;
00277 char buf[2048];
00278
00279 ca = ef_cadef(type);
00280 if (!ca)
00281 return RET_SYN;
00282
00283 if (!snxtitem(&ni, type, arg))
00284 return RET_SYN;
00285
00286 xdhdr(ef_nameof(type), 0);
00287
00288 n = 0;
00289 while (nxtitem(&ni, buf)) {
00290 if (!xdvisible(type, buf))
00291 continue;
00292 ++n;
00293 xdflds(ca, buf);
00294 pr("\n");
00295 }
00296
00297 xdftr(n);
00298
00299 return RET_OK;
00300 }
00301
00302
00303
00304
00305
00306 static int
00307 xdmeta(int type)
00308 {
00309 struct castr *ca = ef_cadef(type);
00310 int i;
00311 int n = 0;
00312
00313 if (!ca)
00314 return RET_SYN;
00315
00316 xdhdr(ef_nameof(type), 1);
00317
00318 for (i = 0; ca[i].ca_name; i++) {
00319 if (ca[i].ca_flags & NSC_DEITY && !player->god)
00320 continue;
00321 if (ca[i].ca_flags & NSC_EXTRA)
00322 continue;
00323 xdflds(mdchr_ca, &ca[i]);
00324 pr("\n");
00325 n++;
00326 }
00327
00328 xdftr(n);
00329
00330 return RET_OK;
00331 }
00332
00333
00334
00335
00336
00337 static int
00338 xdver(int meta)
00339 {
00340 static struct castr vers_ca = {
00341 NSC_STRINGY, 0, sizeof(PACKAGE_STRING), 0, "version", EF_BAD
00342 };
00343 struct keymatch *kp;
00344 char *sep;
00345 int n;
00346 struct castr ca;
00347 struct valstr val;
00348
00349 xdhdr("version", meta);
00350
00351 if (meta) {
00352 n = 0;
00353 xdflds(mdchr_ca, &vers_ca);
00354 pr("\n");
00355 n++;
00356 for (kp = configkeys; kp->km_key; ++kp) {
00357 if (kp->km_type != NSC_NOTYPE && !(kp->km_flags & KM_INTERNAL)) {
00358 ca.ca_type = kp->km_type;
00359 ca.ca_flags = 0;
00360 ca.ca_len = 0;
00361 ca.ca_off = 0;
00362 ca.ca_name = kp->km_key;
00363 ca.ca_table = EF_BAD;
00364 xdflds(mdchr_ca, &ca);
00365 pr("\n");
00366 n++;
00367 }
00368 }
00369 xdftr(n);
00370 return RET_OK;
00371 }
00372
00373 xdeval(&val, vers_ca.ca_type, version, vers_ca.ca_off, 0, vers_ca.ca_len);
00374 sep = xdprval(&val, "");
00375 for (kp = configkeys; kp->km_key; ++kp) {
00376 if (kp->km_type != NSC_NOTYPE && !(kp->km_flags & KM_INTERNAL)) {
00377 xdeval(&val, kp->km_type, kp->km_data, 0, 0, 0);
00378 sep = xdprval(&val, sep);
00379 }
00380 }
00381 pr("\n");
00382
00383 xdftr(1);
00384
00385 return RET_OK;
00386 }
00387
00388
00389 int
00390 xdump(void)
00391 {
00392 char *p;
00393 char buf[1024];
00394 int type;
00395 int meta = 0;
00396 struct natstr *natp;
00397
00398 p = getstarg(player->argp[1], "Table name, or meta? ", buf);
00399 if (p && strcmp(p, "meta") == 0) {
00400 meta = 1;
00401 p = getstarg(player->argp[2], "Table name? ", buf);
00402 }
00403 if (!p || !*p)
00404 return RET_SYN;
00405
00406 natp = getnatp(player->cnum);
00407 type = isdigit(p[0]) ? atoi(p) : ef_byname(p);
00408 if (type >= 0 && type < EF_MAX) {
00409 if (meta)
00410 return xdmeta(type);
00411 else if ((EF_IS_GAME_STATE(type) || EF_IS_VIEW(type))
00412 && !(natp->nat_stat == STAT_ACTIVE || player->god)) {
00413 pr("Access to table %s denied\n", ef_nameof(type));
00414 return RET_FAIL;
00415 } else
00416 return xditem(type, player->argp[2]);
00417 } else if (!strncmp(p, "ver", strlen(p))) {
00418 return xdver(meta);
00419 }
00420
00421 return RET_SYN;
00422 }