Пример #1
0
/** Evaluate a lock.
 * Evaluate lock ltype on thing for player, passing dbrefs for %0/%1.
 * \param player dbref attempting to pass the lock.
 * \param thing object containing the lock.
 * \param ltype type of lock to check.
 * \retval 1 player passes the lock.
 * \retval 0 player does not pass the lock.
 */
int
eval_lock_with(dbref player, dbref thing, lock_type ltype, dbref env0,
	       dbref env1)
{
  char *myenv[10] = { NULL };
  char e0[SBUF_LEN], e1[SBUF_LEN], *ep;
  char *preserves[10];
  int result;

  if (env0 != NOTHING) {
    ep = e0;
    safe_dbref(env0, e0, &ep);
    *ep = '\0';
    myenv[0] = e0;
  }

  if (env1 != NOTHING) {
    ep = e1;
    safe_dbref(env1, e1, &ep);
    *ep = '\0';
    myenv[1] = e1;
  }

  save_global_env("eval_lock_save", preserves);
  restore_global_env("eval_lock", myenv);

  boolexp b = getlock(thing, ltype);
  log_activity(LA_LOCK, thing, unparse_boolexp(player, b, UB_DBREF));
  result = eval_boolexp(player, b, thing, NULL);
  restore_global_env("eval_lock_save", preserves);
  return result;
}
Пример #2
0
/* 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;
  }
Пример #3
0
static void unparse_boolexp1( dbref player, BOOLEXP *b, char outer_type, int format ) {
    ATTR *ap;

    char sep_ch;

    char *buff;

    if( b == TRUE_BOOLEXP ) {
        if( format == F_EXAMINE ) {
            safe_str( ( char * ) "*UNLOCKED*", boolexp_buf, &buftop );
        }
        return;
    }
    switch( b->type ) {
    case BOOLEXP_AND:
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( AND_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_OR:
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( OR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_NOT:
        safe_chr( '!', boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_INDIR:
        safe_chr( INDIR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_IS:
        safe_chr( IS_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CARRY:
        safe_chr( CARRY_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_OWNER:
        safe_chr( OWNER_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CONST:
        if( !mudstate.standalone ) {
            switch( format ) {
            case F_QUIET:

                /*
                 * Quiet output - for dumps and internal use.
                 * Always #Num
                 */

                safe_str( ( char * ) unparse_object_quiet( player,
                          b->thing ), boolexp_buf, &buftop );
                break;
            case F_EXAMINE:

                /*
                 * Examine output - informative. *
                 * Name(#Num) or Name
                 */

                buff = unparse_object( player, b->thing, 0 );
                safe_str( buff, boolexp_buf, &buftop );
                free_lbuf( buff );
                break;
            case F_DECOMPILE:

                /*
                 * Decompile output - should be usable on
                 * other MUSHes. *Name if player, Name if
                 * thing, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                case TYPE_THING:
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
                break;
            case F_FUNCTION:

                /*
                 * Function output - must be usable by @lock
                 * cmd.  *Name if player, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
            }
        } else {
            safe_str( ( char * ) unparse_object_quiet( player,
                      b->thing ), boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_ATR:
    case BOOLEXP_EVAL:
        if( b->type == BOOLEXP_EVAL ) {
            sep_ch = '/';
        } else {
            sep_ch = ':';
        }
        ap = atr_num( b->thing );
        if( ap && ap->number ) {
            safe_str( ( char * ) ap->name, boolexp_buf, &buftop );
        } else {
            safe_ltos( boolexp_buf, &buftop, b->thing );
        }
        safe_chr( sep_ch, boolexp_buf, &buftop );
        safe_str( ( char * ) b->sub1, boolexp_buf, &buftop );
        break;
    default:
        log_write_raw( 1, "ABORT! unparse.c, bad boolexp type in unparse_boolexp1().\n" );
        abort();
        break;
    }
}
Пример #4
0
/** Given a ufun, executor, enactor, PE_Info, and arguments for %0-%9,
 *  call the ufun with appropriate permissions on values given for
 *  wenv_args. The value returned is stored in the buffer pointed to
 *  by ret, if given.
 * \param ufun The ufun_attrib that was initialized by fetch_ufun_attrib
 * \param ret If desired, a pointer to a buffer in which the results
 *            of the process_expression are stored in.
 * \param caller The caller (%@).
 * \param enactor The enactor. (%#)
 * \param pe_info The pe_info passed to the FUNCTION
 * \param user_regs Other arguments that may want to be added. This nests BELOW
 *                the pe_regs created by call_ufun. (It is checked first)
 * \param data a void pointer to extra data. Currently only used to pass the
 *             name to use, when UFUN_NAME is given.
 * \retval 0 success
 * \retval 1 process_expression failed. (CPU time limit)
 */
