From e6a78bfd74f3feb87b31cc98dc3b16c4ab0ae0fb Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Sun, 5 Jan 2020 11:30:18 +0100 Subject: Applied code style and added some minor code improvements to src/map/atcommands.c. * Applied code style to touched @commands. * Added file path validation where fopen() is used to make sure a TXT file is passed. * Added new messages for file name validation to conf/messages.conf. * increased MAX_MSG to be able to use the new messages. --- conf/messages.conf | 4 +++ src/map/atcommand.c | 91 ++++++++++++++++++++++++++++++++++++++++++----------- src/map/atcommand.h | 2 +- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/conf/messages.conf b/conf/messages.conf index e457ed882..e65ceaa48 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -1640,5 +1640,9 @@ 1516: Usage: @reloadnpc {} 1517: Script could not be unloaded. +// File name validation +1518: No file extension specified. +1519: Not a TXT file. + //Custom translations import: conf/import/msg_conf.txt diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3cb10b5ad..0d84dd46e 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -4483,14 +4483,20 @@ ACMD(loadnpc) return true; } +/** + * Unloads a specific NPC. + * + * @code{.herc} + * @unloadnpc {} + * @endcode + * + **/ ACMD(unloadnpc) { - char npc_name[NAME_LENGTH + 1]; + char npc_name[NAME_LENGTH + 1] = {'\0'}; int flag = 1; - memset(npc_name, '\0', sizeof(npc_name)); - - if (*message == '\0' || sscanf(message, "%24s %5d", npc_name, &flag) < 1) { + if (*message == '\0' || sscanf(message, "%24s %1d", npc_name, &flag) < 1) { clif->message(fd, msg_fd(fd, 1133)); /// Please enter a NPC name (Usage: @unloadnpc {}). return false; } @@ -4509,19 +4515,37 @@ ACMD(unloadnpc) return true; } -/// Unload existing NPC within the NPC file and reload it. -/// Usage: @reloadnpc npc/sample_npc.txt {flag} -/// Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. +/** + * Unloads a script file and reloads it. + * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. + * + * @code{.herc} + * @reloadnpc {} + * @endcode + * + **/ ACMD(reloadnpc) { - char file_path[100]; + char file_path[100] = {'\0'}; int flag = 1; - if (*message == '\0' || (sscanf(message, "%99s %5d", file_path, &flag) < 1)) { + if (*message == '\0' || (sscanf(message, "%99s %1d", file_path, &flag) < 1)) { clif->message(fd, msg_fd(fd, 1516)); /// Usage: @reloadnpc {} return false; } + const char *dot = strrchr(file_path, '.'); + + if (dot == NULL) { + clif->message(fd, msg_fd(fd, 1518)); /// No file extension specified. + return false; + } + + if (strlen(dot) < 4 || strncmp(dot, ".txt", 4) != 0) { + clif->message(fd, msg_fd(fd, 1519)); /// Not a TXT file. + return false; + } + FILE *fp = fopen(file_path, "r"); if (fp == NULL) { @@ -6581,13 +6605,21 @@ ACMD(reset) /*========================================== * *------------------------------------------*/ + +/** + * Spawns mobs which treats the invoking as its master. + * + * @code{.herc} + * @summon {} + * @endcode + * + **/ ACMD(summon) { - char name[NAME_LENGTH]; + char name[NAME_LENGTH + 1] = {'\0'}; int duration = 0; - if (*message == '\0' || sscanf(message, "%23s %12d", name, &duration) < 1) - { + if (*message == '\0' || sscanf(message, "%24s %12d", name, &duration) < 1) { clif->message(fd, msg_fd(fd, 1225)); /// Please enter a monster name (usage: @summon {duration}). return false; } @@ -6597,13 +6629,13 @@ ACMD(summon) if (mob_id == 0) mob_id = mob->db_searchname(name); - if (mob_id == 0 || mob->db_checkid(mob_id) == 0) - { + if (mob_id == 0 || mob->db_checkid(mob_id) == 0) { clif->message(fd, msg_fd(fd, 40)); /// Invalid monster ID or name. return false; } - struct mob_data *md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE, 0); + struct mob_data *md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", + SZ_SMALL, AI_NONE, 0); if (md == NULL) return false; @@ -6611,9 +6643,9 @@ ACMD(summon) md->master_id = sd->bl.id; md->special_state.ai = AI_ATTACK; - int64 tick = timer->gettick(); + const int64 tick = timer->gettick(); - md->deletetimer = timer->add(tick + cap_value(duration, 1, 60) * 60000, mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(tick + (int64)cap_value(duration, 1, 60) * 60000, mob->timer_delete, md->bl.id, 0); clif->specialeffect(&md->bl, 344, AREA); mob->spawn(md); sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); @@ -9011,16 +9043,37 @@ ACMD(addperm) return true; } +/** + * Unloads a script file. + * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. + * + * @code{.herc} + * @unloadnpcfile {} + * @endcode + * + **/ ACMD(unloadnpcfile) { - char file_path[100]; + char file_path[100] = {'\0'}; int flag = 1; - if (*message == '\0' || (sscanf(message, "%99s %5d", file_path, &flag) < 1)) { + if (*message == '\0' || (sscanf(message, "%99s %1d", file_path, &flag) < 1)) { clif->message(fd, msg_fd(fd, 1385)); /// Usage: @unloadnpcfile {} return false; } + const char *dot = strrchr(file_path, '.'); + + if (dot == NULL) { + clif->message(fd, msg_fd(fd, 1518)); /// No file extension specified. + return false; + } + + if (strlen(dot) < 4 || strncmp(dot, ".txt", 4) != 0) { + clif->message(fd, msg_fd(fd, 1519)); /// Not a TXT file. + return false; + } + FILE *fp = fopen(file_path, "r"); if (fp == NULL) { diff --git a/src/map/atcommand.h b/src/map/atcommand.h index f3b1be51b..66827b3b2 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -41,7 +41,7 @@ struct config_setting_t; * Defines **/ #define ATCOMMAND_LENGTH 50 -#define MAX_MSG 1516 +#define MAX_MSG 1520 #define msg_txt(idx) atcommand->msg(idx) #define msg_sd(sd,msg_number) atcommand->msgsd((sd),(msg_number)) #define msg_fd(fd,msg_number) atcommand->msgfd((fd),(msg_number)) -- cgit v1.2.3-70-g09d2