示例#1
0
文件: add_action.c 项目: Elohim/FGmud
void setup_new_commands (object_t * dest, object_t * item)
{
    object_t *next_ob, *ob;

    /*
     * Setup the new commands. The order is very important, as commands in
     * the room should override commands defined by the room. Beware that
     * init() in the room may have moved 'item' !
     *
     * The call of init() should really be done by the object itself (except in
     * the -o mode). It might be too slow, though :-(
     */
    if (item->flags & O_ENABLE_COMMANDS) {
	save_command_giver(item);
	(void) apply(APPLY_INIT, dest, 0, ORIGIN_DRIVER);
	restore_command_giver();
	if (item->super != dest)
	    return;
    }
    /*
     * Run init of the item once for every present user, and for the
     * environment (which can be a user).
     */
    for (ob = dest->contains; ob; ob = next_ob) {
	next_ob = ob->next_inv;
	if (ob == item)
	    continue;
	if (ob->flags & O_DESTRUCTED)
	    error("An object was destructed at call of " APPLY_INIT "()\n");
	if (ob->flags & O_ENABLE_COMMANDS) {
	    save_command_giver(ob);
	    (void) apply(APPLY_INIT, item, 0, ORIGIN_DRIVER);
	    restore_command_giver();
	    if (dest != item->super)
		return;
	}
	if (item->flags & O_DESTRUCTED)	/* marion */
	    error("The object to be moved was destructed at call of " APPLY_INIT "()\n");
	if (ob->flags & O_DESTRUCTED) /* Alaron */
	    error("An object was destructed at call of " APPLY_INIT "()\n");
	if (item->flags & O_ENABLE_COMMANDS) {
	    save_command_giver(item);
	    (void) apply(APPLY_INIT, ob, 0, ORIGIN_DRIVER);
	    restore_command_giver();
	    if (dest != item->super)
		return;
	}
    }
    if (dest->flags & O_DESTRUCTED)	/* marion */
	error("The destination to move to was destructed at call of " APPLY_INIT "()\n");
    if (item->flags & O_DESTRUCTED)	/* Alaron */
	error("The object to be moved was destructed at call of " APPLY_INIT "()\n");
    if (dest->flags & O_ENABLE_COMMANDS) {
	save_command_giver(dest);
	(void) apply(APPLY_INIT, item, 0, ORIGIN_DRIVER);
	restore_command_giver();
    }
}
示例#2
0
文件: add_action.c 项目: Elohim/FGmud
static void notify_no_command (void)
{
    union string_or_func p;
    svalue_t *v;

    if (!command_giver || !command_giver->interactive)
	return;
    p = command_giver->interactive->default_err_message;
    if (command_giver->interactive->iflags & NOTIFY_FAIL_FUNC) {
	save_command_giver(command_giver);
	v = call_function_pointer(p.f, 0);
	restore_command_giver();
	free_funp(p.f);
	if (command_giver && command_giver->interactive) {
	    if (v && v->type == T_STRING) {
		tell_object(command_giver, v->u.string, SVALUE_STRLEN(v));
	    }
	    command_giver->interactive->iflags &= ~NOTIFY_FAIL_FUNC;
	    command_giver->interactive->default_err_message.s = 0;
	}
    } else {
	if (p.s) {
	    tell_object(command_giver, p.s, strlen(p.s));
	    free_string(p.s);
	    command_giver->interactive->default_err_message.s = 0;
	} else {
	    tell_object(command_giver, default_fail_message, strlen(default_fail_message));
	}
    }
}
示例#3
0
文件: add_action.c 项目: Elohim/FGmud
/*
 * Take a user command and parse it.
 * The command can also come from a NPC.
 * Beware that 'str' can be modified and extended !
 */
