Esempio n. 1
0
void do_mob(CHAR_DATA * ch, char *argument)
{
    /*
     * Security check!
     */
    if (ch->desc != NULL && get_trust(ch) < MAX_LEVEL)
	return;
    mob_interpret(ch, argument);
}
Esempio n. 2
0
void program_flow( 
        sh_int pvnum,  /* For diagnostic purposes */
	char *source,  /* the actual MOBprog code */
	CHAR_DATA *mob, CHAR_DATA *ch, const void *arg1, const void *arg2 )
{
    CHAR_DATA *rch = NULL;
    char *code, *line;
    char buf[MAX_STRING_LENGTH];
    char control[MAX_INPUT_LENGTH], data[MAX_STRING_LENGTH];

    static int call_level; /* Keep track of nested "mpcall"s */

    int level, eval, check;
    int state[MAX_NESTED_LEVEL], /* Block state (BEGIN,IN,END) */
	cond[MAX_NESTED_LEVEL];  /* Boolean value based on the last if-check */

    sh_int mvnum = mob->pIndexData->vnum;

    if( ++call_level > MAX_CALL_LEVEL )
    {
	bug( "MOBprogs: MAX_CALL_LEVEL exceeded, vnum %d", mob->pIndexData->vnum );
	return;
    }

    /*
     * Reset "stack"
     */
    for ( level = 0; level < MAX_NESTED_LEVEL; level++ )
    {
    	state[level] = IN_BLOCK;
        cond[level]  = TRUE;
    }
    level = 0;

    code = source;
    /*
     * Parse the MOBprog code
     */
    while ( *code )
    {
	bool first_arg = TRUE;
	char *b = buf, *c = control, *d = data;
	/*
	 * Get a command line. We sneakily get both the control word
	 * (if/and/or) and the rest of the line in one pass.
	 */
	while( isspace( *code ) && *code ) code++;
	while ( *code )
	{
	    if ( *code == '\n' || *code == '\r' )
		break;
	    else if ( isspace(*code) )
	    {
		if ( first_arg )
		    first_arg = FALSE;
		else
		    *d++ = *code;
	    }
	    else
	    {
		if ( first_arg )
		   *c++ = *code;
		else
		   *d++ = *code;
	    }
	    *b++ = *code++;
	}
	*b = *c = *d = '\0';

	if ( buf[0] == '\0' )
	    break;
	if ( buf[0] == '*' ) /* Comment */
	    continue;

        line = data;
	/* 
	 * Match control words
	 */
	if ( !str_cmp( control, "if" ) )
	{
	    if ( state[level] == BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: misplaced if statement, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    state[level] = BEGIN_BLOCK;
            if ( ++level >= MAX_NESTED_LEVEL )
            {
		sprintf( buf, "Mobprog: Max nested level exceeded, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) 
	    {
		cond[level] = FALSE;
		continue;
	    }
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		cond[level] = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
	    {
		sprintf( buf, "Mobprog: invalid if_check (if), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    state[level] = END_BLOCK;
    	}
	else if ( !str_cmp( control, "or" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: or without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		eval = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
            {
		sprintf( buf, "Mobprog: invalid if_check (or), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
            }
            cond[level] = (eval == TRUE) ? TRUE : cond[level];
    	}
	else if ( !str_cmp( control, "and" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: and without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		eval = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
	    {
		sprintf( buf, "Mobprog: invalid if_check (and), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    cond[level] = (cond[level] == TRUE) && (eval == TRUE) ? TRUE : FALSE;
    	}
	else if ( !str_cmp( control, "endif" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: endif without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    cond[level] = TRUE;
	    state[level] = IN_BLOCK;
            state[--level] = END_BLOCK;
        }
	else if ( !str_cmp( control, "else" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: else without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
            state[level] = IN_BLOCK;
            cond[level] = (cond[level] == TRUE) ? FALSE : TRUE;
        }
    	else if ( cond[level] == TRUE
	&& ( !str_cmp( control, "break" ) || !str_cmp( control, "end" ) ) )
	{
	    call_level--;
            return;
	}
	else if ( (!level || cond[level] == TRUE) && buf[0] != '\0' )
	{
	    state[level] = IN_BLOCK;
            expand_arg( data, buf, mob, ch, arg1, arg2, rch );
	    if ( !str_cmp( control, "mob" ) )
	    {
		/* 
		 * Found a mob restricted command, pass it to mob interpreter
		 */
		line = one_argument( data, control );
		mob_interpret( mob, line );
	    }
	    else
	    {
		/* 
		 * Found a normal mud command, pass it to interpreter
		 */
		interpret( mob, data );
	    }
	}
    }
    call_level--;
}