bool
call_ufun_int(ufun_attrib * ufun, char *ret, dbref caller, dbref enactor,
              NEW_PE_INFO *pe_info, PE_REGS *user_regs, void *data)
{
  char rbuff[BUFFER_LEN];
  char *rp, *np = NULL;
  int pe_ret;
  char const *ap;
  char old_attr[BUFFER_LEN];
  int made_pe_info = 0;
  PE_REGS *pe_regs;
  PE_REGS *pe_regs_old;
  int pe_reg_flags = 0;

  /* Make sure we have a ufun first */
  if (!ufun)
    return 1;
  if (!pe_info) {
    pe_info = make_pe_info("pe_info.call_ufun");
    made_pe_info = 1;
  } else {
    strcpy(old_attr, pe_info->attrname);
  }

  pe_regs_old = pe_info->regvals;

  if (ufun->ufun_flags & UFUN_LOCALIZE)
    pe_reg_flags |= PE_REGS_Q;
  else {
    pe_reg_flags |= PE_REGS_NEWATTR;
    if (ufun->ufun_flags & UFUN_SHARE_STACK)
      pe_reg_flags |= PE_REGS_ARGPASS;
  }

  pe_regs = pe_regs_localize(pe_info, pe_reg_flags, "call_ufun");

  rp = pe_info->attrname;
  if (*ufun->attrname == '\0') {
    safe_str("#LAMBDA", pe_info->attrname, &rp);
    safe_chr('/', pe_info->attrname, &rp);
    safe_str(ufun->contents, pe_info->attrname, &rp);
  } else {
    safe_dbref(ufun->thing, pe_info->attrname, &rp);
    safe_chr('/', pe_info->attrname, &rp);
    safe_str(ufun->attrname, pe_info->attrname, &rp);
  }
  *rp = '\0';

  /* If the user doesn't care about the return of the expression,
   * then use our own rbuff.  */
  if (!ret)
    ret = rbuff;
  rp = ret;

  /* Anything the caller wants available goes on the bottom of the stack */
  if (user_regs) {
    user_regs->prev = pe_info->regvals;
    pe_info->regvals = user_regs;
  }

  if (ufun->ufun_flags & UFUN_NAME) {
    char *name = (char *) data;
    if (!name || !*name)
      name = (char *) Name(enactor);
    safe_str(name, ret, &rp);
    if (!(ufun->ufun_flags & UFUN_NAME_NOSPACE))
      safe_chr(' ', ret, &rp);
    np = rp;
  }


  /* And now, make the call! =) */
  ap = ufun->contents;
  pe_ret = process_expression(ret, &rp, &ap, ufun->thing, caller,
                              enactor, ufun->pe_flags, PT_DEFAULT, pe_info);
  *rp = '\0';

  if ((ufun->ufun_flags & UFUN_NAME) && np == rp) {
    /* Attr was empty, so we take off the name again */
    *ret = '\0';
  }

  /* Restore call_ufun's pe_regs */
  if (user_regs) {
    pe_info->regvals = user_regs->prev;
  }

  /* Restore the pe_regs stack. */
  pe_regs_restore(pe_info, pe_regs);
  pe_regs_free(pe_regs);

  pe_info->regvals = pe_regs_old;

  if (!made_pe_info) {
    /* Restore the old attrname. */
    strcpy(pe_info->attrname, old_attr);
  } else {
    free_pe_info(pe_info);
  }

  return pe_ret;
}
Пример #5
0
void get_celestial_attribute(hcelestial *cel, char *which, char *buff, char **bp)
{
  int len;
  
  if (!cel)
  {
    safe_str("#-1 INVALID OBJECT", buff, bp);
    return;
  }
  
  if (!which)
  {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
    return;
  }
  
  len = strlen(which);
  if (len < 1)
  {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
    return;
  }
  
  if (!strncasecmp("OBJNUM", which, len))
  {
    safe_dbref(cel->objnum, buff, bp);
  }
  else if (!strncasecmp("NAME", which, len))
  {
    safe_str(celestial_name(cel), buff, bp);
  }
  else if (!strncasecmp("TYPE", which, len))
  {
    safe_str(STR(hs_object_types, HasFlag(cel->type, HS_OBJECT_FLAGS)), buff, bp);
  }
  else if (!strncasecmp("UNIVERSE", which, len))
  {
    if (cel->uid)
      safe_dbref(cel->uid->objnum, buff, bp);
    else
      safe_dbref(NOTHING, buff, bp);
  }
  else if (!strncasecmp("X", which, len))
  {
    safe_integer(cel->x, buff, bp);
  }
  else if (!strncasecmp("Y", which, len))
  {
    safe_integer(cel->y, buff, bp);
  }
  else if (!strncasecmp("Z", which, len))
  {
    safe_integer(cel->z, buff, bp);
  }
  else if (!strncasecmp("MASS", which, len))
  {
    safe_number(cel->mass, buff, bp);
  }
  else if (!strncasecmp("RADIUS", which, len))
  {
    safe_number(cel->radius, buff, bp);
  }
  else if (!strncasecmp("CONTENTS", which, len))
  {
    if (cel->contents)
      safe_str(cel->contents, buff, bp);
  } else {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
  }

  return;
}
Пример #6
0
void get_ship_attribute(hship *ship, char *which, char *buff, char **bp)
{
  int len, i;
  
  if (!ship)
  {
    safe_str("#-1 INVALID OBJECT", buff, bp);
    return;
  }
  
  if (!which)
  {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
    return;
  }
  
  len = strlen(which);
  if (len < 1)
  {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
    return;
  }
  
  if (!strncasecmp("OBJNUM", which, len))
  {
    safe_dbref(ship->objnum, buff, bp);
  }
  else if (!strncasecmp("NAME", which, len))
  {
    safe_str(ship_name(ship), buff, bp);
  }
  else if (!strncasecmp("TYPE", which, len))
  {
    if (HasFlag(ship->type, HS_DRONE))
      safe_str("DRONE", buff, bp);
    else
      safe_str("SHIP", buff, bp);
  }
  else if (!strncasecmp("UNIVERSE", which, len))
  {
    if (ship->uid)
      safe_dbref(ship->uid->objnum, buff, bp);
    else
      safe_dbref(NOTHING, buff, bp);
  }
  else if (!strncasecmp("X", which, len))
  {
    safe_integer(ship->x, buff, bp);
  }
  else if (!strncasecmp("Y", which, len))
  {
    safe_integer(ship->y, buff, bp);
  }
  else if (!strncasecmp("Z", which, len))
  {
    safe_integer(ship->z, buff, bp);
  }
  else if (!strncasecmp("SPEED", which, len))
  {
    safe_number(ship->speed, buff, bp);
  }
  else if (!strncasecmp("XYHEAD", which, len))
  {
    safe_integer(rint(ship->xyhead), buff, bp);
  }
  else if (!strncasecmp("ZHEAD", which, len))
  {
    safe_integer(rint(ship->zhead), buff, bp);
  }
  else if (!strncasecmp("LOCK", which, len))
  {
    if (ship->lock)
      safe_integer(ship->lock->cnum, buff, bp);
    else
      safe_str("#-1", buff, bp);
  }
  else if (!strncasecmp("WAYPOINT", which, len))
  {
    if (ship->wp_contact && ship->wp_contact->contact)
    {
      if (HasFlag(ship->wp_contact->type, HS_ANY_CELESTIAL))
      {
        safe_format(buff, bp, "#%d %.0f %.0f %.0f", ContactObj(ship->wp_contact), ContactCelestial(ship->wp_contact)->x,
              ContactCelestial(ship->wp_contact)->y, ContactCelestial(ship->wp_contact)->z);
      }
      else if (HasFlag(ship->wp_contact->type, HS_ANY_SHIP))
      {
        safe_format(buff, bp, "#%d %.0f %.0f %.0f", ContactObj(ship->wp_contact), ContactShip(ship->wp_contact)->x,
              ContactShip(ship->wp_contact)->y, ContactShip(ship->wp_contact)->z);
      }
    }
  }
  else if (!strncasecmp("CONSOLES", which, len))
  {
    for (i = 0; i < ship->nconsoles; i++)
    {
      if (i > 0)
        safe_str(" ", buff, bp);
      
      safe_dbref(ship->console[i].objnum, buff, bp);
    }
  }
  else if (!strncasecmp("LANDED", which, len))
  {
    if (ship->landed)
      safe_dbref(ship->landed->objnum, buff, bp);
    else
      safe_dbref(NOTHING, buff, bp);
  }
  else if (!strncasecmp("DOCKED", which, len))
  {
    if (ship->docked)
      safe_dbref(ship->docked->objnum, buff, bp);
    else
      safe_dbref(NOTHING, buff, bp);
  }
  else if (!strncasecmp("LINKED", which, len))
  {
    if (ship->linked)
      safe_dbref(ship->linked->objnum, buff, bp);
    else
      safe_dbref(NOTHING, buff, bp);
  }
  else if (!strncasecmp("ZHEAD", which, len))
  {
    safe_integer(rint(ship->zhead), buff, bp);
  }
  else if (!strncasecmp("NAVMODE", which, len))
  {
    safe_str(STR(hs_nav_modes, HasFlag(ship->type, HS_ANY_MODE)), buff, bp);
  }
  else if (!strncasecmp("AFTERBURNING", which, len))
  {
    if (HasFlag(ship->type, HS_AFTERBURNING))
      safe_integer(1, buff, bp);
    else
      safe_integer(0, buff, bp);
  }
  else if (!strncasecmp("SHIELD", which, len))
  {
    safe_integer(rint(ship->shield.energy / get_stat(ship, SYS_MAX_CAPACITY) * 100.0), buff, bp);
  }
  else if (!strncasecmp("HULL", which, len))
  {
    safe_integer(rint(ship->hull.energy / get_stat(ship, SYS_MAX_ARMOR) * 100.0), buff, bp);
  }
  else if (!strncasecmp("ENGINE", which, len))
  {
    safe_integer(rint(ship->engine.energy / get_stat(ship, SYS_MAX_HEAT) * 100.0), buff, bp);
  }
  else if (!strncasecmp("REACTOR", which, len))
  {
    safe_integer(rint(ship->reactor.energy / get_stat(ship, SYS_MAX_ENERGY) * 100.0), buff, bp);
  }
  else if (!strncasecmp("COMPUTER", which, len))
  {
    safe_integer(rint(ship->computer.energy / get_stat(ship, SYS_MAX_MEMORY) * 100.0), buff, bp);
  }
  else if (!strncasecmp("SENSOR", which, len))
  {
    safe_integer(rint(ship->sensor.energy / get_stat(ship, SYS_MAX_FOCUS) * 100.0), buff, bp);
  }
  else
  {
    safe_str("#-1 INVALID ATTRIBUTE", buff, bp);
  }

  return;
}