فهرست منبع

* Consolidated is_atcommand() and is_atcommand_sub()
- replaced gmlvl arg with a flag arg for internal/player generated checks. (dummy sds that used this arg are given gm levels)
- each command check runs through is_atcommand() and is checked for its origin (internal or player generated)
- charcommands are also parsed in this function.
- script atcommand/charcommand function calls to is_atcommand() have been updated
- also updated some clif/map functions calls to is_atcommand()
* charcommands should now log properly with the target of the command included.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13545 54d463be-8e91-2dee-dedb-b68131a5f0ec

sketchyphoenix 16 سال پیش
والد
کامیت
35dbe82eea
6فایلهای تغییر یافته به همراه107 افزوده شده و 113 حذف شده
  1. 7 0
      Changelog-Trunk.txt
  2. 86 86
      src/map/atcommand.c
  3. 1 2
      src/map/atcommand.h
  4. 5 5
      src/map/clif.c
  5. 1 1
      src/map/map.c
  6. 7 19
      src/map/script.c

+ 7 - 0
Changelog-Trunk.txt

@@ -8,6 +8,13 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 	* Added missing delete_timer's every time spawn_timer is being set. (except when allocating)
 	* Made mob_timer_delete check the deletetimer in the mob.
 	* Added missing delete_timer's every time deletetimer is being set. (except when allocating)
+	* Consolidated is_atcommand() and is_atcommand_sub() [SketchyPhoenix]
+	- replaced gmlvl arg with a flag arg for internal/player generated checks. (dummy sds that used this arg are given gm levels)
+	- each command check runs through is_atcommand() and is checked for its origin (internal or player generated)
+	- charcommands are also parsed in this function.
+	- script atcommand/charcommand function calls to is_atcommand() have been updated
+	- also updated some clif/map functions calls to is_atcommand()
+	* charcommands should now log properly with the target of the command included.
 2009/02/20
 	* Increased variable size for status/skill points to remove the 65k cap (bugreport:1579) [ultramage]
 	* Modified WFIFOSET to trigger a fatal error when trying to send a packet that is too big. [FlavioJS]

+ 86 - 86
src/map/atcommand.c

@@ -8924,103 +8924,66 @@ int get_atcommand_level(const AtCommandFunc func)
 
 
 /// Executes an at-command.
-/// To be called by internal server code (bypasses various restrictions).
-bool is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl)
+bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type)
 {
-	AtCommandInfo* info;
-	struct map_session_data *ssd;
+	char charname[NAME_LENGTH], params[100];
+	char charname2[NAME_LENGTH], params2[100];
 	char command[100];
-	char args[100];
 	char output[200];
+	int x, y, z;
 	
-	if( !str || !*str )
-		return false;
-	
-	if( *str != atcommand_symbol && *str != charcommand_symbol ) // check first char
-		return false;
-	
-	if( sscanf(str, "%99s %99[^\n]", command, args) < 2 )
-		args[0] = '\0';
-
-	info = get_atcommandinfo_byname(command);
-	if( info == NULL || info->func == NULL || ( *str == atcommand_symbol && gmlvl < info->level ) || ( *str == charcommand_symbol && gmlvl < info->level2 ) )
-	{
-		if( gmlvl == 0 )
-			return false; // will just display as normal text
-		else
-		{
-			sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
-			clif_displaymessage(fd, output);
-			return true;
-		}
-	}
-
-	if( log_config.gm && info->level >= log_config.gm && *str == atcommand_symbol )
-		log_atcommand(sd, str);
-	
-	if( log_config.gm && info->level2 >= log_config.gm && *str == charcommand_symbol 
-	&& (ssd = (struct map_session_data *)session[fd]->session_data) != NULL )
-		log_atcommand(ssd, str);
-
-	if( info->func(fd, sd, command, args) != 0 )
-	{
-		sprintf(output, msg_txt(154), command); // "%s failed."
-		clif_displaymessage(fd, output);
-	}
+	//Reconstructed message
+	char atcmd_msg[200];
 	
-	return true;
-}
+	TBL_PC * ssd = NULL; //sd for target
+	AtCommandInfo * info;
 
-/// Executes an at-command.
-/// To be used by player-invoked code (restrictions will be applied).
-bool is_atcommand(const int fd, struct map_session_data* sd, const char* message)
-{
-	struct map_session_data* pl_sd;
-	
-	char charname[NAME_LENGTH], charname2[NAME_LENGTH];
-	char cmd[100];
-	char param[100], param2[100];
-	char output[200];
-	char message2[200];
-	
-	int x, y, z, gmlvl = pc_isGM(sd);
-	
 	nullpo_retr(false, sd);
 	
+	//Shouldn't happen
 	if( !message || !*message )
-		return false; // shouldn't happen
-	
-	if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND )
-		return true; // so that it won't display as normal message
-	
-	if( battle_config.atc_gmonly != 0 && gmlvl == 0 )
 		return false;
 	
