Пример #1
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);
  }
}
Пример #2
0
/** Clone an object.
 * \verbatim
 * This is the top-level function for @clone, which creates a duplicate
 * of a (non-player) object.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to clone.
 * \param newname the name to give the duplicate.
 * \param preserve if 1, preserve ownership and privileges on duplicate.
 * \param newdbref the (unparsed) dbref to give the object, or NULL to use the next free
 * \param pe_info The pe_info to use for lock and \@command priv checks
 * \return dbref of the duplicate, or NOTHING.
 */
dbref
do_clone(dbref player, char *name, char *newname, int preserve, char *newdbref,
         NEW_PE_INFO *pe_info)
{
  dbref clone, thing;
  char dbnum[BUFFER_LEN];

  thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING);
  if (thing == NOTHING)
    return NOTHING;

  if (newname && *newname && !ok_name(newname, IsExit(thing))) {
    notify(player, T("That is not a reasonable name."));
    return NOTHING;
  }

  if (!controls(player, thing) || IsPlayer(thing) ||
      (IsRoom(thing) && !command_check_byname(player, "@dig", pe_info)) ||
      (IsExit(thing) && !command_check_byname(player, "@open", pe_info)) ||
      (IsThing(thing) && !command_check_byname(player, "@create", pe_info))) {
    notify(player, T("Permission denied."));
    return NOTHING;
  }
  /* don't allow cloning of destructed things */
  if (IsGarbage(thing)) {
    notify(player, T("There's nothing left of it to clone!"));
    return NOTHING;
  }
  if (preserve && !Wizard(player)) {
    notify(player, T("You cannot @CLONE/PRESERVE. Use normal @CLONE instead."));
    return NOTHING;
  }

  if (!make_first_free_wrapper(player, newdbref)) {
    return NOTHING;
  }

  /* make sure owner can afford it */
  switch (Typeof(thing)) {
  case TYPE_THING:
    if (can_pay_fees(player, Pennies(thing))) {
      clone = clone_object(player, thing, newname, preserve);
      notify_format(player, T("Cloned: Object %s."), unparse_dbref(clone));
      if (IsRoom(player))
        moveto(clone, player, player, "cloned");
      else
        moveto(clone, Location(player), player, "cloned");
      current_state.things++;
      local_data_clone(clone, thing, preserve);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  NULL, 0, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_ROOM:
    if (can_pay_fees(player, ROOM_COST)) {
      clone = clone_object(player, thing, newname, preserve);
      Exits(clone) = NOTHING;
      notify_format(player, T("Cloned: Room #%d."), clone);
      current_state.rooms++;
      local_data_clone(clone, thing, preserve);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  NULL, 0, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_EXIT:
    /* For exits, we don't want people to be able to link it to
       a location they can't with @open. So, all this stuff.
     */
    switch (Location(thing)) {
    case NOTHING:
      strcpy(dbnum, "#-1");
      break;
    case HOME:
      strcpy(dbnum, "home");
      break;
    case AMBIGUOUS:
      strcpy(dbnum, "variable");
      break;
    default:
      strcpy(dbnum, unparse_dbref(Location(thing)));
    }
    if (newname && *newname)
      clone = do_real_open(player, newname, dbnum, NOTHING, pe_info);
    else
      clone = do_real_open(player, Name(thing), dbnum, NOTHING, pe_info);
    if (!GoodObject(clone)) {
      return NOTHING;
    } else {
      char *alias_val = NULL;
      ATTR *alias_attr = NULL;
      alias_attr = atr_get_noparent(clone, "ALIAS");
      if (alias_attr) {
        alias_val = safe_atr_value(alias_attr, "atrval.do_clone");
        atr_clr(clone, "ALIAS", GOD);
      }
      atr_cpy(clone, thing);
      if (alias_val) {
        atr_add(clone, "ALIAS", alias_val, player, 0);
        mush_free(alias_val, "atrval.do_clone");
      }
      clone_locks(player, thing, clone);
      Zone(clone) = Zone(thing);
      Parent(clone) = Parent(thing);
      Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing));
      if (!preserve) {
        clear_flag_internal(clone, "WIZARD");
        clear_flag_internal(clone, "ROYALTY");
        Warnings(clone) = 0;    /* zap warnings */
        Powers(clone) = new_flag_bitmask("POWER");      /* zap powers */
      } else {
        Warnings(clone) = Warnings(thing);
        Powers(clone) = clone_flag_bitmask("POWER", Powers(thing));
      }
      if (Wizard(clone) || Royalty(clone) || Warnings(clone) ||
          !null_flagmask("POWER", Powers(clone)))
        notify(player,
               T
               ("Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @powers, or @warnings."));
      notify_format(player, T("Cloned: Exit #%d."), clone);
      local_data_clone(clone, thing, preserve);
      return clone;
    }
  }
  return NOTHING;

}