/** 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; }
/* 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; }
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; } }
/** 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; }
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; }
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; }