-	if( map[sd->bl.m].nocommand && gmlvl < map[sd->bl.m].nocommand )
-	{
-		clif_displaymessage(fd, msg_txt(143)); // "Commands are disabled on this map."
-		return false;
-	}
-	
+	//Block NOCHAT but do not display it as a normal message
+	if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND )
+		return true;
+		
 	// skip 10/11-langtype's codepage indicator, if detected
 	if( message[0] == '|' && strlen(message) >= 4 && (message[3] == atcommand_symbol || message[3] == charcommand_symbol) )
 		message += 3;
-
-	if (*message == charcommand_symbol)
+		
+	//Should display as a normal message
+	if ( *message != atcommand_symbol && *message != charcommand_symbol )
+		return false;
+	
+	// type value 0 = server invoked: bypass restrictions
+	// 1 = player invoked
+	if( type )
 	{
-		if (gmlvl == 0)
+		//Commands are disabled on maps flagged as 'nocommand'
+		if( map[sd->bl.m].nocommand && pc_isGM(sd) < map[sd->bl.m].nocommand )
+		{
+			clif_displaymessage(fd, msg_txt(143));
 			return false;
-			
+		}
+		
+		//Displays as a normal message for Non-GMs
+		if( battle_config.atc_gmonly != 0 && pc_isGM(sd) == 0 )
+			return false;	
+	}
+
+	while (*message == charcommand_symbol)
+	{	
 		//Checks to see if #command has a name or a name + parameters.
-		x = sscanf(message, "%99s \"%23[^\"]\" %99[^\n]", cmd, charname, param);
-		y = sscanf(message, "%99s %23s %99[^\n]", cmd, charname2, param2);
+		x = sscanf(message, "%99s \"%23[^\"]\" %99[^\n]", command, charname, params);
+		y = sscanf(message, "%99s %23s %99[^\n]", command, charname2, params2);
 		
 		//z always has the value of the scan that was successful
 		z = ( x > 1 ) ? x : y;
 		
-		if ( (pl_sd = map_nick2sd(charname)) == NULL  && ( (pl_sd = map_nick2sd(charname2)) == NULL ) )
+		if ( (ssd = map_nick2sd(charname)) == NULL  && ( (ssd = map_nick2sd(charname2)) == NULL ) )
 		{
-			sprintf(output, "%s failed. Player not found.", cmd);
+			sprintf(output, "%s failed. Player not found.", command);
 			clif_displaymessage(fd, output);
 			return true;
 		}
@@ -9029,28 +8992,65 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
 		//can be looked at by the actual command function since most scan to see if the
 		//right parameters are used.
 		if ( x > 2 ) {
-			sprintf(message2, "%s %s", cmd, param);
-			return is_atcommand_sub(fd,pl_sd,message2,gmlvl);
+			sprintf(atcmd_msg, "%s %s", command, params);
+			break;
 		}
 		else if ( y > 2 ) {
-			sprintf(message2, "%s %s", cmd, param2);
-			return is_atcommand_sub(fd,pl_sd,message2,gmlvl);
+			sprintf(atcmd_msg, "%s %s", command, params2);
+			break;
 		}
-		
 		//Regardless of what style the #command is used, if it's correct, it will always have
 		//this value if there is no parameter. Send it as just the #command
-		if ( z == 2 ) {
-			sprintf(message2, "%s", cmd);
-			return is_atcommand_sub(fd,pl_sd,message2,gmlvl);
+		else if ( z == 2 ) {
+			sprintf(atcmd_msg, "%s", command);
+			break;
 		}
 		
 		sprintf(output, "Charcommand failed. Usage: #<command> <char name> <params>.");
 		clif_displaymessage(fd, output);
 		return true;
-		
 	}
 	
-	return is_atcommand_sub(fd,sd,message,gmlvl);
+	if (*message == atcommand_symbol) {
+		//atcmd_msg is constructed above differently for charcommands
+		//it's copied from message if not a charcommand so it can 
+		//pass through the rest of the code compatible with both symbols
+		sprintf(atcmd_msg, "%s", message);
+	}
+	
+	//Clearing these to be used once more. 
+	memset(command, '\0', sizeof(command));
+	memset(params, '\0', sizeof(params));
+	
+	//check to see if any params exist within this command
+	if( sscanf(atcmd_msg, "%99s %99[^\n]", command, params) < 2 )
+		params[0] = '\0';
+	
+	//Grab the command information and check for the proper GM level required to use it or if the command exists
+	info = get_atcommandinfo_byname(command);
+	if( info == NULL || info->func == NULL || ( *atcmd_msg == atcommand_symbol && pc_isGM(sd) < info->level ) || ( *atcmd_msg == charcommand_symbol && pc_isGM(sd) < info->level2 ) )
+	{
+			sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
+			clif_displaymessage(fd, output);
+			return true;
+	}
+	
+	//Attempt to use the command
+	if ( (info->func(fd, (*atcmd_msg == atcommand_symbol) ? sd : ssd, command, params) != 0) )
+	{
+		sprintf(output,msg_txt(154), command);
+		clif_displaymessage(fd, output);
+	}
+	
+	//Log atcommands
+	if( log_config.gm && info->level >= log_config.gm && *atcmd_msg == atcommand_symbol )
+		log_atcommand(sd, atcmd_msg);
+		
+	//Log Charcommands
+	if( log_config.gm && info->level2 >= log_config.gm && *atcmd_msg == charcommand_symbol && ssd != NULL )
+		log_atcommand(ssd, message);
+	
+	return true;
 }
 
 
