From e6a78bfd74f3feb87b31cc98dc3b16c4ab0ae0fb Mon Sep 17 00:00:00 2001
From: Kenpachi Developer <Kenpachi.Developer@gmx.de>
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 <path> {<flag>}
 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 <NPC_name> {<flag>}
+ * @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 <NPC_name> {<flag>}).
 		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 <path> {<flag>}
+ * @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 <path> {<flag>}
 		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 <monster name/ID> {<duration>}
+ * @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 <monster name> {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 <path> {<flag>}
+ * @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 <path> {<flag>}
 		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