예제 #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
파일: 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);
}
예제 #3
0
/** Helper function for calling \@functioned funs.
 * \param buff string to store result of evaluation.
 * \param bp pointer into end of buff.
 * \param obj object on which the ufun is stored.
 * \param attrib pointer to attribute on which the ufun is stored.
 * \param nargs number of arguments passed to the ufun.
 * \param args array of arguments passed to the ufun.
 * \param executor executor.
 * \param caller caller (unused).
 * \param enactor enactor.
 * \param pe_info pointer to structure for process_expression data.
 * \param extra_flags extra PE_ flags to pass in (PE_USERFN or 0).
 */
void
do_userfn(char *buff, char **bp, dbref obj, ATTR *attrib, int nargs,
          char **args, dbref executor, dbref caller
          __attribute__ ((__unused__)), dbref enactor, NEW_PE_INFO *pe_info,
          int extra_flags)
{
  int j;
  int made_pe_info = 0;
  char *tbuf;
  char const *tp;
  int pe_flags = PE_DEFAULT | extra_flags;
  PE_REGS *pe_regs;

  if (nargs > 10)
    nargs = 10;                 /* maximum ten args */

  /* save our stack */
  if (!pe_info) {
    made_pe_info = 1;
    pe_info = make_pe_info("pe_info-do_userfn");
  }

  /* copy the appropriate args into pe_regs */
  pe_regs = pe_regs_localize(pe_info, PE_REGS_ARG, "do_userfn");
  for (j = 0; j < nargs; j++) {
    pe_regs_setenv_nocopy(pe_regs, j, args[j]);
  }

  tp = tbuf = safe_atr_value(attrib);
  if (AF_NoDebug(attrib))
    pe_flags |= PE_NODEBUG;     /* no_debug overrides debug */
  else if (AF_Debug(attrib))
    pe_flags |= PE_DEBUG;

  process_expression(buff, bp, &tp, obj, executor, enactor, pe_flags,
                     PT_DEFAULT, pe_info);

  free(tbuf);

  pe_regs_restore(pe_info, pe_regs);
  pe_regs_free(pe_regs);

  if (made_pe_info) {
    free_pe_info(pe_info);
  }
}
예제 #4
0
/** 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);
}