From dfe34055b68355a836b05df417248544892828e4 Mon Sep 17 00:00:00 2001 From: Alina Lenk Date: Sun, 10 Apr 2022 18:02:32 +0200 Subject: [PATCH] Forbid 'alltemperate' and 'singlepole' server setting requirements They are replaced by world-ranged MinLatitude and MaxLatitude requirements See osdn #44326 Signed-off-by: Alina Lenk --- server/rscompat.c | 57 +++++++++++++++++++++++++++++++++++++++++++ server/rscompat.h | 3 +++ server/rssanity.c | 61 +++++------------------------------------------ server/ruleset.c | 4 ++++ 4 files changed, 70 insertions(+), 55 deletions(-) diff --git a/server/rscompat.c b/server/rscompat.c index b16592cf53..00234b169a 100644 --- a/server/rscompat.c +++ b/server/rscompat.c @@ -439,3 +439,60 @@ const char *rscompat_req_range_3_2(struct rscompat_info *compat, return old_range; } + +/**********************************************************************//** + Update individual requirements. +**************************************************************************/ +void rscompat_req_adjust_3_2(const struct rscompat_info *compat, + const char **ptype, const char **pname, + bool *ppresent, const char *sec_name) +{ + char buf[1024]; + + if (compat->compat_mode && compat->version < RSFORMAT_3_2) { + /* Recreate old "alltemperate" and "singlepole" ServerSetting + * requirements with MinLatitude and MaxLatitude. */ + if (!fc_strcasecmp(universals_n_name(VUT_SERVERSETTING), *ptype)) { + if (!fc_strcasecmp("alltemperate", *pname)) { + /* alltemperate implies no latitudes != 500 + * !alltemperate implies latitudes 0 to 1000 + * ~> alltemperate enabled iff no latitude >= 750 + * (other numbers in [501,1000] would work as well) + * (no latitude <= some number in [0, 499] would work as well) */ + *ptype = universals_n_name(VUT_MINLATITUDE); + *pname = "750"; + *ppresent = !(*ppresent); + + if (compat->log_cb != NULL) { + /* Inform the user that there are different solutions */ + fc_snprintf(buf, sizeof(buf), + "Replaced 'alltemperate' server setting requirement " + "in %s with a MinLatitude requirement. Other " + "equivalent requirements are possible; make sure it " + "makes sense.", sec_name); + compat->log_cb(buf); + } + } else if (!fc_strcasecmp("singlepole", *pname)) { + /* Assume we're updating a sane ruleset, i.e. singlepole reqs only + * possible/relevant when alltemperate is already disabled. + * singlepole implies no latitudes < 0 + * !singlepole implies latitudes -1000 to -1 (given !alltemperate) + * ~> singlepole enabled iff no latitude <= -500 + * (other numbers in [-1000,-1] would work as well) */ + *ptype = universals_n_name(VUT_MAXLATITUDE); + *pname = "-500"; + *ppresent = !(*ppresent); + + if (compat->log_cb != NULL) { + /* Inform the user that there are different solutions */ + fc_snprintf(buf, sizeof(buf), + "Replaced 'singlepole' server setting requirement " + "in %s with a MaxLatitude requirement. Other " + "equivalent requirements are possible; make sure it " + "makes sense.", sec_name); + compat->log_cb(buf); + } + } + } + } +} diff --git a/server/rscompat.h b/server/rscompat.h index 43348e8598..fe11de8d9b 100644 --- a/server/rscompat.h +++ b/server/rscompat.h @@ -62,6 +62,9 @@ enum impr_genus_id rscompat_genus_3_2(struct rscompat_info *compat, const char *rscompat_req_range_3_2(struct rscompat_info *compat, const char *type, const char *old_range); +void rscompat_req_adjust_3_2(const struct rscompat_info *compat, + const char **ptype, const char **pname, + bool *ppresent, const char *sec_name); #ifdef __cplusplus } diff --git a/server/rssanity.c b/server/rssanity.c index 08bcae0516..4999146db0 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -114,6 +114,12 @@ static bool sanity_check_setting_is_game_rule(struct setting *pset) return FALSE; } + if (pset == setting_by_name("alltemperate") + || pset == setting_by_name("singlepole")) { + /* Should be done via world-ranged MinLatitude and MaxLatitude reqs. */ + return FALSE; + } + return TRUE; } @@ -426,57 +432,6 @@ static bool sanity_check_req_set(int reqs_of_type[], return TRUE; } -/**********************************************************************//** - Helper function: Sanity check potential 'singlepole' server setting - requirement in a requirement vector. - 'conjunctive' should be TRUE if the vector is an AND vector (all - requirements must be active), FALSE if it's a disjunctive (OR) vector. - - Returns TRUE iff everything ok. -**************************************************************************/ -static bool -sanity_check_req_vec_singlepole(const struct requirement_vector *preqs, - bool conjunctive, const char *list_for) -{ - bool has_singlepole_req = FALSE; - - requirement_vector_iterate(preqs, preq) { - server_setting_id id; - struct setting *pset; - - if (preq->source.kind != VUT_SERVERSETTING) { - continue; - } - - id = ssetv_setting_get(preq->source.value.ssetval); - fc_assert_ret_val(server_setting_exists(id), FALSE); - pset = setting_by_number(id); - - if (pset == setting_by_name("singlepole")) { - has_singlepole_req = TRUE; - } else if (pset == setting_by_name("alltemperate") - && XOR(conjunctive, preq->present)) { - return TRUE; - } - } requirement_vector_iterate_end; - - if (!has_singlepole_req) { - /* all good */ - return TRUE; - } - - if (conjunctive) { - log_error("%s: Requirement list containing 'singlepole' server" - " setting requirement must also have negated (!present)" - " 'alltemperate' requirement", list_for); - } else { - log_error("%s: Disjunctive requirement list containing 'singlepole'" - " server setting requirement must also have present" - " 'alltemperate' requirement", list_for); - } - return FALSE; -} - /**********************************************************************//** Sanity check requirement vector, including whether it's free of conflicting requirements. @@ -514,10 +469,6 @@ static bool sanity_check_req_vec(const struct requirement_vector *preqs, } } requirement_vector_iterate_end; - if (!sanity_check_req_vec_singlepole(preqs, conjunctive, list_for)) { - return FALSE; - } - problem = req_vec_suggest_repair(preqs, req_vec_vector_number, preqs); if (problem != NULL) { log_error("%s: %s.", list_for, problem->description); diff --git a/server/ruleset.c b/server/ruleset.c index 49101a2d7a..4de97522a4 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -745,6 +745,10 @@ struct requirement_vector *lookup_req_list(struct section_file *file, "'%s.%s%d'.", filename, sec, sub, j); } + if (compat->compat_mode) { + rscompat_req_adjust_3_2(compat, &type, &name, &present, sec); + } + req = req_from_str(type, range, survives, present, quiet, name); if (req.source.kind == universals_n_invalid()) { ruleset_error(LOG_ERROR, "\"%s\" [%s] has invalid or unknown req: " -- 2.17.1