int parse_command (char * str, object_t * ob)
{
    int res;

    /* disallow users to issue commands containing ansi escape codes */
#if defined(NO_ANSI) && !defined(STRIP_BEFORE_PROCESS_INPUT)
    char *c;

    for (c = str;  *c;  c++) {
	if (*c == 27) {
	    *c = ' ';		/* replace ESC with ' ' */
	}
    }
#endif

    save_command_giver(ob);
    res = user_parser(str);
    restore_command_giver();

    return res;
}
示例#4
0
文件: add_action.c 项目: Elohim/FGmud
static int user_parser (char * buff)
{
    char verb_buff[MAX_VERB_BUFF];
    sentence_t *s;
    char *p;
    int length;
    char *user_verb = 0;
    int where;
    int save_illegal_sentence_action;

    debug(d_flag, ("cmd [/%s]: %s\n", command_giver->obname, buff));

    /* strip trailing spaces. */
    for (p = buff + strlen(buff) - 1; p >= buff; p--) {
	if (*p != ' ')
	    break;
	*p = '\0';
    }
    if (buff[0] == '\0')
	return 0;
    length = p - buff + 1;
    p = strchr(buff, ' ');
    if (p == 0) {
	user_verb = findstring(buff);
    } else {
	*p = '\0';
	user_verb = findstring(buff);
	*p = ' ';
	length = p - buff;
    }
    if (!user_verb) {
	/* either an xverb or a verb without a specific add_action */
	user_verb = buff;
    }
    /*
     * copy user_verb into a static character buffer to be pointed to by
     * last_verb.
     */
    strncpy(verb_buff, user_verb, MAX_VERB_BUFF - 1);
    if (p) {
	int pos;

	pos = p - buff;
	if (pos < MAX_VERB_BUFF) {
	    verb_buff[pos] = '\0';
	}
    }

    save_illegal_sentence_action = illegal_sentence_action;
    illegal_sentence_action = 0;
    for (s = command_giver->sent; s; s = s->next) {
	svalue_t *ret;
	object_t *command_object;

	if (s->flags & (V_NOSPACE | V_SHORT)) {
	    if (strncmp(buff, s->verb, strlen(s->verb)) != 0)
		continue;
	} else {
	    /* note: if was add_action(blah, "") then accept it */
	    if (s->verb[0] && (user_verb != s->verb))
		continue;
	}
	/*
	 * Now we have found a special sentence !
	 */

	if (!(s->flags & V_FUNCTION))
	    debug(d_flag, ("Local command %s on /%s",
			   s->function.s, s->ob->obname));

	if (s->flags & V_NOSPACE) {
	    int l1 = strlen(s->verb);
	    int l2 = strlen(verb_buff);

	    if (l1 < l2)
		last_verb = verb_buff + l1;
	    else
		last_verb = "";
	} else {
	    if (!s->verb[0] || (s->flags & V_SHORT))
		last_verb = verb_buff;
	    else
		last_verb = s->verb;
	}
	/*
	 * If the function is static and not defined by current object, then
	 * it will fail. If this is called directly from user input, then
	 * the origin is the driver and it will be allowed.
	 */
	where = (current_object ? ORIGIN_EFUN : ORIGIN_DRIVER);

	/*
	 * Remember the object, to update moves.
	 */
	command_object = s->ob;
	save_command_giver(command_giver);
	if (s->flags & V_NOSPACE) {
	    copy_and_push_string(&buff[strlen(s->verb)]);
	} else if (buff[length] == ' ') {
	    copy_and_push_string(&buff[length + 1]);
	} else {
	    push_undefined();
	}
	if (s->flags & V_FUNCTION) {
	    ret = call_function_pointer(s->function.f, 1);
	} else {
	    if (s->function.s[0] == APPLY___INIT_SPECIAL_CHAR)
		error("Illegal function name.\n");
	    ret = apply(s->function.s, s->ob, 1, where);
	}
	/* s may be dangling at this point */

	restore_command_giver();

	last_verb = 0;

	/* was this the right verb? */
	if (ret == 0) {
	    /* is it still around?  Otherwise, ignore this ...
	       it moved somewhere or dested itself */
	    if (s == command_giver->sent) {
		char buf[256];
		if (s->flags & V_FUNCTION) {
		    sprintf(buf, "Verb '%s' bound to uncallable function pointer.\n", s->verb);
		    error(buf);
		} else {
		    sprintf(buf, "Function for verb '%s' not found.\n",
			    s->verb);
		    error(buf);
		}
	    }
	}

	if (ret && (ret->type != T_NUMBER || ret->u.number != 0)) {
#ifdef PACKAGE_MUDLIB_STATS
	    if (command_giver && command_giver->interactive
#ifndef NO_WIZARDS
		&& !(command_giver->flags & O_IS_WIZARD)
#endif
		)
		add_moves(&command_object->stats, 1);
#endif
	    if (!illegal_sentence_action)
		illegal_sentence_action = save_illegal_sentence_action;
	    return 1;
	}
	if (illegal_sentence_action) {
	    switch (illegal_sentence_action) {
	    case 1:
		error("Illegal to call remove_action() [caller was /%s] from a verb returning zero.\n", illegal_sentence_ob->obname);
	    case 2:
		error("Illegal to move or destruct an object (/%s) defining actions from a verb function which returns zero.\n", illegal_sentence_ob->obname);
	    }
	}
    }
    notify_no_command();
    illegal_sentence_action = save_illegal_sentence_action;

    return 0;
}
示例#5
0
void call_heart_beat()
{
    object_t *ob;
    heart_beat_t *curr_hb;
    error_context_t econ;

    current_interactive = 0;

    if ((num_hb_to_do = num_hb_objs)) {
        num_hb_calls++;
        heart_beat_index = 0;
        save_context(&econ);
        while (1) {
            ob = (curr_hb = &heart_beats[heart_beat_index])->ob;
            DEBUG_CHECK(!(ob->flags & O_HEART_BEAT),
                    "Heartbeat not set in object on heartbeat list!");
            /* is it time to do a heart beat ? */
            curr_hb->heart_beat_ticks--;

            if (ob->prog->heart_beat != 0) {
                if (curr_hb->heart_beat_ticks < 1) {
                    object_t *new_command_giver;
                    curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat;
                    current_heart_beat = ob;
                    new_command_giver = ob;
#ifndef NO_SHADOWS
                    while (new_command_giver->shadowing)
                        new_command_giver = new_command_giver->shadowing;
#endif
#ifndef NO_ADD_ACTION
                    if (!(new_command_giver->flags & O_ENABLE_COMMANDS))
                        new_command_giver = 0;
#endif
#ifdef PACKAGE_MUDLIB_STATS
                    add_heart_beats(&ob->stats, 1);
#endif
                    set_eval(max_cost);

                    if (SETJMP(econ.context)) {
                        restore_context(&econ);
                    } else {
                        save_command_giver(new_command_giver);
                        call_direct(ob, ob->prog->heart_beat - 1,
                                ORIGIN_DRIVER, 0);
                        pop_stack(); /* pop the return value */
                        restore_command_giver();
                    }

                    current_object = 0;
                }
            }
            if (++heart_beat_index == num_hb_to_do)
                break;
        }
        pop_context(&econ);
        if (heart_beat_index < num_hb_to_do)
            perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do;
        else
            perc_hb_probes = 100.0;
        heart_beat_index = num_hb_to_do = 0;
    }
    current_prog = 0;
    current_heart_beat = 0;
    look_for_objects_to_swap();
#ifdef PACKAGE_MUDLIB_STATS
    mudlib_stats_decay();
#endif
}       /* call_heart_beat() */
示例#6
0
static void call_heart_beat()
{
    object_t *ob;
    heart_beat_t *curr_hb;
    error_context_t econ;

#ifdef WIN32
    static long Win32Thread = -1;
#endif

    heart_beat_flag = 0;
#ifdef SIGALRM
    signal(SIGALRM, sigalrm_handler);
#endif

#ifdef HAS_UALARM
    ualarm(HEARTBEAT_INTERVAL, 0);
#else
#  ifdef WIN32
    if (Win32Thread == -1) Win32Thread = _beginthread(
/* This shouldn't be necessary b/c alarm_loop is already declared as this.
   Microsoft lossage? -Beek */
	(void (__cdecl *)(void *))
	alarm_loop, 256, 0);
#  else
    alarm(SYSV_HEARTBEAT_INTERVAL);	/* defined in config.h */
#  endif
#endif

    current_interactive = 0;

    if ((num_hb_to_do = num_hb_objs)) {
	num_hb_calls++;
	heart_beat_index = 0;
	save_context(&econ);
	while (!heart_beat_flag) {
	    ob = (curr_hb = &heart_beats[heart_beat_index])->ob;
	    DEBUG_CHECK(!(ob->flags & O_HEART_BEAT),
			"Heartbeat not set in object on heartbeat list!");
	    DEBUG_CHECK(ob->flags & O_SWAPPED,
			"Heartbeat in swapped object.\n");
	    /* is it time to do a heart beat ? */
	    curr_hb->heart_beat_ticks--;

	    if (ob->prog->heart_beat != 0) {
		if (curr_hb->heart_beat_ticks < 1) {
		    object_t *new_command_giver;
		    curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat;
		    current_heart_beat = ob;
		    new_command_giver = ob;
#ifndef NO_SHADOWS
		    while (new_command_giver->shadowing)
			new_command_giver = new_command_giver->shadowing;
#endif
#ifndef NO_ADD_ACTION
		    if (!(new_command_giver->flags & O_ENABLE_COMMANDS))
			new_command_giver = 0;
#endif
#ifdef PACKAGE_MUDLIB_STATS
		    add_heart_beats(&ob->stats, 1);
#endif
		    eval_cost = max_cost;

		    if (SETJMP(econ.context)) {
			restore_context(&econ);
		    } else {
			save_command_giver(new_command_giver);
			call_direct(ob, ob->prog->heart_beat - 1,
				    ORIGIN_DRIVER, 0);
			pop_stack(); /* pop the return value */
			restore_command_giver();
		    }

		    current_object = 0;
		}
	    }
	    if (++heart_beat_index == num_hb_to_do)
		break;
	}
	pop_context(&econ);
	if (heart_beat_index < num_hb_to_do)
	    perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do;
	else
	    perc_hb_probes = 100.0;
	heart_beat_index = num_hb_to_do = 0;
    }
    current_prog = 0;
    current_heart_beat = 0;
    look_for_objects_to_swap();
    call_out();
#ifdef PACKAGE_MUDLIB_STATS
    mudlib_stats_decay();
#endif
}				/* call_heart_beat() */