From c2634bd095074266d8a664f042c76f164d3a2444 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 7 Oct 2017 19:44:23 +0200 Subject: [PATCH] move readorders to orderfile module. --- src/bind_eressea.c | 1 + src/kernel/save.c | 211 ---------------------------------------- src/kernel/save.h | 1 - src/orderfile.c | 235 +++++++++++++++++++++++++++++++++++++++++---- src/orderfile.h | 5 +- 5 files changed, 220 insertions(+), 233 deletions(-) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index de8751306..ffc23fbfc 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -3,6 +3,7 @@ #include #include "json.h" +#include "orderfile.h" #include #include diff --git a/src/kernel/save.c b/src/kernel/save.c index 6338b6827..aa09a27be 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -123,217 +123,6 @@ char *rns(FILE * f, char *c, size_t size) return c; } - -static unit *unitorders(FILE * F, int enc, struct faction *f) -{ - int i; - unit *u; - - if (!f) - return NULL; - - i = getid(); - u = findunitg(i, NULL); - - if (u && u->faction == f) { - order **ordp; - - if (!fval(u, UFL_ORDERS)) { - /* alle wiederholbaren, langen befehle werden gesichert: */ - fset(u, UFL_ORDERS); - u->old_orders = u->orders; - ordp = &u->old_orders; - while (*ordp) { - order *ord = *ordp; - keyword_t kwd = getkeyword(ord); - if (!is_repeated(kwd)) { - *ordp = ord->next; - ord->next = NULL; - free_order(ord); - } - else { - ordp = &ord->next; - } - } - } - else { - free_orders(&u->orders); - } - u->orders = 0; - - ordp = &u->orders; - - for (;;) { - const char *s; - /* Erst wenn wir sicher sind, dass kein Befehl - * eingegeben wurde, checken wir, ob nun eine neue - * Einheit oder ein neuer Spieler drankommt */ - - s = getbuf(F, enc); - if (s == NULL) - break; - - if (s[0]) { - if (s[0] != '@') { - char token[64]; - const char *stok = s; - stok = parse_token(&stok, token, sizeof(token)); - - if (stok) { - bool quit = false; - param_t param = findparam(stok, u->faction->locale); - switch (param) { - case P_UNIT: - case P_REGION: - quit = true; - break; - case P_FACTION: - case P_NEXT: - case P_GAMENAME: - /* these terminate the orders, so we apply extra checking */ - if (strlen(stok) >= 3) { - quit = true; - break; - } - else { - quit = false; - } - break; - default: - break; - } - if (quit) { - break; - } - } - } - /* Nun wird der Befehl erzeut und eingehängt */ - *ordp = parse_order(s, u->faction->locale); - if (*ordp) { - ordp = &(*ordp)->next; - } - else { - ADDMSG(&f->msgs, msg_message("parse_error", "unit command", u, s)); - } - } - } - - } - else { - return NULL; - } - return u; -} - -static faction *factionorders(void) -{ - faction *f = NULL; - int fid = getid(); - - f = findfaction(fid); - - if (f != NULL && !fval(f, FFL_NPC)) { - char token[128]; - const char *pass = gettoken(token, sizeof(token)); - - if (!checkpasswd(f, (const char *)pass)) { - log_debug("Invalid password for faction %s", itoa36(fid)); - ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", pass)); - return 0; - } - /* Die Partei hat sich zumindest gemeldet, so dass sie noch - * nicht als untätig gilt */ - f->lastorders = turn; - - } - else { - log_debug("orders for invalid faction %s", itoa36(fid)); - } - return f; -} - -int readorders(const char *filename) -{ - FILE *F = NULL; - const char *b; - int nfactions = 0; - struct faction *f = NULL; - - F = fopen(filename, "r"); - if (!F) { - perror(filename); - return -1; - } - log_info("reading orders from %s", filename); - - /* TODO: recognize UTF8 BOM */ - b = getbuf(F, enc_gamedata); - - /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten - * Partei */ - - while (b) { - char token[128]; - const struct locale *lang = f ? f->locale : default_locale; - param_t p; - const char *s; - init_tokens_str(b); - s = gettoken(token, sizeof(token)); - p = findparam_block(s, lang, true); - switch (p) { - case P_GAMENAME: - case P_FACTION: - f = factionorders(); - if (f) { - ++nfactions; - } - - b = getbuf(F, enc_gamedata); - break; - - /* in factionorders wird nur eine zeile gelesen: - * diejenige mit dem passwort. Die befehle der units - * werden geloescht, und die Partei wird als aktiv - * vermerkt. */ - - case P_UNIT: - if (!f || !unitorders(F, enc_gamedata, f)) { - do { - b = getbuf(F, enc_gamedata); - if (!b) { - break; - } - init_tokens_str(b); - s = gettoken(token, sizeof(token)); - p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM; - } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT - && p != P_GAMENAME); - } - break; - - /* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue - * Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut - * durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf - * auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier - * muss buf erneut gefüllt werden, da die betreffende Information in nur - * einer Zeile steht, und nun die nächste gelesen werden muss. */ - - case P_NEXT: - f = NULL; - b = getbuf(F, enc_gamedata); - break; - - default: - b = getbuf(F, enc_gamedata); - break; - } - } - - fclose(F); - log_info("done reading orders for %d factions", nfactions); - return 0; -} - /* ------------------------------------------------------------- */ /* #define INNER_WORLD */ diff --git a/src/kernel/save.h b/src/kernel/save.h index 763ff66b6..e8b631aab 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -43,7 +43,6 @@ extern "C" { /* TODO: is this *really* still in use? */ extern int enc_gamedata; - int readorders(const char *filename); int readgame(const char *filename); int writegame(const char *filename); diff --git a/src/orderfile.c b/src/orderfile.c index 9f044ddbe..90348cc17 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -1,30 +1,231 @@ +#include +#include #include "orderfile.h" #include #include +#include +#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include -void read_orders(stream *strm) +#include + + +static unit *unitorders(FILE * F, int enc, struct faction *f) +{ + int i; + unit *u; + + if (!f) + return NULL; + + i = getid(); + u = findunitg(i, NULL); + + if (u && u->faction == f) { + order **ordp; + + if (!fval(u, UFL_ORDERS)) { + /* alle wiederholbaren, langen befehle werden gesichert: */ + fset(u, UFL_ORDERS); + u->old_orders = u->orders; + ordp = &u->old_orders; + while (*ordp) { + order *ord = *ordp; + keyword_t kwd = getkeyword(ord); + if (!is_repeated(kwd)) { + *ordp = ord->next; + ord->next = NULL; + free_order(ord); + } + else { + ordp = &ord->next; + } + } + } + else { + free_orders(&u->orders); + } + u->orders = 0; + + ordp = &u->orders; + + for (;;) { + const char *s; + /* Erst wenn wir sicher sind, dass kein Befehl + * eingegeben wurde, checken wir, ob nun eine neue + * Einheit oder ein neuer Spieler drankommt */ + + s = getbuf(F, enc); + if (s == NULL) + break; + + if (s[0]) { + if (s[0] != '@') { + char token[64]; + const char *stok = s; + stok = parse_token(&stok, token, sizeof(token)); + + if (stok) { + bool quit = false; + param_t param = findparam(stok, u->faction->locale); + switch (param) { + case P_UNIT: + case P_REGION: + quit = true; + break; + case P_FACTION: + case P_NEXT: + case P_GAMENAME: + /* these terminate the orders, so we apply extra checking */ + if (strlen(stok) >= 3) { + quit = true; + break; + } + else { + quit = false; + } + break; + default: + break; + } + if (quit) { + break; + } + } + } + /* Nun wird der Befehl erzeut und eingehängt */ + *ordp = parse_order(s, u->faction->locale); + if (*ordp) { + ordp = &(*ordp)->next; + } + else { + ADDMSG(&f->msgs, msg_message("parse_error", "unit command", u, s)); + } + } + } + + } + else { + return NULL; + } + return u; +} + +static faction *factionorders(void) { faction *f = NULL; - unit *u = NULL; - char line[1024]; + int fid = getid(); - line = strm->api->readln(strm->handle, line, sizeof(line)); -} + f = findfaction(fid); + + if (f != NULL && !fval(f, FFL_NPC)) { + char token[128]; + const char *pass = gettoken(token, sizeof(token)); + + if (!checkpasswd(f, (const char *)pass)) { + log_debug("Invalid password for faction %s", itoa36(fid)); + ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", pass)); + return 0; + } + /* Die Partei hat sich zumindest gemeldet, so dass sie noch + * nicht als untätig gilt */ + f->lastorders = turn; -void read_orderfile(const char *filename) -{ - stream strm; - FILE * F = fopen(filename, "r"); - if (!F) { - return; } - fstream_init(&strm, F); - read_orders(&strm); - fstream_done(&strm); - fclose(F); + else { + log_debug("orders for invalid faction %s", itoa36(fid)); + } + return f; +} + +int readorders(const char *filename) +{ + FILE *F = NULL; + const char *b; + int nfactions = 0; + int enc_gamedata = ENCODING_UTF8; + struct faction *f = NULL; + + F = fopen(filename, "r"); + if (!F) { + perror(filename); + return -1; + } + log_info("reading orders from %s", filename); + + /* TODO: recognize UTF8 BOM */ + b = getbuf(F, enc_gamedata); + + /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten + * Partei */ + + while (b) { + char token[128]; + const struct locale *lang = f ? f->locale : default_locale; + param_t p; + const char *s; + init_tokens_str(b); + s = gettoken(token, sizeof(token)); + p = findparam_block(s, lang, true); + switch (p) { + case P_GAMENAME: + case P_FACTION: + f = factionorders(); + if (f) { + ++nfactions; + } + + b = getbuf(F, enc_gamedata); + break; + + /* in factionorders wird nur eine zeile gelesen: + * diejenige mit dem passwort. Die befehle der units + * werden geloescht, und die Partei wird als aktiv + * vermerkt. */ + + case P_UNIT: + if (!f || !unitorders(F, enc_gamedata, f)) { + do { + b = getbuf(F, enc_gamedata); + if (!b) { + break; + } + init_tokens_str(b); + s = gettoken(token, sizeof(token)); + p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM; + } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT + && p != P_GAMENAME); + } + break; + + /* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue + * Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut + * durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf + * auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier + * muss buf erneut gefüllt werden, da die betreffende Information in nur + * einer Zeile steht, und nun die nächste gelesen werden muss. */ + + case P_NEXT: + f = NULL; + b = getbuf(F, enc_gamedata); + break; + + default: + b = getbuf(F, enc_gamedata); + break; + } + } + + fclose(F); + log_info("done reading orders for %d factions", nfactions); + return 0; } diff --git a/src/orderfile.h b/src/orderfile.h index 11364d361..b36b8acae 100644 --- a/src/orderfile.h +++ b/src/orderfile.h @@ -7,10 +7,7 @@ extern "C" { #endif - struct stream; - - void read_orderfile(const char *filename); - void read_orders(struct stream *strm); + int readorders(const char *filename); #ifdef __cplusplus }