diff options
-rw-r--r-- | Changelog-Trunk.txt | 7 | ||||
-rw-r--r-- | src/map/atcommand.c | 172 | ||||
-rw-r--r-- | src/map/atcommand.h | 3 | ||||
-rw-r--r-- | src/map/clif.c | 10 | ||||
-rw-r--r-- | src/map/map.c | 2 | ||||
-rw-r--r-- | src/map/script.c | 26 |
6 files changed, 107 insertions, 113 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 007638d80..b534299a3 100644 --- a/Changelog-Trunk.txt +++ b/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] diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 4c8766a4c..e40645a83 100644 --- a/src/map/atcommand.c +++ b/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; -}
\ No newline at end of file +} diff --git a/src/map/atcommand.h b/src/map/atcommand.h index f74adb9f5..30ef3f297 100644 --- a/src/map/atcommand.h +++ b/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); diff --git a/src/map/clif.c b/src/map/clif.c index 2759f29ea..94f0dceef 100644 --- a/src/map/clif.c +++ b/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); } /*========================================== diff --git a/src/map/map.c b/src/map/map.c index 7dfd56488..5dbdaae04 100644 --- a/src/map/map.c +++ b/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 || diff --git a/src/map/script.c b/src/map/script.c index fc65a3d7e..c2ec1ddc8 100644 --- a/src/map/script.c +++ b/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; } |