コード例 #1
0
ファイル: look.c プロジェクト: ccubed/MuDocker
/* Show the 'Obvious Exits' list for a room. Used in 'look' and 'examine'.
 * \param player The player looking
 * \param loc room whose exits we're showing
 * \param exit_name "Obvious Exits" string
 * \param pe_info the pe_info to use for evaluating EXITFORMAT and interact locks
 */
static void
look_exits(dbref player, dbref loc, const char *exit_name, NEW_PE_INFO *pe_info)
{
  dbref thing;
  char *tbuf1, *tbuf2, *nbuf;
  char *s1, *s2;
  char *p;
  int exit_count, this_exit, total_count;
  int texits;
  ufun_attrib ufun;
  PUEBLOBUFF;

  /* make sure location is a room */
  if (!IsRoom(loc))
    return;

  tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string");
  tbuf2 = (char *) mush_malloc(BUFFER_LEN, "string");
  nbuf = (char *) mush_malloc(BUFFER_LEN, "string");
  if (!tbuf1 || !tbuf2 || !nbuf)
    mush_panic("Unable to allocate memory in look_exits");
  s1 = tbuf1;
  s2 = tbuf2;
  texits = exit_count = total_count = 0;
  this_exit = 1;

  if (fetch_ufun_attrib
      ("EXITFORMAT", loc, &ufun, UFUN_IGNORE_PERMS | UFUN_REQUIRE_ATTR)) {
    char *arg, *buff, *bp;
    PE_REGS *pe_regs = pe_regs_create(PE_REGS_ARG, "look_exits");

    arg = (char *) mush_malloc(BUFFER_LEN, "string");
    buff = (char *) mush_malloc(BUFFER_LEN, "string");
    if (!arg || !buff)
      mush_panic("Unable to allocate memory in look_exits");

    bp = arg;
    DOLIST(thing, Exits(loc)) {
      if (((Light(loc) || Light(thing)) || !(Dark(loc) || Dark(thing)))
          && can_interact(thing, player, INTERACT_SEE, pe_info)) {
        if (bp != arg)
          safe_chr(' ', arg, &bp);
        safe_dbref(thing, arg, &bp);
      }
    }
    *bp = '\0';
    pe_regs_setenv_nocopy(pe_regs, 0, arg);

    call_ufun(&ufun, buff, player, player, pe_info, pe_regs);

    pe_regs_free(pe_regs);
    notify_by(loc, player, buff);
    mush_free(tbuf1, "string");
    mush_free(tbuf2, "string");
    mush_free(nbuf, "string");
    mush_free(arg, "string");
    mush_free(buff, "string");
    return;
  }
コード例 #2
0
/** A wrapper for real_did_it that can set %0 and %1 to dbrefs.
 * \param player the enactor.
 * \param thing object being triggered.
 * \param what message attribute for enactor.
 * \param def default message to enactor.
 * \param owhat message attribute for others.
 * \param odef default message to others.
 * \param awhat action attribute to trigger.
 * \param loc location in which action is taking place.
 * \param env0 dbref to pass as %0, or NOTHING.
 * \param env1 dbref to pass as %1, or NOTHING.
 * \param flags interaction flags to pass to real_did_it.
 * \retval 0 no attributes were present, only defaults were used if given.
 * \retval 1 some attributes were evaluated and used.
 */
int
did_it_with(dbref player, dbref thing, const char *what, const char *def,
            const char *owhat, const char *odef, const char *awhat,
            dbref loc, dbref env0, dbref env1, int flags, int an_flags)
{
  PE_REGS *pe_regs = pe_regs_create(PE_REGS_ARG, "did_it_with");
  int retval;

  if (env0 != NOTHING) {
    pe_regs_setenv(pe_regs, 0, unparse_dbref(env0));
  }
  if (env1 != NOTHING) {
    pe_regs_setenv(pe_regs, 1, unparse_dbref(env1));
  }
  retval = real_did_it(player, thing, what, def, owhat, odef, awhat, loc,
                       pe_regs, flags, an_flags);

  pe_regs_free(pe_regs);
  return retval;
}
コード例 #3
0
ファイル: speech.c プロジェクト: kymoon/pennmush
/** The say command.
 * \param player the enactor.
 * \param message the message to say.
 * \param pe_info pe_info to eval speechmod with
 */
void
do_say(dbref player, const char *message, NEW_PE_INFO *pe_info)
{
  dbref loc;
  PE_REGS *pe_regs;
  char modmsg[BUFFER_LEN];
  char says[BUFFER_LEN];
  char *sp;
  int mod = 0;
  loc = speech_loc(player);
  if (!GoodObject(loc))
    return;

  if (!Loud(player) && !eval_lock_with(player, loc, Speech_Lock, pe_info)) {
    fail_lock(player, loc, Speech_Lock, T("You may not speak here!"), NOTHING);
    return;
  }

  if (*message == SAY_TOKEN && CHAT_STRIP_QUOTE)
    message++;

  pe_regs = pe_regs_create(PE_REGS_ARG, "do_say");
  pe_regs_setenv_nocopy(pe_regs, 0, message);
  pe_regs_setenv_nocopy(pe_regs, 1, "\"");
  modmsg[0] = '\0';

  if (call_attrib(player, "SPEECHMOD", modmsg, player, pe_info, pe_regs)
      && *modmsg != '\0')
    mod = 1;
  pe_regs_free(pe_regs);

  /* notify everybody */
  notify_format(player, T("You say, \"%s\""), (mod ? modmsg : message));
  sp = says;
  safe_format(says, &sp, T("%s says, \"%s\""), spname(player),
              (mod ? modmsg : message));
  *sp = '\0';
  notify_except(player, loc, player, says, NA_INTER_HEAR);
}
コード例 #4
0
ファイル: set.c プロジェクト: FranticFanatic/pennmush
/** Rename something.
 * \verbatim
 * This implements @name.
 * \endverbatim
 * \param player the enactor.
 * \param name current name of object to rename.
 * \param newname_ new name for object.
 */
void
do_name(dbref player, const char *name, char *newname_)
{
  dbref thing;
  char oldname[BUFFER_LEN];
  char *newname = NULL;
  char *alias = NULL;
  PE_REGS *pe_regs;

  if ((thing = match_controlled(player, name)) == NOTHING)
    return;

  /* check for bad name */
  if ((*newname_ == '\0') || strchr(newname_, '[')) {
    notify(player, T("Give it what new name?"));
    return;
  }
  switch (Typeof(thing)) {
  case TYPE_PLAYER:
    switch (ok_object_name
            (newname_, player, thing, TYPE_PLAYER, &newname, &alias)) {
    case OPAE_INVALID:
    case OPAE_NULL:
      notify(player, T("You can't give a player that name or alias."));
      if (newname)
        mush_free(newname, "name.newname");
      if (alias)
        mush_free(alias, "name.newname");
      return;
    case OPAE_TOOMANY:
      notify(player, T("Too many aliases."));
      mush_free(newname, "name.newname");
      return;
    case OPAE_SUCCESS:
      break;
    }
    break;
  case TYPE_EXIT:
    if (ok_object_name(newname_, player, thing, TYPE_EXIT, &newname, &alias) !=
        OPAE_SUCCESS) {
      notify(player, T("That is not a reasonable name."));
      if (newname)
        mush_free(newname, "name.newname");
      if (alias)
        mush_free(alias, "name.newname");
      return;
    }
    break;
  case TYPE_THING:
  case TYPE_ROOM:
    if (!ok_name(newname_, 0)) {
      notify(player, T("That is not a reasonable name."));
      return;
    }
    newname = mush_strdup(trim_space_sep(newname_, ' '), "name.newname");
    break;
  default:
    /* Should never occur */
    notify(player, T("I don't see that here."));
    return;
  }

  /* Actually change it */
  mush_strncpy(oldname, Name(thing), BUFFER_LEN);

  if (IsPlayer(thing)) {
    do_log(LT_CONN, 0, 0, "Name change by %s(#%d) to %s",
           Name(thing), thing, newname);
    if (Suspect(thing) && strcmp(Name(thing), newname) != 0)
      flag_broadcast("WIZARD", 0,
                     T("Broadcast: Suspect %s changed name to %s."),
                     Name(thing), newname);
    reset_player_list(thing, Name(thing), NULL, newname, NULL);
  }
  set_name(thing, newname);
  if (alias) {
    if (*alias == ALIAS_DELIMITER) {
      do_set_atr(thing, "ALIAS", NULL, player, 0);
    } else {
      /* New alias to set */
      do_set_atr(thing, "ALIAS", alias, player, 0);
    }
    mush_free(alias, "name.newname");
  }

  queue_event(player, "OBJECT`RENAME", "%s,%s,%s",
              unparse_objid(thing), newname, oldname);

  if (!AreQuiet(player, thing))
    notify(player, T("Name set."));
  pe_regs = pe_regs_create(PE_REGS_ARG, "do_name");
  pe_regs_setenv_nocopy(pe_regs, 0, oldname);
  pe_regs_setenv_nocopy(pe_regs, 1, newname);
  real_did_it(player, thing, NULL, NULL, "ONAME", NULL, "ANAME", NOTHING,
              pe_regs, NA_INTER_PRESENCE, AN_SYS);
  pe_regs_free(pe_regs);
  mush_free(newname, "name.newname");
}
コード例 #5
0
/** User-defined verbs.
 * \verbatim
 * This implements the @verb command.
 * \endverbatim
 * \param executor the executor.
 * \param enactor the object causing this command to run.
 * \param arg1 the object to read verb attributes from.
 * \param argv the array of remaining arguments to the verb command.
 * \param queue_entry The queue entry \@verb is running in
 */
void
do_verb(dbref executor, dbref enactor, char *arg1, char **argv,
        MQUE *queue_entry)
{
  dbref victim;
  dbref actor;
  int i;
  PE_REGS *pe_regs = NULL;

  /* find the object that we want to read the attributes off
   * (the object that was the victim of the command)
   */

  /* our victim object can be anything */
  victim = match_result(executor, arg1, NOTYPE, MAT_EVERYTHING);

  if (!GoodObject(victim)) {
    notify(executor, T("What was the victim of the verb?"));
    return;
  }
  /* find the object that executes the action */

  if (!argv || !argv[1] || !*argv[1]) {
    notify(executor, T("What do you want to do with the verb?"));
    return;
  }
  actor = match_result(executor, argv[1], NOTYPE, MAT_EVERYTHING);

  if (!GoodObject(actor)) {
    notify(executor, T("What do you want to do the verb?"));
    return;
  }
  /* Control check is fascist.
   * First check: we don't want <actor> to do something involuntarily.
   *   Both victim and actor have to be controlled by the thing which did
   *   the @verb (for speed we do a WIZARD check first), or: cause controls
   *   actor plus the second check is passed.
   * Second check: we need read access to the attributes.
   *   Either the player controls victim or the player
   *   must be priviledged, or the victim has to be VISUAL.
   */

  if (!(Wizard(executor) ||
        (controls(executor, victim) && controls(executor, actor)) ||
        ((controls(enactor, actor) && Can_Examine(executor, victim))))) {
    notify(executor, T("Permission denied."));
    return;
  }
  /* We're okay.  Send out messages. */

  pe_regs = pe_regs_create(PE_REGS_ARG | PE_REGS_Q, "do_verb");
  for (i = 0; i < MAX_STACK_ARGS; i++) {
    if (argv[i + 7]) {
      pe_regs_setenv_nocopy(pe_regs, i, argv[i + 7]);
    }
  }
  pe_regs_qcopy(pe_regs, queue_entry->pe_info->regvals);

  real_did_it(actor, victim,
              upcasestr(argv[2]), argv[3], upcasestr(argv[4]), argv[5],
              NULL, Location(actor), pe_regs, NA_INTER_HEAR, AN_SYS);

  /* Now we copy our args into the stack, and do the command. */

  if (argv[6] && *argv[6])
    queue_attribute_base(victim, upcasestr(argv[6]), actor, 0, pe_regs,
                         (queue_entry->queue_type & QUEUE_EVENT));

  pe_regs_free(pe_regs);
}
コード例 #6
0
/** The switch command.
 * \verbatim
 * For lack of better place the @switch code is here.
 * @switch expression=args
 * \endverbatim
 * \param executor the executor.
 * \param expression the expression to test against cases.
 * \param argv array of cases and actions.
 * \param enactor the object that caused this code to run.
 * \param first if 1, run only first matching case; if 0, run all matching cases.
 * \param notifyme if 1, perform a notify after executing matched cases.
 * \param regexp if 1, do regular expression matching; if 0, wildcard globbing.
 * \param queue_type the type of queue to run any new commands as
 * \param queue_entry the queue entry \@switch is being run in
 */
void
do_switch(dbref executor, char *expression, char **argv, dbref enactor,
          int first, int notifyme, int regexp, int queue_type,
          MQUE *queue_entry)
{
  int any = 0, a;
  char buff[BUFFER_LEN], *bp;
  char const *ap;
  char *tbuf1;
  PE_REGS *pe_regs;

  if (!argv[1])
    return;

  /* now try a wild card match of buff with stuff in coms */
  for (a = 1;
       !(first && any) && (a < (MAX_ARG - 1)) && argv[a] && argv[a + 1];
       a += 2) {
    /* eval expression */
    ap = argv[a];
    bp = buff;
    if (process_expression(buff, &bp, &ap, executor, enactor, enactor,
                           PE_DEFAULT, PT_DEFAULT, queue_entry->pe_info)) {
      return;
    }
    *bp = '\0';
    /* check for a match */
    pe_regs = pe_regs_create(PE_REGS_SWITCH | PE_REGS_CAPTURE, "do_switch");
    pe_regs_set(pe_regs, PE_REGS_SWITCH, "t0", expression);
    if (regexp ? regexp_match_case_r(buff, expression, 0,
                                     NULL, 0, NULL, 0, pe_regs, 0)
        : local_wild_match(buff, expression, pe_regs)) {
      tbuf1 = replace_string("#$", expression, argv[a + 1]);
      if (!any) {
        /* Add the new switch context to the parent queue... */
        any = 1;
      }
      if (queue_type & QUEUE_INPLACE) {
        new_queue_actionlist(executor, enactor, enactor, tbuf1, queue_entry,
                             PE_INFO_SHARE, queue_type, pe_regs);
      } else {
        new_queue_actionlist(executor, enactor, enactor, tbuf1, queue_entry,
                             PE_INFO_CLONE, queue_type, pe_regs);
      }
      mush_free(tbuf1, "replace_string.buff");
    }
  }
  /* do default if nothing has been matched */
  if ((a < MAX_ARG) && !any && argv[a]) {
    tbuf1 = replace_string("#$", expression, argv[a]);
    pe_regs = pe_regs_create(PE_REGS_SWITCH | PE_REGS_CAPTURE, "do_switch");
    pe_regs_set(pe_regs, PE_REGS_SWITCH, "t0", expression);
    if (queue_type & QUEUE_INPLACE) {
      new_queue_actionlist(executor, enactor, enactor, tbuf1, queue_entry,
                           PE_INFO_SHARE, queue_type, pe_regs);
    } else {
      new_queue_actionlist(executor, enactor, enactor, tbuf1, queue_entry,
                           PE_INFO_CLONE, queue_type, pe_regs);
    }
    mush_free(tbuf1, "replace_string.buff");
  }

  if (!(queue_type & QUEUE_INPLACE) && notifyme) {
    parse_que(executor, enactor, "@notify me", NULL);
  }
}