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 @@
-