From 357a73e8266d9be86e8d9f03e39b9c9b9e3c35ad Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 18 Nov 2005 23:23:47 +0000 Subject: [PATCH] XML reports - incomplete implementation, might finish it eventually. --- src/common/gamecode/Jamfile | 1 + src/common/gamecode/creport.c | 21 ++-- src/common/gamecode/gamecode.vcproj | 6 + src/common/gamecode/report.c | 16 ++- src/common/gamecode/xmlreport.c | 182 ++++++++++++++++++++++++++++ src/common/gamecode/xmlreport.h | 27 +++++ src/common/kernel/eressea.c | 3 +- src/common/kernel/eressea.h | 3 +- src/common/kernel/reports.c | 20 +-- src/common/kernel/reports.h | 1 + src/eressea/server.cpp | 2 + src/res/eressea.xml | 4 +- src/res/tutorial.xml | 4 +- src/res/vinyambar-wdw.xml | 3 +- 14 files changed, 262 insertions(+), 31 deletions(-) create mode 100644 src/common/gamecode/xmlreport.c create mode 100644 src/common/gamecode/xmlreport.h diff --git a/src/common/gamecode/Jamfile b/src/common/gamecode/Jamfile index 606287d77..b7be60f22 100644 --- a/src/common/gamecode/Jamfile +++ b/src/common/gamecode/Jamfile @@ -18,6 +18,7 @@ SOURCES = report.c spy.c study.c + xmlreport.c ; Library gamecode : $(SOURCES) ; diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 197e7a1a8..7d222c210 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -1041,7 +1041,7 @@ cr_borders(seen_region ** seen, const region * r, const faction * f, int seemode /* main function of the creport. creates the header and traverses all regions */ static int -report_computer(FILE * F, report_context * ctx) +report_computer(const char * filename, report_context * ctx) { int i; faction * f = ctx->f; @@ -1057,6 +1057,11 @@ report_computer(FILE * F, report_context * ctx) #ifdef SCORE_MODULE int score = 0, avgscore = 0; #endif + FILE * F = fopen(filename, "wt"); + if (F==NULL) { + perror(filename); + return -1; + } /* must call this to get all the neighbour regions */ get_seen_interval(ctx->seen, &first, &last); @@ -1229,17 +1234,8 @@ report_computer(FILE * F, report_context * ctx) } fprintf(F, "\"%s\";Terrain\n", add_translation(tname, locale_string(f->locale, tname))); - switch (sd->mode) { - case see_far: - fputs("\"neighbourhood\";visibility\n", F); - break; - case see_lighthouse: - fputs("\"lighthouse\";visibility\n", F); - break; - case see_travel: - fputs("\"travel\";visibility\n", F); - break; - } + if (sd->mode!=see_unit) fprintf(F, "\"%s\";visibility\n", visibility[sd->mode]); + { unit * owner = region_owner(r); if (owner) { @@ -1441,6 +1437,7 @@ report_computer(FILE * F, report_context * ctx) log_error(("%s\n", strerror(errno))); errno = 0; } + fclose(F); return 0; } diff --git a/src/common/gamecode/gamecode.vcproj b/src/common/gamecode/gamecode.vcproj index 94df194de..a2281b3d3 100644 --- a/src/common/gamecode/gamecode.vcproj +++ b/src/common/gamecode/gamecode.vcproj @@ -203,6 +203,9 @@ + + @@ -237,6 +240,9 @@ + + diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 5c98a539f..63aac69fe 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1417,12 +1417,17 @@ buildingmaintenance(const building * b, const resource_type * rtype) } static int -report_template(FILE * F, report_context * ctx) +report_template(const char * filename, report_context * ctx) { faction * f = ctx->f; region *r; plane *pl; region *last = lastregion(f); + FILE * F = fopen(filename, "wt"); + if (F==NULL) { + perror(filename); + return -1; + } rps_nowrap(F, ""); rnl(F); @@ -1538,6 +1543,7 @@ report_template(FILE * F, report_context * ctx) sprintf(buf, LOC(f->locale, parameters[P_NEXT])); rps_nowrap(F, buf); rnl(F); + fclose(F); return 0; } @@ -1894,7 +1900,7 @@ report_building(FILE *F, const region * r, const building * b, const faction * f } int -report_plaintext(FILE *F, report_context * ctx) +report_plaintext(const char * filename, report_context * ctx) { int flag = 0; char ch; @@ -1912,6 +1918,11 @@ report_plaintext(FILE *F, report_context * ctx) region * last = lastregion(f); int ix = Pow(O_STATISTICS); int wants_stats = (f->options & ix); + FILE * F = fopen(filename, "wt"); + if (F==NULL) { + perror(filename); + return -1; + } strftime(pzTime, 64, "%A, %d. %B %Y, %H:%M", localtime(&ctx->report_time)); m = msg_message("nr_header_date", "game date", global.gamename, pzTime); @@ -2318,6 +2329,7 @@ report_plaintext(FILE *F, report_context * ctx) list_address(F, f, ctx->addresses); } } + fclose(F); return 0; } diff --git a/src/common/gamecode/xmlreport.c b/src/common/gamecode/xmlreport.c new file mode 100644 index 000000000..c38bcfb03 --- /dev/null +++ b/src/common/gamecode/xmlreport.c @@ -0,0 +1,182 @@ +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea-pbem.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include +#include +#include "xmlreport.h" + +/* tweakable features */ +#define ENCODE_SPECIAL 1 +#define RENDER_CRMESSAGES + +/* modules include */ +#include + +/* attributes include */ +#include +#include +#include +#include +#include + +/* gamecode includes */ +#include "laws.h" +#include "economy.h" + +/* kernel includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* util includes */ +#include +#include +#include +#include + +/* libxml2 includes */ +#include +#include + +/* libc includes */ +#include +#include +#include +#include +#include + +#define L10N(x) x + +static iconv_t utf8; + +static xmlChar* +xml_s(const char * str) +{ + static char buffer[1024]; + const char * inbuf = str; + char * outbuf = buffer; + size_t inbytes = strlen(str)+1; + size_t outbytes = sizeof(buffer); + iconv(utf8, (const char**)&inbuf, &inbytes, (char**)&outbuf, &outbytes); + return (xmlChar*)buffer; +} + +static xmlChar* +xml_i(double number) +{ + static char buffer[128]; + sprintf(buffer, "%.0lf", number); + return (xmlChar*)buffer; +} + +static xmlNodePtr +report_faction(report_context * ctx, faction * f) +{ + xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "faction"); + xmlNewProp(node, BAD_CAST "id", xml_i(f->no)); + xmlNewProp(node, BAD_CAST "name", xml_s(f->name)); + xmlNewProp(node, BAD_CAST "email", xml_s(f->email)); + if (f->banner && *f->banner) xmlNewProp(node, BAD_CAST "banner", xml_s(f->banner)); + if (f==ctx->f) { + const char * s; + xmlNewProp(node, BAD_CAST "locale", BAD_CAST locale_name(f->locale)); + xmlNewProp(node, BAD_CAST "age", xml_i(f->age)); + xmlNewProp(node, BAD_CAST "options", xml_i(f->options)); + xmlNewProp(node, BAD_CAST "race", xml_s(L10N(rc_name(f->race, 0)))); + xmlNewProp(node, BAD_CAST "magic", xml_s(L10N(magietypen[f->magiegebiet]))); + s = get_prefix(f->attribs);; + if (s) { + xmlNewProp(node, BAD_CAST "prefix", xml_s(L10N(s))); + } + } + return node; +} + +static xmlNodePtr +report_region(report_context * ctx, seen_region * sr) +{ + const region * r = sr->r; + xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "region"); + xmlNewProp(node, BAD_CAST "terrain", xml_s(L10N(terrain_name(r)))); + xmlNewProp(node, BAD_CAST "x", xml_i(r->x)); + xmlNewProp(node, BAD_CAST "y", xml_i(r->y)); + xmlNewProp(node, BAD_CAST "view", xml_s(visibility[sr->mode])); + if (r->planep) { + xmlNewProp(node, BAD_CAST "plane", xml_s(r->planep->name)); + } + if (r->land!=NULL) { + xmlNewProp(node, BAD_CAST "name", xml_s(r->land->name)); + } + return node; +} + +/* main function of the xmlreport. creates the header and traverses all regions */ +static int +report_xml(const char * filename, report_context * ctx) +{ + xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); + xmlNodePtr xmlReport = xmlNewNode(NULL, BAD_CAST "report"); + const faction_list * address; + region * r = firstregion(ctx->f), * rend = lastregion(ctx->f); + + for (address=ctx->addresses;address;address=address->next) { + xmlAddChild(xmlReport, report_faction(ctx, address->data)); + } + + get_seen_interval(ctx->seen, &r, &rend); + for (;r!=rend;r=r->next) { + seen_region * sr = find_seen(ctx->seen, r); + if (sr!=NULL) xmlAddChild(xmlReport, report_region(ctx, sr)); + } + xmlDocSetRootElement(doc, xmlReport); + xmlKeepBlanksDefault(0); + xmlSaveFormatFileEnc(filename, doc, "utf-8", 1); + xmlFreeDoc(doc); + + return 0; +} + +void +xmlreport_init(void) +{ + register_reporttype("xml", &report_xml, 1< + | Eressea PBEM host | Katja Zedel + | (c) 1998 - 2005 | Enno Rehling + +-------------------+ + + This program may not be used, modified or distributed + without prior permission by the authors of Eressea. +*/ +#ifndef H_GC_XMLREPORT +#define H_GC_XMLREPORT +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern void xmlreport_cleanup(void); +extern void xmlreport_init(void); + +extern int crwritemap(const char * filename); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 0817388b8..d9ff91c61 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -447,7 +447,8 @@ const char *options[MAXOPTIONS] = "ADRESSEN", "BZIP2", "PUNKTE", - "SHOWSKCHANGE" + "SHOWSKCHANGE", + "XML" }; static int diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 0cb29d82c..70f434938 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -574,9 +574,10 @@ enum { O_NEWS, /* 128 */ O_MATERIALPOOL, /* 256 */ O_ADRESSEN, /* 512 */ - O_BZIP2, /* 1024 - crkurz compatible flag */ + O_BZIP2, /* 1024 - compress as bzip2 */ O_SCORE, /* 2048 - punkte anzeigen? */ O_SHOWSKCHANGE, /* 4096 - Skillveränderungen anzeigen? */ + O_XML, /* 8192 - XML report versenden */ MAXOPTIONS }; diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index e5f823291..8f4a84730 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -62,6 +62,15 @@ #include const char * g_reportdir; +const char * visibility[] = { + "none", + "neighbour", + "lighthouse", + "travel", + "far", + "unit", + "battle" +}; const char *coasts[MAXDIRECTIONS] = { @@ -1505,16 +1514,13 @@ write_reports(faction * f, time_t ltime) for (;rtype!=NULL;rtype=rtype->next) { if (f->options & rtype->flag) { - FILE * F; + char * filename; sprintf(buf, "%s/%d-%s.%s", reportpath(), turn, factionid(f), rtype->extension); - F = fopen(buf, "wt"); - if (F!=NULL) { - rtype->write(F, &ctx); - fclose(F); + filename = strdup(buf); + if (rtype->write(filename, &ctx)==0) { gotit = true; - } else { - perror(buf); } + free(filename); } } diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index 8a04991a8..13fa6a3fe 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -85,6 +85,7 @@ extern struct seen_region ** seen_init(void); extern void seen_done(struct seen_region * seehash[]); extern void free_seen(void); extern void get_seen_interval(struct seen_region ** seen, struct region ** first, struct region ** last); +extern const char * visibility[]; typedef struct report_context { struct faction * f; diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index d69bfbf8f..52b59bddb 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -56,6 +56,7 @@ /* gamecode includes */ #include +#include #include #include #include @@ -207,6 +208,7 @@ game_init(void) reports_init(); report_init(); creport_init(); + xmlreport_init(); debug_language("locales.log"); register_races(); diff --git a/src/res/eressea.xml b/src/res/eressea.xml index c603785b0..41de7522d 100644 --- a/src/res/eressea.xml +++ b/src/res/eressea.xml @@ -19,7 +19,7 @@ - Game specific + @@ -28,9 +28,7 @@ - - diff --git a/src/res/tutorial.xml b/src/res/tutorial.xml index b7eaef488..56b789c26 100644 --- a/src/res/tutorial.xml +++ b/src/res/tutorial.xml @@ -19,7 +19,7 @@ - Game specific + @@ -28,10 +28,8 @@ - - diff --git a/src/res/vinyambar-wdw.xml b/src/res/vinyambar-wdw.xml index f95e8aa39..4661227bb 100644 --- a/src/res/vinyambar-wdw.xml +++ b/src/res/vinyambar-wdw.xml @@ -18,7 +18,7 @@ - Game specific + @@ -27,7 +27,6 @@ -