#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "build.h" #define CMD_FILE DATA_DIR "commands.dat" #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } #define SKEY( string, field ) \ if ( !str_cmp( word, string ) ) \ { \ free_string( field ); \ field = fread_string( fp ); \ fMatch = TRUE; \ break; \ } void load_commands( void ); void save_commands( void ); struct cmd_list_type { char *name; DO_FUN *function; }; extern bool fBootDb; int MAX_CMD; struct cmd_type *cmd_table; void clear_table_commands args( ( void ) ); #if defined(COMMAND) #undef COMMAND #endif #define COMMAND(cmd) { #cmd, cmd }, const struct cmd_list_type cmd_list [] = { #include "commands.h" { NULL, NULL } }; #undef COMMAND #define COMMAND(cmd) DECLARE_DO_FUN(cmd); const struct olc_cmd_type cmdedit_table[] = { { "name", cmdedit_name }, { "function", cmdedit_function }, { "level", cmdedit_level }, { "position", cmdedit_position }, { "log", cmdedit_log }, { "new", cmdedit_new }, { "delete", cmdedit_delete }, { "list", cmdedit_list }, { "show", cmdedit_show }, { "commands", show_commands }, { "?", show_help }, { "", 0 } }; char * cmd_func_name( DO_FUN *command ) { int cmd; for ( cmd = 0; cmd_list[cmd].name; cmd++ ) if ( cmd_list[cmd].function == command ) return cmd_list[cmd].name; return ""; } DO_FUN * cmd_func_lookup( char *arg ) { int cmd; for ( cmd = 0; cmd_list[cmd].name; cmd++ ) if ( !str_cmp(cmd_list[cmd].name, arg) ) return cmd_list[cmd].function; if ( fBootDb ) { bugf( "Cmd_func_lookup : funcion %s non-exhistant.", arg ); return do_nothing; } return NULL; } /* * Returns FALSE if not used in the cmd_table[cmd].function */ bool fun_lookup( DO_FUN *do_fun ) { int cmd; for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ ) if( cmd_table[cmd].do_fun == do_fun ) return TRUE; return FALSE; } int cmd_lookup( char *arg ) { int cmd; for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ ) if ( LOWER(arg[0]) == LOWER(cmd_table[cmd].name[0]) && !str_prefix( arg, cmd_table[cmd].name ) ) return cmd; return -1; } void cmdedit( CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; char command[MAX_INPUT_LENGTH]; struct cmd_type *pCmd; int cmd; EDIT_CMD( ch, pCmd ); smash_tilde(argument); strcpy(arg, argument); argument = one_argument( argument, command); if( get_trust(ch) < LEVEL_JUDGE ) { send_to_char("Insufficiant trust to edit commands.\n\r", ch); edit_done(ch); return; } if (command[0] == '\0') { cmdedit_show(ch, argument); return; } if (!str_cmp(command, "done") ) { edit_done(ch); return; } if (!str_cmp(command, "save") ) { send_to_char("Saving commands...", ch); save_commands(); send_to_char("Done.\n\r", ch); return; } /* Search Table and Dispatch Command. */ for ( cmd = 0; *cmdedit_table[cmd].name; cmd++ ) { if ( !str_prefix( command, cmdedit_table[cmd].name ) ) { if ( (*cmdedit_table[cmd].olc_fun) ( ch, argument ) ) { logf( NULL, "%s editing %s function.", ch->name, pCmd->name ); save_commands(); } return; } } if( ( cmd = flag_value( show_flags, arg ) ) != NO_FLAG ) { TOGGLE_BIT( pCmd->show, cmd ); send_to_char( "Done.\n\r", ch ); save_commands(); return; } interpret(ch, arg); return; } void do_cmdedit(CHAR_DATA *ch, char *argument) { struct cmd_type *pCmd; char command[MSL]; int comando; if ( IS_NPC(ch) ) return; if ( !argument || argument[0] == '\0' ) { send_to_char( "Syntax : CMDEdit [command]\n\r", ch ); return; } argument = one_argument( argument, command ); if ( !str_cmp( command, "new" ) ) { if ( cmdedit_new(ch, argument) ) save_commands(); return; } if ( !str_cmp( command, "delete" ) ) { if ( cmdedit_delete(ch, argument) ) save_commands(); return; } if( !str_cmp( command, "save_commands" ) ) { save_commands(); stc( "Done.\n\r", ch ); return; } if ( (comando = cmd_lookup(command)) == -1 ) { send_to_char( "CMDEdit : Command non-exhistant.\n\r", ch ); return; } pCmd = &cmd_table[comando]; set_editor( ch->desc, ED_CMD, pCmd ); return; } CMDEDIT( cmdedit_show ) { struct cmd_type *pCmd; char buf[MIL]; EDIT_CMD( ch, pCmd ); sprintf( buf, "{cName {B: {n%s\n\r", pCmd->name ); send_to_char( buf, ch ); sprintf( buf, "{cFunction {B: {n%s\n\r", cmd_func_name(pCmd->do_fun) ); send_to_char( buf, ch ); sprintf( buf, "{cLevel {B: {C[{n%d{C]\n\r", pCmd->level ); send_to_char( buf, ch ); sprintf( buf, "{cPosition {B: {C[{n%d{C]\n\r", pCmd->position ); send_to_char( buf, ch ); sprintf( buf, "{cLog {B: {n%s\n\r", flag_string( log_flags, pCmd->log ) ); send_to_char( buf, ch ); sprintf( buf, "{cShowTo {B: {n%s\n\r", flag_string( show_flags, pCmd->show ) ); send_to_char( buf, ch ); if( pCmd->disabled_by[0] != '\0' ) { sprintf( buf, "{cDisabled {B: {C%d {n%s\n\r", pCmd->disable_level, pCmd->disabled_by ); send_to_char( buf, ch ); send_to_char( "{cReason \n\r{n",ch ); if( pCmd->reason ) sprintf( buf, "%s\n\r", pCmd->reason ); else sprintf( buf, "(None given)\n\r" ); send_to_char( buf, ch ); } return FALSE; } void list_functions( CHAR_DATA *ch ) { int i; char buf[MSL]; sprintf( buf, "Num %-13.13s Num %-13.13s Num %-13.13s Num %-13.13s\n\r", "Func", "Func", "Func", "Func" ); send_to_char(buf,ch); for ( i = 0; cmd_list[i].name; i++ ) { sprintf( buf, "%3d %-13.13s", i, cmd_list[i].name ); if ( i % 4 == 3 ) strcat( buf, "\n\r" ); else strcat( buf, " " ); send_to_char( buf, ch ); } if ( i % 4 != 0 ) send_to_char( "\n\r", ch); } void used_functions( CHAR_DATA *ch ) { int i; char buf [ MAX_STRING_LENGTH ]; bool found; sprintf( buf, "Num %-13.13s Num %-13.13s Num %-13.13s Num %-13.13s\n\r", "Func", "Func", "Func", "Func" ); send_to_char(buf,ch); found = FALSE; for ( i = 0; cmd_list[i].name; i++ ) { if( !fun_lookup( cmd_list[i].function ) ) { found = TRUE; sprintf( buf, "%3d %-13.13s", i, cmd_list[i].name ); if ( i % 4 == 3 ) strcat( buf, "\n\r" ); else strcat( buf, " " ); send_to_char( buf, ch ); } } if( !found ) send_to_char( "There are no used functions in commands.h\n\r", ch ); else if ( i % 4 != 0 ) send_to_char( "\n\r", ch); return; } void list_commands(CHAR_DATA *ch, int minlev, int maxlev) { char buf[MSL]; int i, cnt = 0; sprintf( buf, "Lvl %-12.12s %-13.13s Pos Log Lvl %-12.12s %-13.13s Pos Log\n\r", "Name", "Function", "Name", "Function" ); send_to_char( buf, ch ); for ( i = 0; i < MAX_CMD; ++i ) { if ( cmd_table[i].level < minlev || cmd_table[i].level > maxlev ) continue; sprintf( buf, "%2d %-12.12s %-13.13s %-3.3s %-3.3s", cmd_table[i].level, cmd_table[i].name, cmd_func_name(cmd_table[i].do_fun), flag_string( position_flags, cmd_table[i].position ), flag_string( log_flags,cmd_table[i].log)); if ( cnt % 2 == 1 ) strcat(buf,"\n\r"); else strcat(buf," "); send_to_char( buf, ch ); cnt++; } if ( cnt % 2 != 0 ) stc("\n\r",ch); return; } CMDEDIT( cmdedit_list ) { char arg[MIL], arg2[MIL]; int minlev, maxlev; argument = one_argument( argument, arg ); if ( arg[0] == '\0' || !is_name(arg, "commands functions unused") ) { send_to_char( "Syntax : list commands [level min] [level max]\n\r", ch ); send_to_char( " list functions\n\r", ch ); send_to_char( " list unused\n\r", ch ); return FALSE; } minlev = 0; maxlev = MAX_LEVEL; if ( argument[0] != '\0' ) { argument = one_argument( argument, arg2 ); if ( !is_number( arg2 ) ) { send_to_char( "CMDEdit : Argument must be a number.\n\r", ch ); return FALSE; } minlev = atoi( arg2 ); if ( argument[0] == '\0' ) maxlev = atoi( argument ); else maxlev = 0; if ( maxlev < 1 || maxlev > MAX_LEVEL ) maxlev = minlev; } if ( !str_prefix(arg,"commands") ) list_commands(ch,minlev,maxlev); else if ( !str_prefix(arg,"functions") ) list_functions(ch); else if ( !str_prefix(arg,"unused" ) ) used_functions(ch); else send_to_char("Invalid.\n\r",ch); return FALSE; } void do_nothing( CHAR_DATA *ch, char *argument ) { return; } CMDEDIT( cmdedit_name ) { struct cmd_type *pCmd; int cmd; EDIT_CMD(ch,pCmd); if ( !argument || argument[0] == '\0' ) { send_to_char( "Sintaxis : name [name]\n\r", ch ); return FALSE; } if ( cmd_lookup(argument) != -1 ) { send_to_char( "CMDEdit : Command already exhists.\n\r", ch ); return FALSE; } free_string(pCmd->name); pCmd->name = str_dup( argument ); clear_table_commands(); cmd = cmd_lookup(argument); if ( cmd != -1 ) ch->desc->pEdit = &cmd_table[cmd]; else bugf( "Cmdedit_name : cmd_lookup returns -1 at %s!", argument ); send_to_char( "Ok.\n\r", ch ); return TRUE; } CMDEDIT( cmdedit_new ) { DESCRIPTOR_DATA *d; CHAR_DATA *tch; struct cmd_type *new_table; int cmd; if ( !argument || argument[0] == '\0' ) { send_to_char( "Syntax : new [number of command]\n\r", ch ); return FALSE; } cmd = cmd_lookup( argument ); if (cmd != -1) { send_to_char ("CMDEdit : Command non-exhistant.\n\r",ch); return FALSE; } for ( d = descriptor_list; d; d = d->next ) { if ( d->connected != CON_PLAYING || (tch = CH(d)) == NULL || tch->desc == NULL ) continue; if ( tch->desc->editor == ED_CMD ) edit_done(tch); } MAX_CMD++; new_table = realloc (cmd_table, sizeof(struct cmd_type) * (MAX_CMD + 1)); if (!new_table) /* realloc failed */ { send_to_char ("Failure to reallocate table. Prepare for the worse.\n\r",ch); return FALSE; } cmd_table = new_table; cmd_table[MAX_CMD-1].name = str_dup (argument); cmd_table[MAX_CMD-1].do_fun = do_nothing; cmd_table[MAX_CMD-1].position = POS_STANDING; cmd_table[MAX_CMD-1].level = ch->level; cmd_table[MAX_CMD-1].log = LOG_ALWAYS; cmd_table[MAX_CMD-1].show = CSHOW_NEVER; cmd_table[MAX_CMD-1].disabled_by = str_dup( "" ); cmd_table[MAX_CMD-1].reason = str_dup( "" ); cmd_table[MAX_CMD-1].disable_level = 12; cmd_table[MAX_CMD].name = str_dup( "" ); clear_table_commands(); cmd = cmd_lookup(argument); if ( cmd != -1 ) ch->desc->pEdit = &cmd_table[cmd]; else bugf( "Cmdedit_new : cmd_lookup returned -1 with %s!", argument ); ch->desc->editor = ED_CMD; send_to_char ("Command created.\n\r",ch); return TRUE; } CMDEDIT( cmdedit_delete ) { DESCRIPTOR_DATA *d; CHAR_DATA *tch; int i,j,iCmd; struct cmd_type *new_table; if ( !argument || argument[0] == '\0' ) { send_to_char( "Syntax : delete [number or command]\n\r", ch ); return FALSE; } iCmd = cmd_lookup(argument); if (iCmd == -1) { send_to_char( "CMDEdit : Command non-exhistant.\n\r", ch ); return FALSE; } for ( d = descriptor_list; d; d = d->next ) { if ( d->connected != CON_PLAYING || (tch = CH(d)) == NULL || tch->desc == NULL ) continue; if ( tch->desc->editor == ED_CMD ) edit_done(tch); } new_table = malloc (sizeof(struct cmd_type) * MAX_CMD); if (!new_table) { send_to_char ("Memory allocation failed. Brace for impact...\n\r",ch); return FALSE; } for (i = 0, j = 0; i < MAX_CMD+1; i++) if (i != iCmd) /* copy, increase only if copied */ { new_table[j] = cmd_table[i]; j++; } free (cmd_table); cmd_table = new_table; MAX_CMD--; /* Important :() */ clear_table_commands(); send_to_char ("Command deleted\n\r",ch); return TRUE; } CMDEDIT( cmdedit_function ) { struct cmd_type *pCmd; DO_FUN *funcion; EDIT_CMD(ch,pCmd); if ( !argument || argument[0] == '\0' ) { send_to_char( "Syntax : function [name-function]\n\r", ch ); return FALSE; } if ( (funcion = cmd_func_lookup(argument)) == NULL ) { send_to_char( "CMDEdit : Function inexistente.\n\r", ch ); return FALSE; } pCmd->do_fun = funcion; send_to_char( "Ok.\n\r", ch ); return TRUE; } CMDEDIT( cmdedit_level ) { struct cmd_type *pCmd; int niv; EDIT_CMD(ch,pCmd); if ( !argument || argument[0] == '\0') { ch_printf( ch, "Syntax : level [level]\n\r" ); return FALSE; } if( is_number( argument ) ) niv = atoi( argument ); else if ( (niv = flag_value(level_flags, argument)) == NO_FLAG ) { send_to_char( "CMDEdit : Level out of range.\n\r", ch ); return FALSE; } if ( pCmd->level > ch->level ) { send_to_char( "CMDEdit : Cannot create command higher then you.\n\r", ch ); return FALSE; } pCmd->level = niv; send_to_char( "Ok.\n\r", ch ); return TRUE; } CMDEDIT( cmdedit_log ) { struct cmd_type *pCmd; int value; EDIT_CMD(ch,pCmd); if ( !argument || argument[0] == '\0' ) { ch_printf( ch, "Syntax : log [type/number]\n\r" ); return FALSE; } if( is_number( argument ) ) value = atoi( argument ); else value = flag_value( log_flags, argument ); if( value < 0 || value > 2 ) { ch_printf( ch, "CMDEdit: Log %d is to large.\n\r", value ); return FALSE; } pCmd->log = value; stc("Log toggled.\n\r", ch); return TRUE; } CMDEDIT( cmdedit_position ) { struct cmd_type *pCmd; int value; EDIT_CMD(ch,pCmd); if ( !argument || argument[0] == '\0' ) { ch_printf( ch, "Syntax : log [type/number]\n\r" ); return FALSE; } if( is_number( argument ) ) value = atoi( argument ); else value = flag_value( position_flags, argument ); if( value < 0 || value > 9 ) { ch_printf( ch, "CMDEdit: Position %d is invalid.\n\r", value ); return FALSE; } pCmd->position = value; stc("Position set.\n\r", ch); return TRUE; } void fread_cmd( FILE *fp, struct cmd_type * pCmd ) { char buf[MAX_STRING_LENGTH]; char *word; bool fMatch; pCmd->disabled_by = str_dup( "" ); pCmd->reason = str_dup( "" ); pCmd->disable_level = MAX_LEVEL; for ( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': case '#': fMatch = TRUE; fread_to_eol( fp ); break; case 'D': if( !str_cmp( word, "D" ) ) { fMatch = TRUE; pCmd->disable_level = fread_number( fp ); free_string( pCmd->disabled_by ); pCmd->disabled_by = fread_string( fp ); break; } break; case 'C': if( !str_cmp( word, "C" ) ) { char * p; fMatch = TRUE; p = fread_string ( fp ); pCmd->do_fun = cmd_func_lookup( p ); free_string( p ); break; } break; case 'E': if ( !str_cmp( word, "End" ) ) { if( pCmd->do_fun == do_nothing ) SET_BIT( pCmd->show, CSHOW_NEVER ); return; } break; case 'L': KEY( "Lv", pCmd->level, fread_number(fp) ); KEY( "Lg", pCmd->log, fread_number(fp) ); break; case 'N': if( !str_cmp( word, "N" ) ) { free_string( pCmd->name ); pCmd->name = fread_string( fp ); fMatch = TRUE; break; } break; case 'P': KEY( "P", pCmd->position, fread_number(fp) ); break; case 'R': SKEY( "R", pCmd->reason ); case 'S': KEY( "S", pCmd->show, fread_number(fp) ); break; } if ( !fMatch ) { sprintf( buf, "Fread_command: no match: %s", word ); bug( buf, 0 ); } } } void load_commands( void ) { FILE * fp; extern struct cmd_type * cmd_table; extern int MAX_CMD; int i = 0, large; fp = fopen( CMD_FILE, "r" ); if ( !fp ) { perror( "load_table_commands "); exit(1); } large = fread_number(fp); MAX_CMD = large; logf( NULL, "Creating cmd_table: large %d, size: %d", large + 1, sizeof(struct cmd_type) * (large + 1) ); cmd_table = calloc( sizeof(struct cmd_type), large + 1); for( i = 0; i < MAX_CMD; i++ ) fread_cmd( fp, &cmd_table[i] ); logf( NULL, "Table of commands loaded." ); fclose(fp); cmd_table[MAX_CMD].name = str_dup( "" ); /* Backwards compat */ return; } void save_commands( void ) { FILE * fp; struct cmd_type * temp; extern struct cmd_type * cmd_table; int cnt = 0; fp = fopen( CMD_FILE, "w" ); if ( !fp ) { perror( "save_table_commands" ); return; } for ( MAX_CMD = 0; cmd_table[MAX_CMD].name[0]; MAX_CMD++ ) ; fprintf( fp, "%d\n\n", MAX_CMD ); for( cnt = 0; cnt < MAX_CMD; cnt++ ) { temp = &cmd_table[cnt]; fprintf( fp, "#COMAND\n" ); fprintf( fp, "N %s~\n", temp->name ); fprintf( fp, "C %s~\n", cmd_func_name(temp->do_fun) ); fprintf( fp, "Lv %d\n", temp->level ); fprintf( fp, "P %d\n", temp->position ); fprintf( fp, "Lg %d\n", temp->log ); fprintf( fp, "S %d\n", temp->show ); if( temp->disabled_by[0] != '\0' ) { fprintf( fp, "D %d %s~\n", temp->disable_level, temp->disabled_by ); fprintf( fp, "R %s~\n", strip_cr(temp->reason) ); } fprintf( fp, "End\n\n" ); } fclose(fp); }