From 23b589f971b1c0da7bbaa6a98280fd45225b2d8a Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 22 Oct 2023 07:16:19 +0300 Subject: [PATCH 44/44] Base "/list rulesets" info on .modpack files See osdn #43461 Signed-off-by: Marko Lindqvist --- common/modpack.h | 4 +-- server/gamehand.c | 31 ++++++++++++++-------- server/gamehand.h | 4 ++- server/stdinhand.c | 64 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 79 insertions(+), 24 deletions(-) diff --git a/common/modpack.h b/common/modpack.h index 366b4eb930..ae1680f61e 100644 --- a/common/modpack.h +++ b/common/modpack.h @@ -32,7 +32,7 @@ const char *modpack_has_ruleset(struct section_file *sf); bool modpack_check_capabilities(struct section_file *file, const char *us_capstr, const char *filename, bool verbose); - + const char *modpack_serv_file(struct section_file *sf); const char *modpack_rulesetdir(struct section_file *sf); @@ -43,4 +43,4 @@ void modpack_ruleset_cache_iterate(mrc_cb cb, void *data); } #endif /* __cplusplus */ -#endif /* FC__MODPACK_H */ +#endif /* FC__MODPACK_H */ diff --git a/server/gamehand.c b/server/gamehand.c index ad41b135de..9758d470c4 100644 --- a/server/gamehand.c +++ b/server/gamehand.c @@ -1102,7 +1102,7 @@ const char *new_challenge_filename(struct connection *pc) return get_challenge_filename(pc); } -struct mrc_data { +struct mrc_sendclient_data { int count; struct packet_ruleset_choices *packet; }; @@ -1110,10 +1110,10 @@ struct mrc_data { /************************************************************************//** Callback called from modpack ruleset cache iteration. ****************************************************************************/ -static void ruleset_cache_cb(const char *mp_name, const char *filename, - void *data_in) +static void ruleset_cache_sendclient_cb(const char *mp_name, + const char *filename, void *data_in) { - struct mrc_data *data = (struct mrc_data *)data_in; + struct mrc_sendclient_data *data = (struct mrc_sendclient_data *)data_in; const int maxlen = sizeof(data->packet->rulesets[data->count]); if (data->count >= MAX_NUM_RULESETS) { @@ -1131,15 +1131,11 @@ static void ruleset_cache_cb(const char *mp_name, const char *filename, } /************************************************************************//** - Call this on a connection with HACK access to send it a set of ruleset - choices. Probably this should be called immediately when granting - HACK access to a connection. + Create cache of available rulesets. ****************************************************************************/ -static void send_ruleset_choices(struct connection *pc) +void cache_rulesets(void) { - struct packet_ruleset_choices packet; static bool rulesets_cached = FALSE; - struct mrc_data data; if (!rulesets_cached) { struct fileinfo_list *ruleset_choices; @@ -1161,10 +1157,23 @@ static void send_ruleset_choices(struct connection *pc) rulesets_cached = TRUE; } +} + +/************************************************************************//** + Call this on a connection with HACK access to send it a set of ruleset + choices. Probably this should be called immediately when granting + HACK access to a connection. +****************************************************************************/ +static void send_ruleset_choices(struct connection *pc) +{ + struct packet_ruleset_choices packet; + struct mrc_sendclient_data data; + + cache_rulesets(); data.count = 0; data.packet = &packet; - modpack_ruleset_cache_iterate(ruleset_cache_cb, &data); + modpack_ruleset_cache_iterate(ruleset_cache_sendclient_cb, &data); packet.ruleset_count = data.count; diff --git a/server/gamehand.h b/server/gamehand.h index 4df9334578..a0b1a4e4d5 100644 --- a/server/gamehand.h +++ b/server/gamehand.h @@ -24,6 +24,8 @@ void send_game_info(struct conn_list *dest); void send_scenario_info(struct conn_list *dest); void send_scenario_description(struct conn_list *dest); +void cache_rulesets(void); + enum unit_role_id crole_to_role_id(char crole); struct unit_type *crole_to_unit_type(char crole, struct player *pplayer); @@ -32,4 +34,4 @@ void increase_timeout_because_unit_moved(void); const char *new_challenge_filename(struct connection *pc); -#endif /* FC__GAMEHAND_H */ +#endif /* FC__GAMEHAND_H */ diff --git a/server/stdinhand.c b/server/stdinhand.c index d031ac8d96..713d3cd694 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -49,6 +49,7 @@ #include "game.h" #include "map.h" #include "mapimg.h" +#include "modpack.h" #include "packets.h" #include "player.h" #include "research.h" @@ -6842,25 +6843,68 @@ void show_players(struct connection *caller) cmd_reply(CMD_LIST, caller, C_COMMENT, horiz_line); } +struct mrc_listcmd_data { + struct connection *caller; +}; + +/************************************************************************//** + Callback called from modpack ruleset cache iteration. +****************************************************************************/ +static void ruleset_cache_listcmd_cb(const char *mp_name, + const char *filename, void *data_in) +{ + struct mrc_listcmd_data *data = (struct mrc_listcmd_data *)data_in; + struct section_file *sf; + const char *name; + const char *serv; + const char *rsdir; + + name = modpack_file_from_ruleset_cache(mp_name); + + if (name == NULL) { + log_error("Modpack \"%s\" not in ruleset cache", mp_name); + return; + } + + sf = secfile_load(name, FALSE); + + if (sf == NULL) { + log_error("Failed to load modpack file \"%s\"", name); + return; + } + + serv = modpack_serv_file(sf); + rsdir = modpack_rulesetdir(sf); + + if (serv != NULL || rsdir != NULL) { + /* Modpack has ruleset component */ + cmd_reply(CMD_LIST, data->caller, C_COMMENT, "%s : %s : %s", mp_name, + rsdir != NULL ? rsdir : "-", + serv != NULL ? serv : "-"); + } + + secfile_destroy(sf); +} + /**********************************************************************//** - List rulesets (strictly, .serv init script files that conventionally - accompany rulesets). + List rulesets. **************************************************************************/ static void show_rulesets(struct connection *caller) { - struct strvec *serv_list; + struct mrc_listcmd_data data; cmd_reply(CMD_LIST, caller, C_COMMENT, /* TRANS: don't translate text between '' */ - _("List of rulesets available with '%sread' command:"), - (caller ? "/" : "")); + _("List of available rulesets, and how to load them:")); cmd_reply(CMD_LIST, caller, C_COMMENT, horiz_line); + cmd_reply(CMD_LIST, caller, C_COMMENT, + _("Ruleset : /rulesetdir : /read