@@ -9180,4 +9180,4 @@ int atcommand_commands(const int fd, struct map_session_data* sd, const char* co
 	clif_displaymessage(fd, atcmd_output);
 	
 	return 0;
-}
+}

+ 1 - 2
src/map/atcommand.h

@@ -17,8 +17,7 @@ extern char atcommand_symbol;
 extern char charcommand_symbol;
 typedef int (*AtCommandFunc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
 
-bool is_atcommand(const int fd, struct map_session_data* sd, const char* message);
-bool is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl);
+bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type);
 int get_atcommand_level(const AtCommandFunc func);
 
 void do_init_atcommand(void);

+ 5 - 5
src/map/clif.c

@@ -8217,7 +8217,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
 	if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
 		return;
 
-	if( is_atcommand(fd, sd, message)  )
+	if( is_atcommand(fd, sd, message, 1)  )
 		return;
 
 	if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
@@ -8528,7 +8528,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
 	if( !clif_process_message(sd, 1, &target, &namelen, &message, &messagelen) )
 		return;
 
-	if (is_atcommand(fd, sd, message)  )
+	if (is_atcommand(fd, sd, message, 1)  )
 		return;
 
 	if (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
@@ -10055,7 +10055,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
 	if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
 		return;
 
-	if( is_atcommand(fd, sd, message)  )
+	if( is_atcommand(fd, sd, message, 1)  )
 		return;
 
 	if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
@@ -10333,7 +10333,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
 	if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
 		return;
 
-	if( is_atcommand(fd, sd, message) )
+	if( is_atcommand(fd, sd, message, 1) )
 		return;
 
 	if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
@@ -10548,7 +10548,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd)
  *------------------------------------------*/
 void clif_parse_GMKickAll(int fd, struct map_session_data* sd)
 {
-	is_atcommand(fd, sd, "@kickall");
+	is_atcommand(fd, sd, "@kickall", 1);
 }
 
 /*==========================================

+ 1 - 1
src/map/map.c

@@ -2881,7 +2881,7 @@ int parse_console(char* buf)
 	ShowInfo("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
 
 	if( n == 5 && strcmpi("admin",type) == 0 ){
-		if( !is_atcommand_sub(sd.fd,&sd,command,99) )
+		if( !is_atcommand(sd.fd,&sd,command,0) )
 			ShowInfo("Console: not atcommand\n");
 	} else if( n == 2 && strcmpi("server",type) == 0 ){
 		if( strcmpi("shutdown",command) == 0 ||

+ 7 - 19
src/map/script.c

@@ -10733,7 +10733,8 @@ BUILDIN_FUNC(atcommand)
 			cmd++;
 	}
 
-	is_atcommand_sub(fd, sd, cmd, 99);
+	sd->gmlevel = 99;
+	is_atcommand(fd, sd, cmd, 0);
 
 	return 0;
 }
@@ -10742,11 +10743,8 @@ BUILDIN_FUNC(charcommand)
 {
 	TBL_PC dummy_sd;
 	TBL_PC* sd;
-	TBL_PC* temp_sd;
-	char output[200], temp[200], command[200], charname[NAME_LENGTH], param[200];
 	int fd;
 	const char* cmd;
-	const char* message;
 
 	cmd = script_getstr(st,2);
 
@@ -10767,24 +10765,14 @@ BUILDIN_FUNC(charcommand)
 		}
 	}
 
-	if (*cmd == charcommand_symbol)
-	{
-		if (sscanf(cmd, "%99s \"%23[^\"]\" %99[^\n]", command, charname, param) > 2
-		|| sscanf(cmd, "%99s %23s %99[^\n]", command, charname, param) > 2)
-		{
-			if ( (temp_sd = map_nick2sd(charname)) != NULL )
-			{
-				sprintf(output, "%s %s", cmd, param);
-				memcpy(temp, output, sizeof(output));
-				message = temp;
-				is_atcommand_sub(fd,sd,message,99);
-			}
-		}
-	}
-	else {
+	if (*cmd != charcommand_symbol) {
 		ShowWarning("script: buildin_charcommand: No '#' symbol!");
 		script_reportsrc(st);
+		return 1;
 	}
+	
+	sd->gmlevel = 99;
+	is_atcommand(0, sd, cmd, 0);
 
 	return 0;
 }