From 495c45391db8aaace3376e78dfcc6011b7c24f49 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 25 Jan 2018 15:38:55 +0100 Subject: [PATCH 1/8] CID 182344: Integer handling issues --- src/spells.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/spells.c b/src/spells.c index 4c7eb431e..2c20ec447 100644 --- a/src/spells.c +++ b/src/spells.c @@ -539,7 +539,6 @@ static int sp_summon_familiar(castorder * co) const race *rc; int sk; int dh, dh1; - int bytes; message *msg; char zText[2048], *bufp = zText; size_t size = sizeof(zText) - 1; @@ -591,25 +590,25 @@ static int sp_summon_familiar(castorder * co) for (sk = 0; sk < MAXSKILLS; sk++) { if (skill_enabled(sk) && rc->bonus[sk] > -5) { + size_t bytes; dh--; if (dh1 == 0) { dh1 = 1; } else { if (dh == 0) { - bytes = (int) str_strlcpy(bufp, (const char *)LOC(mage->faction->locale, + bytes = str_strlcpy(bufp, (const char *)LOC(mage->faction->locale, "list_and"), size); } else { - bytes = (int)str_strlcpy(bufp, (const char *)", ", size); + bytes = str_strlcpy(bufp, (const char *)", ", size); } - assert(bytes >= 0); + assert(bytes >= 0 && bytes <= INT_MAX); BUFFER_STRCAT(bufp, size, bytes); } - bytes = - str_strlcpy(bufp, (const char *)skillname((skill_t)sk, mage->faction->locale), + bytes = str_strlcpy(bufp, skillname((skill_t)sk, mage->faction->locale), size); - assert(bytes <= INT_MAX); + assert(bytes >= 0 && bytes <= INT_MAX); BUFFER_STRCAT(bufp, size, (int)bytes); } } From 6a9320a0d030629de715a3f1e04c49576aab7f71 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 25 Jan 2018 15:43:29 +0100 Subject: [PATCH 2/8] these casts not required. --- src/spells.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/spells.c b/src/spells.c index 2c20ec447..410235c14 100644 --- a/src/spells.c +++ b/src/spells.c @@ -597,18 +597,18 @@ static int sp_summon_familiar(castorder * co) } else { if (dh == 0) { - bytes = str_strlcpy(bufp, (const char *)LOC(mage->faction->locale, + bytes = str_strlcpy(bufp, LOC(mage->faction->locale, "list_and"), size); } else { - bytes = str_strlcpy(bufp, (const char *)", ", size); + bytes = str_strlcpy(bufp, ", ", size); } - assert(bytes >= 0 && bytes <= INT_MAX); + assert(bytes <= INT_MAX); BUFFER_STRCAT(bufp, size, bytes); } bytes = str_strlcpy(bufp, skillname((skill_t)sk, mage->faction->locale), size); - assert(bytes >= 0 && bytes <= INT_MAX); + assert(bytes <= INT_MAX); BUFFER_STRCAT(bufp, size, (int)bytes); } } From 0170a6fc09ff05f53de23e2094315cb9f14c66fe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 25 Jan 2018 21:31:09 +0100 Subject: [PATCH 3/8] move bsdstring use to reports.c --- src/reports.c | 36 ++++++++++++++++++++++++++++++++++++ src/reports.h | 1 + src/spells.c | 40 ++++------------------------------------ 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/reports.c b/src/reports.c index 3fb068121..0de70964c 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2195,6 +2195,42 @@ static void eval_trail(struct opstack **stack, const void *userdata) #endif } +void report_race_skills(const race *rc, char *zText, size_t length, const struct locale *lang) +{ + size_t size = length - 1; + int dh = 0, dh1 = 0, sk; + char *bufp = zText; + + for (sk = 0; sk < MAXSKILLS; ++sk) { + if (skill_enabled(sk) && rc->bonus[sk] > -5) + dh++; + } + + for (sk = 0; sk < MAXSKILLS; sk++) { + if (skill_enabled(sk) && rc->bonus[sk] > -5) { + size_t bytes; + dh--; + if (dh1 == 0) { + dh1 = 1; + } + else { + if (dh == 0) { + bytes = str_strlcpy(bufp, LOC(lang, "list_and"), size); + } + else { + bytes = str_strlcpy(bufp, ", ", size); + } + assert(bytes <= INT_MAX); + BUFFER_STRCAT(bufp, size, bytes); + } + bytes = str_strlcpy(bufp, skillname((skill_t)sk, lang), + size); + assert(bytes <= INT_MAX); + BUFFER_STRCAT(bufp, size, (int)bytes); + } + } +} + static void eval_direction(struct opstack **stack, const void *userdata) { const faction *report = (const faction *)userdata; diff --git a/src/reports.h b/src/reports.h index 3eaa6137c..e0a560fe8 100644 --- a/src/reports.h +++ b/src/reports.h @@ -120,6 +120,7 @@ extern "C" { int report_items(const struct unit *u, struct item *result, int size, const struct unit *owner, const struct faction *viewer); void report_warnings(struct faction *f, const struct gamedate *date); + void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, const struct faction *viewer, const char **name, const char **basename, int *number, bool singular); diff --git a/src/spells.c b/src/spells.c index 410235c14..8334d19c0 100644 --- a/src/spells.c +++ b/src/spells.c @@ -18,6 +18,7 @@ #include "spells.h" #include "guard.h" +#include "reports.h" #include "spy.h" #include "vortex.h" #include "laws.h" @@ -72,7 +73,6 @@ #include #include #include -#include #include #include #include @@ -537,11 +537,9 @@ static int sp_summon_familiar(castorder * co) unit *mage = co->magician.u; int cast_level = co->level; const race *rc; - int sk; - int dh, dh1; + int dh; message *msg; - char zText[2048], *bufp = zText; - size_t size = sizeof(zText) - 1; + char zText[2048]; if (get_familiar(mage) != NULL) { cmistake(mage, co->order, 199, MSG_MAGIC); @@ -581,37 +579,7 @@ static int sp_summon_familiar(castorder * co) msg_release(msg); make_familiar(mage, r, rc, zText); - dh = 0; - dh1 = 0; - for (sk = 0; sk < MAXSKILLS; ++sk) { - if (skill_enabled(sk) && rc->bonus[sk] > -5) - dh++; - } - - for (sk = 0; sk < MAXSKILLS; sk++) { - if (skill_enabled(sk) && rc->bonus[sk] > -5) { - size_t bytes; - dh--; - if (dh1 == 0) { - dh1 = 1; - } - else { - if (dh == 0) { - bytes = str_strlcpy(bufp, LOC(mage->faction->locale, - "list_and"), size); - } - else { - bytes = str_strlcpy(bufp, ", ", size); - } - assert(bytes <= INT_MAX); - BUFFER_STRCAT(bufp, size, bytes); - } - bytes = str_strlcpy(bufp, skillname((skill_t)sk, mage->faction->locale), - size); - assert(bytes <= INT_MAX); - BUFFER_STRCAT(bufp, size, (int)bytes); - } - } + report_race_skills(rc, zText, sizeof(zText), mage->faction->locale); ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", "mage race skills", mage, rc, zText)); return cast_level; From e233d08e8fdc27fd4784e873df04556a8fd7cfaa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Jan 2018 17:39:15 +0100 Subject: [PATCH 4/8] move more reporting code to reports.c --- src/kernel/race.c | 24 ++++---- src/laws.c | 144 ++------------------------------------------ src/reports.c | 148 +++++++++++++++++++++++++++++++++++++++++----- src/reports.h | 4 +- 4 files changed, 149 insertions(+), 171 deletions(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index dd0649afb..cb63647b5 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -38,7 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include #include #include #include @@ -536,21 +535,18 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc) if (prefix != NULL) { static char lbuf[80]; /* FIXME: static return value */ - char *bufp = lbuf; - size_t size = sizeof(lbuf) - 1; - int ch, bytes; + sbstring sbs; + char ch[2]; - bytes = (int)str_strlcpy(bufp, LOC(loc, mkname("prefix", prefix)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_init(&sbs, lbuf, sizeof(lbuf)); + sbs_strcpy(&sbs, LOC(loc, mkname("prefix", prefix))); - bytes = (int)str_strlcpy(bufp, LOC(loc, rc_name_s(rc, u->number != 1)), size); - assert(~bufp[0] & 0x80 || !"unicode/not implemented"); - ch = tolower(*(unsigned char *)bufp); - bufp[0] = (char)ch; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - *bufp = 0; + str = LOC(loc, rc_name_s(rc, u->number != 1)); + assert(~str[0] & 0x80 || !"unicode/not implemented"); + ch[0] = (char)tolower(*(unsigned char *)str); + ch[1] = 0; + sbs_strcat(&sbs, ch); + sbs_strcat(&sbs, str + 1); return lbuf; } diff --git a/src/laws.c b/src/laws.c index 7b416f8a4..d90d2f173 100644 --- a/src/laws.c +++ b/src/laws.c @@ -81,7 +81,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -2265,146 +2264,11 @@ static void display_item(unit * u, const item_type * itype) itype->weight, itype->rtype, info)); } -static void display_race(unit * u, const race * rc) +static void display_race(faction * f, const race * rc) { - faction * f = u->faction; - const char *name, *key; - const char *info; - int a, at_count; - char buf[2048], *bufp = buf; - size_t size = sizeof(buf) - 1; - size_t bytes; + char buf[2048]; - name = rc_name_s(rc, NAME_SINGULAR); - - bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - key = mkname("raceinfo", rc->_name); - info = locale_getstring(f->locale, key); - if (info == NULL) { - info = LOC(f->locale, mkname("raceinfo", "no_info")); - } - - if (info) bufp = STRLCPY(bufp, info, size); - - /* hp_p : Trefferpunkte */ - bytes = - slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale, - "stat_hitpoints")); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_attacke : Angriff */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"), - (rc->at_default + rc->at_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_defense : Verteidigung */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"), - (rc->df_default + rc->df_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_armor : Rüstung */ - if (rc->armor > 0) { - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - } - - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); - - /* b_damage : Schaden */ - at_count = 0; - for (a = 0; a < RACE_ATTACKS; a++) { - if (rc->attack[a].type != AT_NONE) { - at_count++; - } - } - if (rc->battle_flags & BF_EQUIPMENT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_equipment"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_PIERCE) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_pierce"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_CUT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_cut"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_BASH) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_bash"))) != 0) - WARN_STATIC_BUFFER(); - } - - if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(f->locale, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) - WARN_STATIC_BUFFER(); - - for (a = 0; a < RACE_ATTACKS; a++) { - if (rc->attack[a].type != AT_NONE) { - if (a != 0) - bufp = STRLCPY(bufp, ", ", size); - else - bufp = STRLCPY(bufp, ": ", size); - - switch (rc->attack[a].type) { - case AT_STANDARD: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_standard"), rc->def_damage); - break; - case AT_NATURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_natural"), rc->attack[a].data.dice); - break; - case AT_SPELL: - case AT_COMBATSPELL: - case AT_DRAIN_ST: - case AT_DRAIN_EXP: - case AT_DAZZLE: - bytes = (size_t)snprintf(bufp, size, "%s", LOC(f->locale, "attack_magical")); - break; - case AT_STRUCTURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_structural"), rc->attack[a].data.dice); - break; - default: - bytes = 0; - } - - assert(bytes <= INT_MAX); - if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - } - } - - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); - - *bufp = 0; + report_raceinfo(rc, f->locale, buf, sizeof(buf)); addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT); } @@ -2453,7 +2317,7 @@ static void reshow_other(unit * u, struct order *ord, const char *s) { } if (rc && u_race(u) == rc) { - display_race(u, rc); + display_race(u->faction, rc); found = true; } } diff --git a/src/reports.c b/src/reports.c index 0de70964c..b3aee94e0 100644 --- a/src/reports.c +++ b/src/reports.c @@ -363,25 +363,145 @@ static void report_resource(resource_report * result, const resource_type *rtype result->level = level; } -void report_race(const struct unit *u, const char **name, const char **illusion) +void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length) { - if (illusion) { - const race *irace = u_irace(u); - if (irace && irace != u_race(u)) { - *illusion = irace->_name; - } - else { - *illusion = NULL; + const char *info; + int a, at_count; + const char *name, *key; + char *bufp = buf; + size_t size = length - 1; + size_t bytes; + + name = rc_name_s(rc, NAME_SINGULAR); + + bytes = slprintf(bufp, size, "%s: ", LOC(lang, name)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + key = mkname("raceinfo", rc->_name); + info = locale_getstring(lang, key); + if (info == NULL) { + info = LOC(lang, mkname("raceinfo", "no_info")); + } + + if (info) bufp = STRLCPY(bufp, info, size); + + /* hp_p : Trefferpunkte */ + bytes = + slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(lang, + "stat_hitpoints")); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_attacke : Angriff */ + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_attack"), + (rc->at_default + rc->at_bonus)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_defense : Verteidigung */ + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_defense"), + (rc->df_default + rc->df_bonus)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_armor : Rüstung */ + if (rc->armor > 0) { + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_armor"), rc->armor); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + } + + if (size > 1) { + *bufp++ = '.'; + --size; + } + else + WARN_STATIC_BUFFER(); + + /* b_damage : Schaden */ + at_count = 0; + for (a = 0; a < RACE_ATTACKS; a++) { + if (rc->attack[a].type != AT_NONE) { + at_count++; } } - if (name) { - *name = u_race(u)->_name; - if (fval(u_race(u), RCF_SHAPESHIFTANY)) { - const char *str = get_racename(u->attribs); - if (str) - *name = str; + if (rc->battle_flags & BF_EQUIPMENT) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_equipment"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_PIERCE) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_pierce"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_CUT) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_cut"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_BASH) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_bash"))) != 0) + WARN_STATIC_BUFFER(); + } + + if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) + WARN_STATIC_BUFFER(); + + for (a = 0; a < RACE_ATTACKS; a++) { + if (rc->attack[a].type != AT_NONE) { + if (a != 0) + bufp = STRLCPY(bufp, ", ", size); + else + bufp = STRLCPY(bufp, ": ", size); + + switch (rc->attack[a].type) { + case AT_STANDARD: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_standard"), rc->def_damage); + break; + case AT_NATURAL: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_natural"), rc->attack[a].data.dice); + break; + case AT_SPELL: + case AT_COMBATSPELL: + case AT_DRAIN_ST: + case AT_DRAIN_EXP: + case AT_DAZZLE: + bytes = (size_t)snprintf(bufp, size, "%s", LOC(lang, "attack_magical")); + break; + case AT_STRUCTURAL: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_structural"), rc->attack[a].data.dice); + break; + default: + bytes = 0; + } + + assert(bytes <= INT_MAX); + if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); } } + + if (size > 1) { + *bufp++ = '.'; + --size; + } + else + WARN_STATIC_BUFFER(); + + *bufp = 0; } void diff --git a/src/reports.h b/src/reports.h index e0a560fe8..0c285257e 100644 --- a/src/reports.h +++ b/src/reports.h @@ -120,15 +120,13 @@ extern "C" { int report_items(const struct unit *u, struct item *result, int size, const struct unit *owner, const struct faction *viewer); void report_warnings(struct faction *f, const struct gamedate *date); + void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length); void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, const struct faction *viewer, const char **name, const char **basename, int *number, bool singular); void report_building(const struct building *b, const char **btype, const char **billusion); - void report_race(const struct unit *u, const char **rcname, - const char **rcillusion); - void add_seen_faction(struct faction *self, struct faction *seen); size_t f_regionid(const struct region *r, const struct faction *f, char *buffer, size_t size); From 1c535b8dda4573688a538b5f67b5da98486d9471 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Jan 2018 17:45:40 +0100 Subject: [PATCH 5/8] rough test of familiar spell --- scripts/tests/e2/spells.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua index d05552a2d..deeb2798c 100644 --- a/scripts/tests/e2/spells.lua +++ b/scripts/tests/e2/spells.lua @@ -103,3 +103,24 @@ function test_earn_silver() assert_equal(350, u:get_item("money")) assert_equal(0, r:get_resource("money")) end + +function test_familiar() + local r = region.create(0, 0, "mountain") + local f = faction.create("human") + local u = unit.create(f, r) + local uid = u.id + u.name = 'Hodor' + u.magic = "gwyrrd" + u.race = "elf" + u:set_skill("magic", 10) + u.aura = 200 + local err = u:add_spell("summon_familiar") + assert_equal(0, err) + u:add_order("ZAUBERE Vertrauten~rufen") + process_orders() + for u in r.units do + if u.id ~= uid then + assert_equal('Vertrauter von Hodor (' .. itoa36(uid) ..')', u.name) + end + end +end From ff85cda72436c5df88e5dd17be88fc935c9b1b0d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Jan 2018 17:56:24 +0100 Subject: [PATCH 6/8] stop using sqlite for a player database --- scripts/run-turn.lua | 16 +--- src/CMakeLists.txt | 13 +--- src/bind_sqlite.c | 88 ---------------------- src/bindings.c | 3 - src/bindings.h | 1 - src/sqlite.c | 172 ------------------------------------------- 6 files changed, 3 insertions(+), 290 deletions(-) delete mode 100644 src/bind_sqlite.c delete mode 100644 src/sqlite.c diff --git a/scripts/run-turn.lua b/scripts/run-turn.lua index 34c1ea4fb..88744db94 100644 --- a/scripts/run-turn.lua +++ b/scripts/run-turn.lua @@ -25,20 +25,6 @@ function callbacks(rules, name, ...) end end -local function dbupdate() - update_scores() - if config.dbname then - dbname = config.basepath..'/'..config.dbname - edb = db.open(dbname) - if edb~=nil then - edb:update_factions() - edb:update_scores() - else - eressea.log.error("could not open "..dbname) - end - end -end - local function write_emails(locales) local files = {} local key @@ -161,7 +147,7 @@ function process(rules, orders) turn_end() -- ageing, etc. write_files(config.locales) - dbupdate() + update_scores() file = '' .. get_turn() .. '.dat' if eressea.write_game(file)~=0 then diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 268d34efd..7518bb2d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -162,13 +162,6 @@ set(SERVER_SRC bind_unit.c ) -if (SQLITE3_FOUND) -set (SERVER_SRC ${SERVER_SRC} - sqlite.c - bind_sqlite.c -) -endif (SQLITE3_FOUND) - if (CURSES_FOUND) set (SERVER_SRC ${SERVER_SRC} gmtool.c @@ -295,15 +288,13 @@ target_link_libraries(convert ${DB_LIBRARIES}) target_link_libraries(eressea ${DB_LIBRARIES}) target_link_libraries(test_eressea ${DB_LIBRARIES}) add_definitions(-DUSE_DB) -endif(DB_FOUND) - -if (SQLITE3_FOUND) +elseif (SQLITE3_FOUND) include_directories (${SQLITE3_INCLUDE_DIR}) target_link_libraries(eressea ${SQLITE3_LIBRARIES}) target_link_libraries(convert ${SQLITE3_LIBRARIES}) target_link_libraries(test_eressea ${SQLITE3_LIBRARIES}) add_definitions(-DUSE_SQLITE) -endif(SQLITE3_FOUND) +endif(DB_FOUND) if (CURSES_FOUND) include_directories (${CURSES_INCLUDE_DIR}) diff --git a/src/bind_sqlite.c b/src/bind_sqlite.c deleted file mode 100644 index 3af4843ea..000000000 --- a/src/bind_sqlite.c +++ /dev/null @@ -1,88 +0,0 @@ -#ifdef _MSC_VER -#include -#endif - -#include "bind_unit.h" -#include "bindings.h" - -#include /* for game_id */ -#include - -#include -#include -#include - -#define LTYPE_DB TOLUA_CAST "db" - -extern int db_update_factions(sqlite3 * db, bool force, int game); -static int tolua_db_update_factions(lua_State * L) -{ - sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); - db_update_factions(db, tolua_toboolean(L, 2, 0), game_id()); - return 0; -} - -extern int db_update_scores(sqlite3 * db, bool force); -static int tolua_db_update_scores(lua_State * L) -{ - sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); - db_update_scores(db, tolua_toboolean(L, 2, 0)); - return 0; -} - -static int tolua_db_execute(lua_State * L) -{ - sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); - const char *sql = tolua_tostring(L, 2, 0); - - int res = sqlite3_exec(db, sql, 0, 0, 0); - - lua_pushinteger(L, res); - return 1; -} - -static int tolua_db_close(lua_State * L) -{ - sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); - sqlite3_close(db); - return 0; -} - -static int tolua_db_create(lua_State * L) -{ - sqlite3 *db; - const char *dbname = tolua_tostring(L, 1, 0); - int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0); - if (result == SQLITE_OK) { - tolua_pushusertype(L, (void *)db, LTYPE_DB); - return 1; - } - return 0; -} - -int tolua_sqlite_open(lua_State * L) -{ - /* register user types */ - - tolua_usertype(L, LTYPE_DB); - - tolua_module(L, NULL, 0); - tolua_beginmodule(L, NULL); - { - tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL); - tolua_beginmodule(L, LTYPE_DB); - { - tolua_function(L, TOLUA_CAST "open", &tolua_db_create); - tolua_function(L, TOLUA_CAST "close", &tolua_db_close); - - tolua_function(L, TOLUA_CAST "update_factions", - &tolua_db_update_factions); - tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores); - tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute); - } - tolua_endmodule(L); - - } - tolua_endmodule(L); - return 0; -} diff --git a/src/bindings.c b/src/bindings.c index c5494e64b..4bf999af1 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -1119,9 +1119,6 @@ lua_State *lua_init(const dictionary *inifile) { register_tolua_helpers(); tolua_bindings_open(L, inifile); tolua_eressea_open(L); -#ifdef USE_SQLITE - tolua_sqlite_open(L); -#endif tolua_unit_open(L); tolua_building_open(L); tolua_ship_open(L); diff --git a/src/bindings.h b/src/bindings.h index b5ebf916b..038afd31e 100755 --- a/src/bindings.h +++ b/src/bindings.h @@ -19,7 +19,6 @@ extern "C" { struct selist; int tolua_toid(struct lua_State *L, int idx, int def); - int tolua_sqlite_open(struct lua_State *L); int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d); int tolua_itemlist_next(struct lua_State *L); int tolua_selist_push(struct lua_State *L, const char *list_type, diff --git a/src/sqlite.c b/src/sqlite.c deleted file mode 100644 index e25d105d2..000000000 --- a/src/sqlite.c +++ /dev/null @@ -1,172 +0,0 @@ -#ifdef _MSC_VER -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct db_faction { - int uid; - int no; - char *email; - char *name; -} db_faction; - -static struct selist * -read_factions(sqlite3 * db, int game_id) { - int res; - selist *result = 0; - const char * sql = - "SELECT f.id, fd.code, fd.name, fd.email FROM faction f" - " LEFT OUTER JOIN faction_data fd" - " WHERE f.id=fd.faction_id AND f.game_id=? AND" - " fd.turn=(SELECT MAX(turn) FROM faction_data fx WHERE fx.faction_id=f.id)" - " ORDER BY f.id"; - sqlite3_stmt *stmt = 0; - sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - sqlite3_bind_int(stmt, 1, game_id); - - res = sqlite3_step(stmt); - while (res == SQLITE_ROW) { - const char * text; - db_faction * dbf = (db_faction*)calloc(1, sizeof(db_faction)); - dbf->uid = (int)sqlite3_column_int64(stmt, 0); - text = (const char *)sqlite3_column_text(stmt, 1); - if (text) dbf->no = atoi36(text); - text = (const char *)sqlite3_column_text(stmt, 2); - if (text) dbf->name = str_strdup(text); - text = (const char *)sqlite3_column_text(stmt, 3); - if (text) dbf->email = str_strdup(text); - selist_push(&result, dbf); - res = sqlite3_step(stmt); - } - sqlite3_finalize(stmt); - return result; -} - -static int insert_faction(sqlite3 *db, int game_id, faction *f) { - const char *sql = "INSERT INTO faction (game_id, race) VALUES (?, ?)"; - sqlite3_stmt *stmt = 0; - sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - sqlite3_bind_int(stmt, 1, game_id); - sqlite3_bind_text(stmt, 2, f->race->_name, -1, SQLITE_STATIC); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - return (int)sqlite3_last_insert_rowid(db); -} - -static void update_faction(sqlite3 *db, const faction *f) { - char code[5]; - const char *sql = - "INSERT INTO faction_data (faction_id, code, name, email, lang, turn)" - " VALUES (?, ?, ?, ?, ?, ?)"; - sqlite3_stmt *stmt = 0; - strcpy(code, itoa36(f->no)); - sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - sqlite3_bind_int(stmt, 1, f->subscription); - sqlite3_bind_text(stmt, 2, code, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 3, f->name, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 4, f->email, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 5, locale_name(f->locale), -1, SQLITE_STATIC); - sqlite3_bind_int(stmt, 6, turn); - sqlite3_step(stmt); - sqlite3_finalize(stmt); -} - -struct cb_data { - const faction *f; - sqlite3 *db; - db_faction *dbf; -}; - -static bool db_faction_cb(void *el, void *arg) { - db_faction *df = (db_faction *)el; - struct cb_data *cb = (struct cb_data *)arg; - const faction *f = cb->f; - - /* FIXME comparing name and email is inaccurate ... */ - if (f->no == df->no || strcmp(faction_getemail(f), df->email?df->email:"") == 0 || strcmp(f->name, df->name) == 0) { - cb->dbf = df; - } - if (f->subscription == df->uid) { - cb->dbf = df; - return false; - } - return true; -} - -int db_update_factions(sqlite3 * db, bool force, int game_id) { - selist *ql = read_factions(db, game_id); - if (ql) { - faction *f; - struct cb_data cbdata; - cbdata.db = db; - cbdata.dbf = NULL; - sqlite3_exec(db, "BEGIN", 0, 0, 0); - for (f = factions; f; f = f->next) { - bool update = force; - cbdata.f = f; - selist_foreach_ex(ql, db_faction_cb, &cbdata); - if (cbdata.dbf) { - const db_faction *dbf = cbdata.dbf; - if (dbf->uid != f->subscription) { - log_warning("faction %s(%d) not found in database, but matches %d\n", itoa36(f->no), f->subscription, dbf->uid); - f->subscription = dbf->uid; - } - update = (dbf->no != f->no) || (strcmp(faction_getemail(f), dbf->email?dbf->email:"") != 0) || (strcmp(f->name, dbf->name) != 0); - } - else { - f->subscription = insert_faction(db, game_id, f); - log_warning("faction %s not found in database, created as %d\n", itoa36(f->no), f->subscription); - update = true; - } - if (update) { - update_faction(db, f); - log_debug("faction %s updated\n", itoa36(f->no)); - } - } - sqlite3_exec(db, "COMMIT", 0, 0, 0); - } - return SQLITE_OK; -} - -int db_update_scores(sqlite3 * db, bool force) -{ - /* - const char *sselist_ins = - "INSERT OR FAIL INTO score (value,faction_id,turn) VALUES (?,?,?)"; - sqlite3_stmt *stmt_ins = stmt_cache_get(db, sselist_ins); - const char *sselist_upd = - "UPDATE score set value=? WHERE faction_id=? AND turn=?"; - sqlite3_stmt *stmt_upd = stmt_cache_get(db, sselist_upd); - faction *f; - sqlite3_exec(db, "BEGIN", 0, 0, 0); - for (f = factions; f; f = f->next) { - int res; - sqlite3_bind_int(stmt_ins, 1, f->score); - sqlite3_bind_int64(stmt_ins, 2, f->subscription); - sqlite3_bind_int(stmt_ins, 3, turn); - res = sqlite3_step(stmt_ins); - if (res == SQLITE_CONSTRAINT) { - sqlite3_bind_int(stmt_upd, 1, f->score); - sqlite3_bind_int64(stmt_upd, 2, f->subscription); - sqlite3_bind_int(stmt_upd, 3, turn); - res = sqlite3_step(stmt_upd); - sqlite3_reset(stmt_upd); - } - sqlite3_reset(stmt_ins); - } - sqlite3_exec(db, "COMMIT", 0, 0, 0); - */ - return SQLITE_OK; -} From b0ef4686172963b19724e875685446ef2ced912c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Jan 2018 18:02:10 +0100 Subject: [PATCH 7/8] select berkeley over sqlite, compile only one --- src/kernel/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 4050ead55..9e5a38ed2 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -38,11 +38,9 @@ SET(_DBFILES db/critbit.c) IF(DB_FOUND) SET(_DBFILES db/berkeley.c) -ENDIF(DB_FOUND) - -IF(SQLITE3_FOUND) +ELSEIF(SQLITE3_FOUND) SET(_DBFILES db/sqlite.c) -ENDIF(SQLITE3_FOUND) +ENDIF(DB_FOUND) SET(_FILES ${_DBFILES} From ed623732d312eb66f8a93e6113d248a1ccddbf42 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 26 Jan 2018 18:18:12 +0100 Subject: [PATCH 8/8] fix reduce_skill max_week calculation. --- src/kernel/skills.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/kernel/skills.c b/src/kernel/skills.c index 5cae0f709..8c4b4d2a6 100644 --- a/src/kernel/skills.c +++ b/src/kernel/skills.c @@ -178,6 +178,7 @@ void sk_set(skill * sv, int level) assert(sv && level != 0); sv->weeks = skill_weeks(level); sv->level = level; + assert(sv->weeks <= sv->level * 2 + 1); } static bool rule_random_progress(void) @@ -215,6 +216,7 @@ void increase_skill(unit * u, skill_t sk, int weeks) sk_set(sv, sv->level + 1); } sv->weeks -= weeks; + assert(sv->weeks <= sv->level * 2 + 1); } void reduce_skill(unit * u, skill * sv, int weeks) @@ -229,11 +231,13 @@ void reduce_skill(unit * u, skill * sv, int weeks) while (sv->level > 0 && sv->weeks > max_weeks) { sv->weeks -= sv->level; --sv->level; + max_weeks -= 2; } if (sv->level == 0) { /* reroll */ sv->weeks = skill_weeks(sv->level); } + assert(sv->weeks <= sv->level * 2 + 1); } int skill_compare(const skill * sk, const skill * sc)