Beispiel #1
0
void 
do_parent(dbref player, dbref cause, int key, char *tname, char *pname)
{
    dbref thing, parent, curr;
    int lev;

    /* get victim */

    init_match(player, tname, NOTYPE);
    match_everything(0);
    thing = noisy_match_result();
    if (thing == NOTHING)
	return;

    /* Make sure we can do it */

    if ( NoMod(thing) && !WizMod(player) ) {
	notify_quiet(player, "Permission denied.");
	return;
    }
    if (!Controls(player, thing) &&
        !could_doit(player,thing,A_LTWINK, 0, 0)) {
	notify_quiet(player, "Permission denied.");
	return;
    }
    if ( Backstage(player) && NoBackstage(thing) ) {
	notify_quiet(player, "Permission denied.");
	return;
    }
    /* Find out what the new parent is */

    if (*pname) {
	init_match(player, pname, Typeof(thing));
	match_everything(0);
	parent = noisy_match_result();
	if (parent == NOTHING)
	    return;

	/* Make sure we have rights to set parent */

	if (!Parentable(player, parent)) {
	    notify_quiet(player, "Permission denied.");
	    return;
	}
	/* Verify no recursive reference */

	ITER_PARENTS(parent, curr, lev) {
	    if (curr == thing) {
		notify_quiet(player,
			     "You can't have yourself as a parent!");
		return;
	    }
	}
    } else {
Beispiel #2
0
void
do_mcpedit(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;
    McpFrame *mfr;

    if (!(mfr = descr_mcpframe(descr))) {
        do_edit(descr, player, name);
        return;
    } else if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS)
        return;

    mcpedit_program(descr, player, i, name, mfr);
}
Beispiel #3
0
void
do_unbless(int descr, dbref player, const char *what, const char *propname)
{
	dbref victim;
	struct match_data md;
	char buf[BUFFER_LEN];
	int cnt;

	if (!Wizard(player) || Typeof(player) != TYPE_PLAYER) {
		notify(player, "Only Wizard players may use this command.");
		return;
	}

	if (!propname || !*propname) {
		notify(player, "Usage is @unbless object=propname.");
		return;
	}

	/* get victim */
	init_match(descr, player, what, NOTYPE, &md);
	match_everything(&md);
	if ((victim = noisy_match_result(&md)) == NOTHING) {
		return;
	}

	if (!Wizard(OWNER(player))) {
		notify(player, "Permission denied. (You're not a wizard)");
		return;
	}

	cnt = blessprops_wildcard(player, victim, "", propname, 0);
	snprintf(buf, sizeof(buf), "%d propert%s unblessed.", cnt, (cnt == 1)? "y" : "ies");
	notify(player, buf);
}
Beispiel #4
0
/*
 * do_attach()
 *
 * This routine attaches a previously existing action to a source object.
 * The action will not do anything unless it is LINKed.
 *
 */
void
do_attach(int descr, dbref player, const char *action_name,
          const char *source_name)
{
    dbref action, source;
    dbref loc;                  /* player's current location */
    struct match_data md;
    char buf[BUFFER_LEN];

    if ((loc = DBFETCH(player)->location) == NOTHING)
        return;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (!*action_name || !*source_name) {
        anotify_nolisten2(player,
                          CINFO
                          "You must specify an action name and a source object.");
        return;
    }
    init_match(descr, player, action_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((action = noisy_match_result(&md)) == NOTHING)
        return;

    if (Typeof(action) != TYPE_EXIT) {
        anotify_nolisten2(player, CINFO "That's not an action.");
        return;
    } else if (!controls(player, action)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    }
    if (((source = parse_source(descr, player, source_name)) == NOTHING)
        || Typeof(source) == TYPE_PROGRAM)
        return;

    if (!unset_source(player, loc, action)) {
        return;
    }
    set_source(player, action, source);
    sprintf(buf, CSUCC "Action %s re-attached to %s.",
            unparse_object(player, action), NAME(source));
    anotify_nolisten2(player, buf);
    if (MLevel(action)) {
        SetMLevel(action, 0);
        anotify_nolisten2(player, CINFO "Action priority Level reset to zero.");
    }
}
Beispiel #5
0
HS_DBREF CHSInterface::NoisyMatchRoom(HS_DBREF player, char *name)
{
    HS_DBREF room;

#ifdef PENNMUSH                 // No change in code between versions
    room = noisy_match_result(player, name, TYPE_ROOM,
                              MAT_ABSOLUTE | MAT_HERE);
#endif

#if defined(TM3) || defined(MUX)
    init_match(player, name, TYPE_ROOM);
    match_absolute();
    match_here();
    room = noisy_match_result();
#endif

    if (room == AMBIGUOUS)
        room = NOTHING;

    return room;
}
Beispiel #6
0
void
do_edit(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;

    if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS)
        return;

    if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    } else if (FLAGS(i) & INTERNAL) {
        anotify_nolisten2(player, CFAIL NOEDIT_MESG);
        return;
    }

    FLAGS(i) |= INTERNAL;
    DBFETCH(i)->sp.program.first = read_program(i);
    DBFETCH(player)->sp.player.curr_prog = i;
    anotify_fmt(player, CINFO "Entering editor for %s.",
                unparse_object(player, i));
    /* list current line */
    do_list(player, i, 0, 0, 0);
    FLAGS(player) |= INTERACTIVE;
    DBDIRTY(i);
    DBDIRTY(player);
}
Beispiel #7
0
void
do_bless(int descr, dbref player, const char *what, const char *propname)
{
	dbref victim;
	struct match_data md;
	char buf[BUFFER_LEN];
	int cnt;

	if (force_level) {
		notify(player, "Can't @force an @bless.");
		return;
	}


	if (!Wizard(player) || Typeof(player) != TYPE_PLAYER) {
		notify(player, "Only Wizard players may use this command.");
		return;
	}

	if (!propname || !*propname) {
		notify(player, "Usage is @bless object=propname.");
		return;
	}

	/* get victim */
	init_match(descr, player, what, NOTYPE, &md);
	match_everything(&md);
	if ((victim = noisy_match_result(&md)) == NOTHING) {
		return;
	}

#ifdef GOD_PRIV
	if(tp_strict_god_priv && !God(player) && God(OWNER(victim))) {
		notify(player, "Only God may touch God's stuff.");
		return;
	}
#endif

	if (!Wizard(OWNER(player))) {
		notify(player, "Permission denied. (you're not a wizard)");
		return;
	}

	cnt = blessprops_wildcard(player, victim, "", propname, 1);
	snprintf(buf, sizeof(buf), "%d propert%s blessed.", cnt, (cnt == 1)? "y" : "ies");
	notify(player, buf);
}
Beispiel #8
0
HS_DBREF CHSInterface::NoisyMatchThing(HS_DBREF player, char *name)
{
    HS_DBREF console;

#ifdef PENNMUSH                 // No change in code between versions
    console = noisy_match_result(player, name, TYPE_THING, MAT_NEAR_THINGS);
#endif

#if defined(TM3) || defined(MUX)
    console = match_thing(player, name);
#endif

    if (console == AMBIGUOUS)
        console = NOTHING;

    return console;
}
Beispiel #9
0
/** Parse object/attribute strings into components.
 * This function takes a string which is of the format obj/attr or attr,
 * and returns the dbref of the object, and a pointer to the attribute.
 * If no object is specified, then the dbref returned is the player's.
 * str is destructively modified. This function is probably underused.
 * \param player the default object.
 * \param str the string to parse.
 * \param thing pointer to dbref of object parsed out of string.
 * \param attrib pointer to pointer to attribute structure retrieved.
 */
void
parse_attrib(dbref player, char *str, dbref *thing, ATTR **attrib)
{
  char *name;

  /* find the object */

  if ((name = strchr(str, '/')) != NULL) {
    *name++ = '\0';
    *thing = noisy_match_result(player, str, NOTYPE, MAT_EVERYTHING);
  } else {
    name = str;
    *thing = player;
  }

  /* find the attribute */
  *attrib = (ATTR *) atr_get(*thing, upcasestr(name));
}
Beispiel #10
0
// Specifically matches an exit for a given game driver
HS_DBREF CHSInterface::NoisyMatchExit(HS_DBREF player, char *name)
{
    HS_DBREF exit_m;

#ifdef PENNMUSH                 // No change in code between versions
    exit_m = match_result(player, name, TYPE_EXIT, MAT_EXIT);
#endif

#if defined(TM3) || defined(MUX)
    init_match(player, name, TYPE_EXIT);
    match_exit();
    match_absolute();
    exit_m = noisy_match_result();
#endif

    if (exit_m == AMBIGUOUS)
        exit_m = NOTHING;

    return exit_m;
}
Beispiel #11
0
/*
 * parse_source()
 *
 * This is a utility used by do_action and do_attach.  It parses
 * the source string into a dbref, and checks to see that it
 * exists.
 *
 * The return value is the dbref of the source, or NOTHING if an
 * error occurs.
 *
 */
dbref
parse_source(int descr, dbref player, const char *source_name)
{
    dbref source;
    struct match_data md;

    init_match(descr, player, source_name, NOTYPE, &md); /* source type can be
                                                          * any */
    match_neighbor(&md);
    match_me(&md);
    match_here(&md);
    match_possession(&md);
    match_registered(&md);
    match_absolute(&md);
    source = noisy_match_result(&md);

    if (source == NOTHING)
        return NOTHING;

    /* You can only attach actions to things you control */
    if (!controls(player, source)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return NOTHING;
    }
    if (Typeof(source) == TYPE_EXIT) {
        anotify_nolisten2(player,
                          CFAIL "You can't attach an action to an action.");
        return NOTHING;
    }
    if (Typeof(source) == TYPE_PROGRAM) {
        anotify_nolisten2(player,
                          CFAIL "You can't attach an action to a program.");
        return NOTHING;
    }
    return source;
}
Beispiel #12
0
void
do_teleport(int descr, dbref player, const char *arg1, const char *arg2)
{
	dbref victim;
	dbref destination;
	const char *to;
	struct match_data md;

	/* get victim, destination */
	if (*arg2 == '\0') {
		victim = player;
		to = arg1;
	} else {
		init_match(descr, player, arg1, NOTYPE, &md);
		match_neighbor(&md);
		match_possession(&md);
		match_me(&md);
		match_here(&md);
		match_absolute(&md);
		match_registered(&md);
		match_player(&md);

		if ((victim = noisy_match_result(&md)) == NOTHING) {
			return;
		}
		to = arg2;
	}
#ifdef GOD_PRIV
	if(tp_strict_god_priv && !God(player) && God(OWNER(victim))) {
		notify(player, "God has already set that where He wants it to be.");
		return;
	}
#endif

	/* get destination */
	init_match(descr, player, to, TYPE_PLAYER, &md);
	match_possession(&md);
	match_me(&md);
	match_here(&md);
	match_home(&md);
	match_absolute(&md);
	match_registered(&md);
	if (Wizard(OWNER(player))) {
		match_neighbor(&md);
		match_player(&md);
	}
	switch (destination = match_result(&md)) {
	case NOTHING:
		notify(player, "Send it where?");
		break;
	case AMBIGUOUS:
		notify(player, "I don't know which destination you mean!");
		break;
	case HOME:
		switch (Typeof(victim)) {
		case TYPE_PLAYER:
			destination = PLAYER_HOME(victim);
			if (parent_loop_check(victim, destination))
				destination = PLAYER_HOME(OWNER(victim));
			break;
		case TYPE_THING:
			destination = THING_HOME(victim);
			if (parent_loop_check(victim, destination)) {
			  destination = PLAYER_HOME(OWNER(victim));
			  if (parent_loop_check(victim, destination)) {
			    destination = (dbref) 0;
			  }
			}
			break;
		case TYPE_ROOM:
			destination = GLOBAL_ENVIRONMENT;
			break;
		case TYPE_PROGRAM:
			destination = OWNER(victim);
			break;
		default:
			destination = tp_player_start;	/* caught in the next
											   * switch anyway */
			break;
		}
	default:
		switch (Typeof(victim)) {
		case TYPE_PLAYER:
			if (!controls(player, victim) ||
				!controls(player, destination) ||
				!controls(player, getloc(victim)) ||
				(Typeof(destination) == TYPE_THING && !controls(player, getloc(destination)))) {
				notify(player, "Permission denied. (must control victim, dest, victim's loc, and dest's loc)");
				break;
			}
			if (Typeof(destination) != TYPE_ROOM && Typeof(destination) != TYPE_THING) {
				notify(player, "Bad destination.");
				break;
			}
			if (!Wizard(victim) &&
				(Typeof(destination) == TYPE_THING && !(FLAGS(destination) & VEHICLE))) {
				notify(player, "Destination object is not a vehicle.");
				break;
			}
			if (parent_loop_check(victim, destination)) {
				notify(player, "Objects can't contain themselves.");
				break;
			}
			notify(victim, "You feel a wrenching sensation...");
			enter_room(descr, victim, destination, DBFETCH(victim)->location);
			notify(player, "Teleported.");
			break;
		case TYPE_THING:
			if (parent_loop_check(victim, destination)) {
				notify(player, "You can't make a container contain itself!");
				break;
			}
		case TYPE_PROGRAM:
			if (Typeof(destination) != TYPE_ROOM
				&& Typeof(destination) != TYPE_PLAYER && Typeof(destination) != TYPE_THING) {
				notify(player, "Bad destination.");
				break;
			}
			if (!((controls(player, destination) ||
				   can_link_to(player, NOTYPE, destination)) &&
				  (controls(player, victim) || controls(player, DBFETCH(victim)->location)))) {
				notify(player, "Permission denied. (must control dest and be able to link to it, or control dest's loc)");
				break;
			}
			/* check for non-sticky dropto */
			if (Typeof(destination) == TYPE_ROOM
				&& DBFETCH(destination)->sp.room.dropto != NOTHING
				&& !(FLAGS(destination) & STICKY))
						destination = DBFETCH(destination)->sp.room.dropto;
			if (tp_thing_movement && (Typeof(victim) == TYPE_THING)) {
				enter_room(descr, victim, destination, DBFETCH(victim)->location);
			} else {
				moveto(victim, destination);
			}
			notify(player, "Teleported.");
			break;
		case TYPE_ROOM:
			if (Typeof(destination) != TYPE_ROOM) {
				notify(player, "Bad destination.");
				break;
			}
			if (!controls(player, victim)
				|| !can_link_to(player, NOTYPE, destination)
				|| victim == GLOBAL_ENVIRONMENT) {
				notify(player, "Permission denied. (Can't move #0, dest must be linkable, and must control victim)");
				break;
			}
			if (parent_loop_check(victim, destination)) {
				notify(player, "Parent would create a loop.");
				break;
			}
			moveto(victim, destination);
			notify(player, "Parent set.");
			break;
		case TYPE_GARBAGE:
			notify(player, "That object is in a place where magic cannot reach it.");
			break;
		default:
			notify(player, "You can't teleport that.");
			break;
		}
		break;
	}
	return;
}
Beispiel #13
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.
 * \paran newdbref the (unparsed) dbref to give the object, or NULL to use the next free
 * \return dbref of the duplicate, or NOTHING.
 */
dbref
do_clone(dbref player, char *name, char *newname, int preserve, char *newdbref)
{
  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")) ||
      (IsExit(thing) && !command_check_byname(player, "@open")) ||
      (IsThing(thing) && !command_check_byname(player, "@create"))) {
    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);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  global_eval_context.wenv, 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);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  global_eval_context.wenv, 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);
    else
      clone = do_real_open(player, Name(thing), dbnum, NOTHING);
    if (!GoodObject(clone)) {
      return NOTHING;
    } else {
      atr_cpy(clone, thing);
      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);
      return clone;
    }
  }
  return NOTHING;

}
Beispiel #14
0
void
do_force(int descr, dbref player, const char *what, char *command)
{
	dbref victim, loc;
	struct match_data md;

	assert(what != NULL);
	assert(command != NULL);
	assert(player > 0);

	if (force_level > (tp_max_force_level - 1)) {
		notify(player, "Can't force recursively.");
		return;
	}

	if (!tp_zombies && (!Wizard(player) || Typeof(player) != TYPE_PLAYER)) {
		notify(player, "Zombies are not enabled here.");
		return;
#ifdef DEBUG	
	} else {
		notify(player, "[debug] Zombies are not enabled for nonwizards -- force succeeded.");
#endif
	}

	/* get victim */
	init_match(descr, player, what, NOTYPE, &md);
	match_neighbor(&md);
	match_possession(&md);
	match_me(&md);
	match_here(&md);
	match_absolute(&md);
	match_registered(&md);
	match_player(&md);

	if ((victim = noisy_match_result(&md)) == NOTHING) {
#ifdef DEBUG
		notify(player, "[debug] do_force: unable to find your target!");
#endif /* DEBUG */
		return;
	}

	if (Typeof(victim) != TYPE_PLAYER && Typeof(victim) != TYPE_THING) {
		notify(player, "Permission Denied -- Target not a player or thing.");
		return;
	}
#ifdef GOD_PRIV
	if (God(victim)) {
		notify(player, "You cannot force God to do anything.");
		return;
	}
#endif							/* GOD_PRIV */

/*    if (!controls(player, victim)) {
 *	notify(player, "Permission denied. (you're not a wizard!)");
 *	return;
 *    }
 */

	if (!Wizard(player) && !(FLAGS(victim) & XFORCIBLE)) {
		notify(player, "Permission denied: forced object not @set Xforcible.");
		return;
	}
	if (!Wizard(player) && !test_lock_false_default(descr, player, victim, MESGPROP_FLOCK)) {
		notify(player, "Permission denied: Object not force-locked to you.");
		return;
	}

	loc = getloc(victim);
	if (!Wizard(player) && Typeof(victim) == TYPE_THING && loc != NOTHING &&
		(FLAGS(loc) & ZOMBIE) && Typeof(loc) == TYPE_ROOM) {
		notify(player, "Sorry, but that's in a no-puppet zone.");
		return;
	}

	if (!Wizard(OWNER(player)) && Typeof(victim) == TYPE_THING) {
		const char *ptr = NAME(victim);
		char objname[BUFFER_LEN], *ptr2;

		if ((FLAGS(player) & ZOMBIE)) {
			notify(player, "Permission denied -- you cannot use zombies.");
			return;
		}
		if (FLAGS(victim) & DARK) {
			notify(player, "Permission denied -- you cannot force dark zombies.");
			return;
		}
		for (ptr2 = objname; *ptr && !isspace(*ptr);)
			*(ptr2++) = *(ptr++);
		*ptr2 = '\0';
		if (lookup_player(objname) != NOTHING) {
			notify(player, "Puppet cannot share the name of a player.");
			return;
		}
	}

	log_status("FORCED: %s(%d) by %s(%d): %s", NAME(victim),
			   victim, NAME(player), player, command);
	/* force victim to do command */
	force_prog=NOTHING;
	force_level++;
	process_command(dbref_first_descr(victim), victim, command);
	force_level--;
	force_prog=NOTHING;
}
Beispiel #15
0
/** Populate a ufun_attrib struct from an obj/attr pair.
 * \verbatim Given an attribute [<object>/]<name> pair (which may include #lambda),
 * fetch its value, owner (thing), and pe_flags, and store in the struct
 * pointed to by ufun
 * \endverbatim
 * \param attrstring The obj/name of attribute.
 * \param executor Dbref of the executing object.
 * \param ufun Pointer to an allocated ufun_attrib struct to fill in.
 * \param flags A bitwise or of desired UFUN_* flags.
 * \return 0 on failure, true on success.
 */
bool
fetch_ufun_attrib(const char *attrstring, dbref executor, ufun_attrib * ufun,
                  int flags)
{
  char *thingname, *attrname;
  char astring[BUFFER_LEN];
  ATTR *attrib;

  if (!ufun)
    return 0;

  ufun->contents[0] = '\0';
  ufun->errmess = (char *) "";
  ufun->thing = executor;
  ufun->pe_flags = PE_UDEFAULT;
  ufun->ufun_flags = flags;

  ufun->thing = executor;
  thingname = NULL;

  if (!attrstring)
    return 0;
  strncpy(astring, attrstring, BUFFER_LEN);

  /* Split obj/attr */
  if ((flags & UFUN_OBJECT) && ((attrname = strchr(astring, '/')) != NULL)) {
    thingname = astring;
    *(attrname++) = '\0';
  } else {
    attrname = astring;
  }

  if (thingname && (flags & UFUN_LAMBDA)
      && (strcasecmp(thingname, "#lambda") == 0
          || strncasecmp(thingname, "#apply", 6) == 0)) {
    /* It's a lambda. */

    ufun->ufun_flags &= ~UFUN_NAME;
    ufun->thing = executor;
    if (strcasecmp(thingname, "#lambda") == 0)
      mush_strncpy(ufun->contents, attrname, BUFFER_LEN);
    else {                      /* #apply */
      char *ucb = ufun->contents;
      unsigned nargs = 1, n;

      thingname += 6;

      if (*thingname)
        nargs = parse_uinteger(thingname);

      /* Limit between 1 and 10 arguments (%0-%9) */
      if (nargs == 0)
        nargs = 1;
      if (nargs > 10)
        nargs = 10;

      safe_str(attrname, ufun->contents, &ucb);
      safe_chr('(', ufun->contents, &ucb);
      for (n = 0; n < nargs; n++) {
        if (n > 0)
          safe_chr(',', ufun->contents, &ucb);
        safe_format(ufun->contents, &ucb, "%%%u", n);
      }
      safe_chr(')', ufun->contents, &ucb);
      *ucb = '\0';
    }

    ufun->attrname[0] = '\0';
    return 1;
  }

  if (thingname) {
    /* Attribute is on something else. */
    ufun->thing =
      noisy_match_result(executor, thingname, NOTYPE, MAT_EVERYTHING);
    if (!GoodObject(ufun->thing)) {
      ufun->errmess = (char *) "#-1 INVALID OBJECT";
      return 0;
    }
  }

  attrib = (ATTR *) atr_get(ufun->thing, upcasestr(attrname));
  if (attrib && AF_Internal(attrib)) {
    /* Regardless of whether we're doing permission checks, we should
     * never be showing internal attributes here */
    attrib = NULL;
  }

  /* An empty attrib is the same as no attrib. */
  if (attrib == NULL) {
    if (flags & UFUN_REQUIRE_ATTR) {
      if (!(flags & UFUN_IGNORE_PERMS) && !Can_Examine(executor, ufun->thing))
        ufun->errmess = e_atrperm;
      return 0;
    } else {
      mush_strncpy(ufun->attrname, attrname, ATTRIBUTE_NAME_LIMIT + 1);
      return 1;
    }
  }
  if (!(flags & UFUN_IGNORE_PERMS)
      && !Can_Read_Attr(executor, ufun->thing, attrib)) {
    ufun->errmess = e_atrperm;
    return 0;
  }
  if (!(flags & UFUN_IGNORE_PERMS)
      && !CanEvalAttr(executor, ufun->thing, attrib)) {
    ufun->errmess = e_perm;
    return 0;
  }

  /* DEBUG attributes */
  if (AF_NoDebug(attrib))
    ufun->pe_flags |= PE_NODEBUG;       /* No_Debug overrides Debug */
  else if (AF_Debug(attrib))
    ufun->pe_flags |= PE_DEBUG;

  if (flags & UFUN_NAME) {
    if (attrib->flags & AF_NONAME)
      ufun->ufun_flags &= ~UFUN_NAME;
    else if (attrib->flags & AF_NOSPACE)
      ufun->ufun_flags |= UFUN_NAME_NOSPACE;
  }

  /* Populate the ufun object */
  mush_strncpy(ufun->contents, atr_value(attrib), BUFFER_LEN);
  mush_strncpy(ufun->attrname, AL_NAME(attrib), ATTRIBUTE_NAME_LIMIT + 1);

  /* We're good */
  return 1;
}
Beispiel #16
0
/** Link an exit, room, player, or thing.
 * \verbatim
 * This is the top-level function for @link, which is used to link an
 * exit to a destination, set a player or thing's home, or set a
 * drop-to on a room.
 *
 * Linking an exit usually seizes ownership of the exit and costs 1 penny.
 * 1 penny is also transferred to the former owner.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to link.
 * \param room_name the name of the link destination.
 * \param preserve if 1, preserve ownership and zone data on exit relink.
 */
void
do_link(dbref player, const char *name, const char *room_name, int preserve)
{
  /* Use this to link to a room that you own.
   * It usually seizes ownership of the exit and costs 1 penny,
   * plus a penny transferred to the exit owner if they aren't you.
   * You must own the linked-to room AND specify it by room number.
   */

  dbref thing;
  dbref room;

  if (!room_name || !*room_name) {
    do_unlink(player, name);
    return;
  }
  if (!IsRoom(player) && GoodObject(Location(player)) &&
      IsExit(Location(player))) {
    notify(player, T("You somehow wound up in a exit. No biscuit."));
    return;
  }
  if ((thing = noisy_match_result(player, name, TYPE_EXIT, MAT_EVERYTHING))
      != NOTHING) {
    switch (Typeof(thing)) {
    case TYPE_EXIT:
      if ((room = check_var_link(room_name)) == NOTHING)
        room = parse_linkable_room(player, room_name);
      if (room == NOTHING)
        return;
      if (GoodObject(room) && !can_link_to(player, room)) {
        notify(player, T("Permission denied."));
        break;
      }
      /* We may link an exit if it's unlinked and we pass the link-lock
       * or if we control it.
       */
      if (!(controls(player, thing)
            || ((Location(thing) == NOTHING)
                && eval_lock(player, thing, Link_Lock)))) {
        notify(player, T("Permission denied."));
        return;
      }
      if (preserve && !Wizard(player)) {
        notify(player, T("Permission denied."));
        return;
      }
      /* handle costs */
      if (Owner(thing) == Owner(player)) {
        if (!payfor(player, LINK_COST)) {
          notify_format(player, T("It costs %d %s to link this exit."),
                        LINK_COST, ((LINK_COST == 1) ? MONEY : MONIES));
          return;
        }
      } else {
        if (!payfor(player, LINK_COST + EXIT_COST)) {
          int a = LINK_COST + EXIT_COST;
          notify_format(player, T("It costs %d %s to link this exit."), a,
                        ((a == 1) ? MONEY : MONIES));
          return;
        } else if (!preserve) {
          /* pay the owner for his loss */
          giveto(Owner(thing), EXIT_COST);
          chown_object(player, thing, player, 0);
        }
      }

      /* link has been validated and paid for; do it */
      if (!preserve) {
        Owner(thing) = Owner(player);
        Zone(thing) = Zone(player);
      }
      Location(thing) = room;

      /* notify the player */
      notify_format(player, T("Linked exit #%d to %s"), thing,
                    unparse_object(player, room));
      break;
    case TYPE_PLAYER:
    case TYPE_THING:
      if ((room =
           noisy_match_result(player, room_name, NOTYPE,
                              MAT_EVERYTHING)) == NOTHING) {
        notify(player, T("No match."));
        return;
      }
      if (IsExit(room)) {
        notify(player, T("That is an exit."));
        return;
      }
      if (thing == room) {
        notify(player, T("You may not link something to itself."));
        return;
      }
      /* abode */
      if (!controls(player, room) && !Abode(room)) {
        notify(player, T("Permission denied."));
        break;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else if (room == HOME) {
        notify(player, T("Can't set home to home."));
      } else {
        /* do the link */
        Home(thing) = room;     /* home */
        if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
          notify(player, T("Home set."));
      }
      break;
    case TYPE_ROOM:
      if ((room = parse_linkable_room(player, room_name)) == NOTHING)
        return;
      if ((room != HOME) && (!IsRoom(room))) {
        notify(player, T("That is not a room!"));
        return;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else {
        /* do the link, in location */
        Location(thing) = room; /* dropto */
        notify(player, T("Dropto set."));
      }
      break;
    default:
      notify(player, T("Internal error: weird object type."));
      do_log(LT_ERR, NOTHING, NOTHING,
             "Weird object! Type of #%d is %d", thing, Typeof(thing));
      break;
    }
  }
}
Beispiel #17
0
/** Change an object's zone.
 * \verbatim
 * This implements @chzone.
 * \endverbatim
 * \param player the enactor.
 * \param name name of the object to change zone of.
 * \param newobj name of new ZMO.
 * \param noisy if 1, notify player about success and failure.
 * \param preserve was the /preserve switch given?
 * \param pe_info the pe_info for lock and permission checks
 * \retval 0 failed to change zone.
 * \retval 1 successfully changed zone.
 */
int
do_chzone(dbref player, char const *name, char const *newobj, bool noisy,
          bool preserve, NEW_PE_INFO *pe_info)
{
  dbref thing;
  dbref zone;
  int has_lock;

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

  if (!newobj || !*newobj || !strcasecmp(newobj, "none"))
    zone = NOTHING;
  else {
    if ((zone = noisy_match_result(player, newobj, NOTYPE, MAT_EVERYTHING))
        == NOTHING)
      return 0;
  }

  if (Zone(thing) == zone) {
    if (noisy)
      notify(player, T("That object is already in that zone."));
    return 0;
  }


  if (!controls(player, thing)) {
    if (noisy)
      notify(player, T("You don't have the power to shift reality."));
    return 0;
  }
  /* a player may change an object's zone to:
   * 1.  NOTHING
   * 2.  an object he controls
   * 3.  an object with a chzone-lock that the player passes.
   * Note that an object with no chzone-lock isn't valid
   */
  has_lock = (getlock(zone, Chzone_Lock) != TRUE_BOOLEXP);
  if (!(Wizard(player) || (zone == NOTHING) || controls(player, zone) ||
        (has_lock && eval_lock_with(player, zone, Chzone_Lock, pe_info)))) {
    if (noisy) {
      if (has_lock) {
        fail_lock(player, zone, Chzone_Lock,
                  T("You cannot move that object to that zone."), NOTHING);
      } else {
        notify(player, T("You cannot move that object to that zone."));
      }
    }
    return 0;
  }
  /* Don't chzone object to itself for mortals! */
  if ((zone == thing) && !Hasprivs(player)) {
    if (noisy)
      notify(player, T("You shouldn't zone objects to themselves!"));
    return 0;
  }
  /* Don't allow circular zones */
  if (GoodObject(zone)) {
    dbref tmp;
    int zone_depth = MAX_ZONES;
    for (tmp = Zone(zone); GoodObject(tmp); tmp = Zone(tmp)) {
      if (tmp == thing) {
        notify(player, T("You can't make circular zones!"));
        return 0;
      }
      if (tmp == Zone(tmp))     /* Ran into an object zoned to itself */
        break;
      zone_depth--;
      if (!zone_depth) {
        notify(player, T("Overly deep zone chain."));
        return 0;
      }
    }
  }

  /* Don't allow chzone to objects without elocks!
   * If no lock is set, set a default lock (warn if zmo are used for control)
   * This checks for many trivial elocks (canuse/1, where &canuse=1)
   */
  if (zone != NOTHING)
    check_zone_lock(player, zone, noisy);

  /* Warn Wiz/Royals when they zone their stuff */
  if ((zone != NOTHING) && Hasprivs(Owner(thing))) {
    if (noisy)
      notify(player, T("Warning: @chzoning admin-owned object!"));
  }
  /* everything is okay, do the change */
  Zone(thing) = zone;

  /* If we're not unzoning, and we're working with a non-player object,
   * we'll remove wizard, royalty, inherit, and powers, for security, unless
   * a wizard is changing the zone and explicitly says not to.
   */
  if (!Wizard(player))
    preserve = 0;
  if (!preserve && ((zone != NOTHING) && !IsPlayer(thing))) {
    /* if the object is a player, resetting these flags is rather
     * inconvenient -- although this may pose a bit of a security
     * risk. Be careful when @chzone'ing wizard or royal players.
     */
    clear_flag_internal(thing, "WIZARD");
    clear_flag_internal(thing, "ROYALTY");
    clear_flag_internal(thing, "TRUST");
    destroy_flag_bitmask("POWER", Powers(thing));
    Powers(thing) = new_flag_bitmask("POWER");
  } else {
    if (noisy && (zone != NOTHING)) {
      if (Hasprivs(thing))
        notify(player, T("Warning: @chzoning a privileged player."));
      if (Inherit(thing))
        notify(player, T("Warning: @chzoning a TRUST player."));
    }
  }
  if (noisy)
    notify(player, T("Zone changed."));
  return 1;
}
Beispiel #18
0
/* do_link
 *
 * Use this to link to a room that you own.  It also sets home for
 * objects and things, and drop-to's for rooms.
 * It seizes ownership of an unlinked exit, and costs 1 penny
 * plus a penny transferred to the exit owner if they aren't you
 *
 * All destinations must either be owned by you, or be LINK_OK.
 */
void
do_link(int descr, dbref player, const char *thing_name, const char *dest_name)
{
    dbref good_dest[MAX_LINKS];
    int ndest, i;
    struct match_data md;
    char buf[BUFFER_LEN];
    dbref thing, dest;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (Guest(player)) {
        anotify_fmt(player, CFAIL "%s", tp_noguest_mesg);
        return;
    }

    init_match(descr, player, thing_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_registered(&md);

    if (Mage(OWNER(player)))
        match_player(&md);

    if ((thing = noisy_match_result(&md)) == NOTHING)
        return;

    switch (Typeof(thing)) {
        case TYPE_EXIT:
            /* we're ok, check the usual stuff */
            if (DBFETCH(thing)->sp.exit.ndest != 0) {
                if (controls(player, thing)) {
                    if ((DBFETCH(thing)->sp.exit.dest)[0] != NIL) {
                        anotify_nolisten2(player,
                                          CINFO "That exit is already linked.");
                        return;
                    }
                } else {
                    anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                    return;
                }
            }

            /* handle costs */
            if (OWNER(thing) == OWNER(player)) {
                if (!payfor(player, tp_link_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                tp_link_cost,
                                (tp_link_cost == 1) ? tp_penny : tp_pennies);
                    return;
                }
            } else {
                if (!payfor(player, tp_link_cost + tp_exit_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                (tp_link_cost + tp_exit_cost),
                                (tp_link_cost + tp_exit_cost ==
                                 1) ? tp_penny : tp_pennies);
                    return;
                } else if (!Builder(player)) {
                    anotify_nolisten2(player, CFAIL NOBBIT_MESG);
                    return;
                } else {
                    /* pay the owner for his loss */
                    dbref owner = OWNER(thing);

                    DBFETCH(owner)->sp.player.pennies += tp_exit_cost;
                    DBDIRTY(owner);
                }
            }

            /* link has been validated and paid for; do it */
            OWNER(thing) = OWNER(player);

            if (!
                (ndest =
                 link_exit(descr, player, thing, (char *) dest_name,
                           good_dest))) {
                anotify_nolisten2(player, CFAIL "No destinations linked.");
                DBFETCH(player)->sp.player.pennies += tp_link_cost; /* Refund! */
                DBDIRTY(player);
                break;
            }

            DBFETCH(thing)->sp.exit.ndest = ndest;
            if (DBFETCH(thing)->sp.exit.dest)
                free(DBFETCH(thing)->sp.exit.dest);

            DBFETCH(thing)->sp.exit.dest =
                (dbref *) malloc(sizeof(dbref) * ndest);
            for (i = 0; i < ndest; i++)
                (DBFETCH(thing)->sp.exit.dest)[i] = good_dest[i];
            break;
        case TYPE_THING:
        case TYPE_PLAYER:
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_absolute(&md);
            match_registered(&md);
            match_me(&md);
            match_here(&md);
            match_null(&md);

            if (Typeof(thing) == TYPE_THING)
                match_possession(&md);
            if ((dest = noisy_match_result(&md)) == NOTHING)
                return;
	    if (Typeof(thing) == TYPE_THING && dest == NIL) {
                anotify_fmt(player, CFAIL "%s", "You cannot HOME a THING to NIL.");
                return;		
	    }
            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                return;
            }
            if (parent_loop_check(thing, dest)) {
                anotify_nolisten2(player,
                                  CFAIL "That would cause a parent paradox.");
                return;
            }
            /* do the link */
            if (Typeof(thing) == TYPE_THING) {
                DBFETCH(thing)->sp.thing.home = dest;
            } else
                DBFETCH(thing)->sp.player.home = dest;
            sprintf(buf, CSUCC "%s's home set to %s.",
                    NAME(thing), unparse_object(player, dest));
            anotify_nolisten2(player, buf);
            break;
        case TYPE_ROOM:        /* room dropto's */
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_possession(&md);
            match_registered(&md);
            match_absolute(&md);
            match_home(&md);
            match_null(&md);

            if ((dest = noisy_match_result(&md)) == NOTHING)
                break;

            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)
                || (thing == dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
            } else {
                DBFETCH(thing)->sp.room.dropto = dest; /* dropto */
                sprintf(buf, CSUCC "%s's dropto set to %s.",
                        NAME(thing), unparse_object(player, dest));
                anotify_nolisten2(player, buf);
            }

            break;
        case TYPE_PROGRAM:
            anotify_nolisten2(player,
                              CFAIL "You can't link programs to things!");
            break;
        default:
            anotify_nolisten2(player, CFAIL "Weird object type.");
            log_status("*BUG: weird object: Typeof(%d) = %d\n",
                       thing, Typeof(thing));
            break;
    }
    DBDIRTY(thing);
    return;
}
Beispiel #19
0
/** Change an object's owner.
 * \verbatim
 * This implements @chown.
 * \endverbatim
 * \param player the enactor.
 * \param name name of object to change owner of.
 * \param newobj name of new owner for object.
 * \param preserve if 1, preserve privileges and don't halt the object.
 * \param pe_info the pe_info for lock checks
 */
void
do_chown(dbref player, const char *name, const char *newobj, int preserve,
         NEW_PE_INFO *pe_info)
{
  dbref thing;
  dbref newowner = NOTHING;
  long match_flags = MAT_POSSESSION | MAT_HERE | MAT_EXIT | MAT_ABSOLUTE;


  /* check for '@chown <object>/<atr>=<player>'  */
  if (strchr(name, '/')) {
    do_atrchown(player, name, newobj);
    return;
  }
  if (Wizard(player))
    match_flags |= MAT_PLAYER;

  if ((thing = noisy_match_result(player, name, TYPE_THING, match_flags))
      == NOTHING)
    return;

  if (!*newobj || !strcasecmp(newobj, "me")) {
    newowner = player;
  } else {
    if ((newowner = lookup_player(newobj)) == NOTHING) {
      notify(player, T("I couldn't find that player."));
      return;
    }
  }

  if (IsPlayer(thing) && !God(player)) {
    notify(player, T("Players always own themselves."));
    return;
  }
  /* Permissions checking */
  if (!chown_ok(player, thing, newowner, pe_info)) {
    notify(player, T("Permission denied."));
    return;
  }
  if (IsThing(thing) && !Hasprivs(player) &&
      !(GoodObject(Location(thing)) && (Location(thing) == player))) {
    notify(player, T("You must carry the object to @chown it."));
    return;
  }
  if (preserve && !Wizard(player)) {
    notify(player, T("You cannot @CHOWN/PRESERVE. Use normal @CHOWN."));
    return;
  }
  /* chowns to the zone master don't count towards fees */
  if (!ZMaster(newowner)) {
    /* Debit the owner-to-be */
    if (!can_pay_fees(newowner, Pennies(thing))) {
      /* not enough money or quota */
      if (newowner != player)
        notify(player,
               T
               ("That player doesn't have enough money or quota to receive that object."));
      return;
    }
    /* Credit the current owner */
    giveto(Owner(thing), Pennies(thing));
    change_quota(Owner(thing), QUOTA_COST);
  }
  chown_object(player, thing, newowner, preserve);
  notify(player, T("Owner changed."));
}
Beispiel #20
0
/** The oemit(/list) command.
 * \verbatim
 * This implements @oemit and @oemit/list.
 * \endverbatim
 * \param executor The object \@oemit'ing
 * \param speaker The object making the sound (executor, unless /spoof'ing)
 * \param list the list of dbrefs to oemit from the emit.
 * \param message the message to emit.
 * \param flags PEMIT_* flags.
 * \param format a format_msg structure to pass to notify_anything() from \@message
 * \param pe_info the pe_info to use for evaluating speech locks
 */
void
do_oemit_list(dbref executor, dbref speaker, char *list, const char *message,
              int flags, struct format_msg *format, NEW_PE_INFO *pe_info)
{
  char *temp, *p;
  const char *s;
  dbref who;
  dbref room;
  int matched = 0;
  dbref pass[11];
  dbref locs[10];
  int i, oneloc = 0;
  int na_flags = NA_INTER_HEAR | NA_PROPAGATE;

  /* If no message, further processing is pointless.
   * If no list, they should have used @remit. */
  if (!message || !*message || !list || !*list)
    return;

  if (flags & PEMIT_SPOOF)
    na_flags |= NA_SPOOF;

  for (i = 0; i < 11; i++)
    pass[i] = NOTHING;

  /* Find out what room to do this in. If they supplied a db# before
   * the '/', then oemit to anyone in the room who's not on list.
   * Otherwise, oemit to every location which has at least one of the
   * people in the list. This is intended for actions which involve
   * players who are in different rooms, e.g.:
   *
   * X (in #0) fires an arrow at Y (in #2).
   *
   * X sees: You fire an arrow at Y. (pemit to X)
   * Y sees: X fires an arrow at you! (pemit to Y)
   * #0 sees: X fires an arrow at Y. (oemit/list to X Y)
   * #2 sees: X fires an arrow at Y. (from the same oemit)
   */
  /* Find out what room to do this in. They should have supplied a db#
   * before the '/'. */
  if ((temp = strchr(list, '/'))) {
    *temp++ = '\0';
    room = noisy_match_result(executor, list, NOTYPE, MAT_EVERYTHING);
    if (!GoodObject(room)) {
      notify(executor, T("I can't find that room."));
      return;
    }

    if (!Loud(speaker) && !eval_lock_with(speaker, room, Speech_Lock, pe_info)) {
      fail_lock(executor, room, Speech_Lock, T("You may not speak there!"),
                NOTHING);
      return;
    }

    oneloc = 1;                 /* we are only oemitting to one location */
  } else {
    temp = list;
  }

  s = temp;
  while (s && *s) {
    p = next_in_list(&s);
    /* If a room was given, we match relative to the room */
    if (oneloc)
      who = match_result_relative(executor, room, p, NOTYPE, MAT_OBJ_CONTENTS);
    else
      who = noisy_match_result(executor, p, NOTYPE, MAT_OBJECTS);
    /* matched tracks the number of valid players we've found.
     * room is the given room (possibly nothing right now)
     * pass[0..10] are dbrefs of players
     * locs[0..10] are corresponding dbrefs of locations
     * pass[11] is always NOTHING
     */
    if (GoodObject(who) && GoodObject(Location(who))
        && (Loud(speaker) || (oneloc && Location(who) == room) ||
            eval_lock_with(speaker, Location(who), Speech_Lock, pe_info))
      ) {
      if (matched < 10) {
        locs[matched] = Location(who);
        pass[matched] = who;
        matched++;
      } else {
        notify(executor, T("Too many people to oemit to."));
        break;
      }
    }
  }

  if (!matched) {
    if (oneloc) {
      /* A specific location was given, but there were no matching objects to
       * omit, so just remit */
      notify_anything(executor, speaker, na_loc, &room, NULL, na_flags, message,
                      NULL, room, format);
    } else {
      notify(executor, T("No matching objects."));
    }
    return;
  }

  /* Sort the list of rooms to oemit to so we don't oemit to the same
   * room twice */
  qsort((void *) locs, matched, sizeof(locs[0]), dbref_comp);

  for (i = 0; i < matched; i++) {
    if (i != 0 && locs[i] == locs[i - 1])
      continue;
    notify_anything(executor, speaker, na_loc, &locs[i], pass, na_flags,
                    message, NULL, locs[i], format);
  }

}
Beispiel #21
0
void
do_zone(dbref player, dbref cause, int key, char *tname, char *pname)
{
  dbref thing, zonemaster;

  switch( key ) {
    case ZONE_ADD: /* or default */
      if( *tname && !*pname ) {
        init_match(player, tname, NOTYPE);
        match_everything(0);
        thing = noisy_match_result();
        if( thing == NOTHING )
          return;
        if( !Examinable(player, thing) ) {
          notify_quiet(player, "You can't do that.");
          return;
        }
        viewzonelist(player, thing);
        return;
      }
       
      if( !*tname || !*pname ) {
        notify_quiet(player, "This switch expects two arguments.");
        return;
      }
     
      init_match(player, tname, NOTYPE);
      match_everything(0);
      thing = noisy_match_result();
      if( thing == NOTHING )
        return;

      /* Make sure we can do it */

      if ( (NoMod(thing) && !WizMod(player)) ||
           (Backstage(player) && NoBackstage(thing)) ) {
        notify_quiet(player, "Permission denied.");
        return;
      }
      if (!Controls(player, thing)) {
        notify_quiet(player, "Permission denied.");
        return;
      }

      if( ZoneMaster(thing) ) {
        notify_quiet(player, "You can't zone a Zone Master.");
        return;
      }
      /* Find out what the new zone is */

      init_match(player, pname, NOTYPE);
      match_everything(0);
      zonemaster = noisy_match_result();
      if (zonemaster == NOTHING)
        return;
 
      if( !ZoneMaster(zonemaster) ) {
        notify_quiet(player, "That's not a Zone Master.");
        return;
      }

      if(!Controls(player, zonemaster) && 
        !could_doit(player, zonemaster, A_LZONETO, 0, 0) &&
        !could_doit(player, zonemaster, A_LZONEWIZ, 0, 0)) {
        notify_quiet(player, "Permission denied.");
        return;
      }

      if( zlist_inlist(thing, zonemaster) ) {
        notify_quiet(player, "Object is already in that zone.");
        return;
      }

      zlist_add(thing, zonemaster);
      zlist_add(zonemaster, thing);

      notify_quiet(player, "Zone Master added to object.");
      break;
    case ZONE_DELETE:
      if( !*tname || !*pname ) {
        notify_quiet(player, "This switch expects two arguments.");
        return;
      }
      /* Find out what the zone is */

      init_match(player, pname, NOTYPE);
      match_everything(0);
      zonemaster = noisy_match_result();
      if (zonemaster == NOTHING)
        return;
     
      init_match(player, tname, NOTYPE);
      match_everything(0);
      thing = noisy_match_result();
      if( thing == NOTHING )
        return;

      if(!zlist_inlist(thing, zonemaster)) {
        notify_quiet(player, "That is not one of this object's Zone Masters.");
        return;
      }

      /* only need to control zmo or be zonewiz to delete 
         or control object */

      if(!Controls(player, thing) &&
         !Controls(player, zonemaster) && 
         !could_doit(player, zonemaster, A_LZONEWIZ, 0, 0)
         ) {
        notify_quiet(player, "Permission denied.");
        return;
      }

      if ( (NoMod(thing) && !WizMod(player)) ||
           (Backstage(player) && NoBackstage(thing)) ) {
        notify_quiet(player, "Permission denied.");
        return;
      }

      zlist_del(thing, zonemaster);
      zlist_del(zonemaster, thing);

      notify_quiet(player, "Deleted.");
      break;
    case ZONE_PURGE:
      if( !*tname || *pname) {
        notify_quiet(player, "This switch expects one argument.");
        return;
      }
      /* Find out what the zone is */

      init_match(player, tname, NOTYPE);
      match_everything(0);
      thing = noisy_match_result();
      if (thing == NOTHING)
        return;

      if( ZoneMaster(thing) ) {
        if(!Controls(player, thing) && 
          !could_doit(player, thing, A_LZONEWIZ, 0, 0)) {
          notify_quiet(player, "Permission denied.");
          return;
        }
        if ( (NoMod(thing) && !WizMod(player)) ||
             (Backstage(player) && NoBackstage(thing)) ) {
          notify_quiet(player, "Permission denied.");
          return;
        }
        zlist_destroy(thing);
        notify_quiet(player, "All objects removed from zone.");
      }
      else {
        if(!Controls(player, thing)) {
          notify_quiet(player, "Permission denied.");
          return;
        }
        if ( (NoMod(thing) && !WizMod(player)) ||
             (Backstage(player) && NoBackstage(thing)) ) {
          notify_quiet(player, "Permission denied.");
          return;
        }
        zlist_destroy(thing);

        notify_quiet(player, "Object removed from all zones.");
      }
      break;
    default:
      notify_quiet(player, "Unknown switch!");
      break;
  }
  return;
}
Beispiel #22
0
void
match_and_list(int descr, dbref player, const char *name, char *linespec)
{
	dbref thing;
	char *p;
	char *q;
	int range[2];
	int argc;
	struct match_data md;
	struct line *tmpline;

	init_match(descr, player, name, TYPE_PROGRAM, &md);
	match_neighbor(&md);
	match_possession(&md);
	match_registered(&md);
	match_absolute(&md);
	if ((thing = noisy_match_result(&md)) == NOTHING)
		return;
	if (Typeof(thing) != TYPE_PROGRAM) {
		notify(player, "You can't list anything but a program.");
		return;
	}
/*	if (!(controls(player, thing) || Linkable(thing))) { */
	if (!(controls(player, thing) || (FLAGS(thing) & VEHICLE))) {
		notify(player, "Permission denied. (You don't control the program, and it's not set Viewable)");
		return;
	}
	if (!*linespec) {
		range[0] = 1;
		range[1] = -1;
		argc = 2;
	} else {
		q = p = linespec;
		while (*p) {
			while (*p && !isspace(*p))
				*q++ = *p++;
			while (*p && isspace(*++p)) ;
		}
		*q = '\0';

		argc = 1;
		if (isdigit(*linespec)) {
			range[0] = atoi(linespec);
			while (*linespec && isdigit(*linespec))
				linespec++;
		} else {
			range[0] = 1;
		}
		if (*linespec) {
			argc = 2;
			while (*linespec && !isdigit(*linespec))
				linespec++;
			if (*linespec)
				range[1] = atoi(linespec);
			else
				range[1] = -1;
		}
	}
	tmpline = PROGRAM_FIRST(thing);
	PROGRAM_SET_FIRST(thing, read_program(thing));
	do_list(player, thing, range, argc);
	free_prog_text(PROGRAM_FIRST(thing));
	PROGRAM_SET_FIRST(thing, tmpline);
	return;
}
Beispiel #23
0
/*
 * do_dig
 *
 * Use this to create a room.
 */
void
do_dig(int descr, dbref player, const char *name, const char *pname)
{
    char *rname, *qname;
    dbref newparent;
    char rbuf[BUFFER_LEN];
    char qbuf[BUFFER_LEN];
    char buf[BUFFER_LEN];
    dbref room;
    struct match_data md;
    dbref parent;

    if (!Builder(player) && !tp_all_can_build_rooms) {
        anotify_nolisten2(player, CFAIL NOBBIT_MESG);
        return;
    }

    if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    }

    if (*name == '\0') {
        anotify_nolisten2(player, CINFO "You need name for the room.");
        return;
    }

    if (!ok_name(name)) {
        anotify_nolisten2(player, CINFO "That's a silly name for a room!");
        return;
    }

    if (!payfor(player, tp_room_cost)) {
        anotify_fmt(player, CFAIL "You don't have enough %s to dig a room.",
                    tp_pennies);
        return;
    }
    room = new_object(player);

    /* Initialize everything */
    newparent = DBFETCH(DBFETCH(player)->location)->location;
    while ((OkObj(newparent)) && !(FLAGS(newparent) & ABODE)
           && !(FLAG2(newparent) & F2PARENT))
        newparent = DBFETCH(newparent)->location;
    if (!OkObj(newparent)) {
        if (OkObj(tp_default_parent))
            newparent = tp_default_parent;
        else
            newparent = GLOBAL_ENVIRONMENT;
    }

    NAME(room) = alloc_string(name);
    DBFETCH(room)->location = newparent;
    OWNER(room) = OWNER(player);
    DBFETCH(room)->exits = NOTHING;
    DBFETCH(room)->sp.room.dropto = NOTHING;
    FLAGS(room) = TYPE_ROOM | (FLAGS(player) & JUMP_OK);
    PUSH(room, DBFETCH(newparent)->contents);
    DBDIRTY(room);
    DBDIRTY(newparent);

    sprintf(buf, CSUCC "Room %s created.", unparse_object(player, room));
    anotify_nolisten2(player, buf);

    strcpy(buf, pname);
    for (rname = buf; (*rname && (*rname != '=')); rname++) ;
    qname = rname;
    if (*rname)
        *(rname++) = '\0';
    while ((qname > buf) && (isspace(*qname)))
        *(qname--) = '\0';
    qname = buf;
    for (; *rname && isspace(*rname); rname++) ;
    rname = strcpy(rbuf, rname);
    qname = strcpy(qbuf, qname);

    if (*qname) {
        anotify_nolisten2(player, CNOTE "Trying to set parent...");
        init_match(descr, player, qname, TYPE_ROOM, &md);
        match_absolute(&md);
        match_registered(&md);
        match_here(&md);
        if ((parent = noisy_match_result(&md)) == NOTHING
            || parent == AMBIGUOUS) {
            anotify_nolisten2(player, CINFO "Parent set to default.");
        } else {
            if ((!can_link_to(player, Typeof(room), parent)
                 && !(FLAG2(parent) & F2PARENT)) || room == parent) {
                anotify_nolisten2(player,
                                  CFAIL
                                  "Permission denied.  Parent set to default.");
            } else {
                moveto(room, parent);
                sprintf(buf, CSUCC "Parent set to %s.",
                        unparse_object(player, parent));
                anotify_nolisten2(player, buf);
            }
        }
    }

    if (*rname) {
        PData pdat;

        sprintf(buf, "_reg/%s", rname);
        pdat.flags = PROP_REFTYP;
        pdat.data.ref = room;
        set_property(player, buf, &pdat);
        sprintf(buf, CINFO "Room registered as $%s", rname);
        anotify_nolisten2(player, buf);
    }
}
Beispiel #24
0
void 
do_link(dbref player, dbref cause, int key, char *what, char *where)
{
    dbref thing, room;
    char *buff;
    int nomtest;

    if ( (key & SIDEEFFECT) && !SideFX(player) ) {
       notify(player, "#-1 FUNCTION DISABLED");
       return;
    }

    /* Find the thing to link */

    init_match(player, what, TYPE_EXIT);
    match_everything(0);
    thing = noisy_match_result();
    if (thing == NOTHING)
	return;

    nomtest = ((NoMod(thing) && !WizMod(player)) || (DePriv(player,Owner(thing),DP_MODIFY,POWER7,NOTHING) && (Owner(thing) != Owner(player))) || (Backstage(player) && NoBackstage(thing) && !Immortal(player)));
    /* Allow unlink if where is not specified */

    if (!where || !*where) {
      if (!nomtest)
	do_unlink(player, cause, key, what);
      else
	notify(player,"Permission denied.");
      return;
    }
    switch (Typeof(thing)) {
    case TYPE_EXIT:

	/* Set destination */

	room = parse_linkable_room(player, where);
	if (room != NOTHING) {
	  if (!nomtest)
	    link_exit(player, thing, room, key);
	  else
	    notify(player,"Permission denied.");
	}
	break;
    case TYPE_PLAYER:
    case TYPE_THING:

	/* Set home */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	init_match(player, where, NOTYPE);
	match_everything(MAT_NO_EXITS);
	room = noisy_match_result();
	if (!Good_obj(room))
	    break;
	if (!Has_contents(room)) {
	    notify_quiet(player, "Can't link to an exit.");
	    break;
	}
	if (!can_set_home(player, thing, room) ||
	    !could_doit(player, room, A_LLINK, 1, 0)) {
	    notify_quiet(player, "Permission denied.");
	} else if (room == HOME) {
	    notify_quiet(player, "Can't set home to home.");
	} else {
	    s_Home(thing, room);
	    if (!(Quiet(player) || (key & SIDEEFFECT)) )
		notify_quiet(player, "Home set.");
	}
	break;
    case TYPE_ROOM:

	/* Set dropto */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	room = parse_linkable_room(player, where);
	if (!Good_obj(room) && (room != HOME)) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}

	if ((room != HOME) && !isRoom(room)) {
	    notify_quiet(player, "That is not a room!");
	} else if ((room != HOME) &&
		   ((!controls(player, room) && !Link_ok(room)) ||
		    !could_doit(player, room, A_LLINK, 1, 0))) {
	    notify_quiet(player, "Permission denied.");
	} else {
	    s_Dropto(thing, room);
	    if (!Quiet(player))
		notify_quiet(player, "Dropto set.");
	}
	break;
    default:
	STARTLOG(LOG_BUGS, "BUG", "OTYPE")
	    buff = alloc_mbuf("do_link.LOG.badtype");
	sprintf(buff, "Strange object type: object #%d = %d",
		thing, Typeof(thing));
	log_text(buff);
	free_mbuf(buff);
	ENDLOG
    }
}
Beispiel #25
0
void do_notify
(
    dbref executor,
    dbref caller,
    dbref enactor,
    int   key,
    int   nargs,
    char *what,
    char *count
)
{
    UNUSED_PARAMETER(caller);
    UNUSED_PARAMETER(enactor);
    UNUSED_PARAMETER(nargs);

    char *obj = parse_to(&what, '/', 0);
    init_match(executor, obj, NOTYPE);
    match_everything(0);

    dbref thing = noisy_match_result();
    if (!Good_obj(thing))
    {
        return;
    }
    if (!Controls(executor, thing) && !Link_ok(thing))
    {
        notify(executor, NOPERM_MESSAGE);
    }
    else
    {
        int atr = A_SEMAPHORE;
        if (  what
           && what[0] != '\0')
        {
            int i = mkattr(executor, what);
            if (0 < i)
            {
                atr = i;
                if (atr != A_SEMAPHORE)
                {
                    // Do they have permission to set this attribute?
                    //
                    ATTR *ap = (ATTR *)anum_get(atr);
                    if (!bCanSetAttr(executor, thing, ap))
                    {
                        notify_quiet(executor, NOPERM_MESSAGE);
                        return;
                    }
                }
            }
        }

        int loccount;
        if (  count
           && count[0] != '\0')
        {
            loccount = mux_atol(count);
        }
        else
        {
            loccount = 1;
        }
        if (loccount > 0)
        {
            nfy_que(thing, atr, key, loccount);
            if (  (!(Quiet(executor) || Quiet(thing)))
               && key != NFY_QUIET)
            {
                if (key == NFY_DRAIN)
                {
                    notify_quiet(executor, "Drained.");
                }
                else
                {
                    notify_quiet(executor, "Notified.");
                }
            }
        }
    }
}
Beispiel #26
0
// ---------------------------------------------------------------------------
// do_wait: Command interface to wait_que
//
void do_wait
(
    dbref executor,
    dbref caller,
    dbref enactor,
    int   eval,
    int key,
    char *event,
    char *cmd,
    char *cargs[],
    int ncargs
)
{
    CLinearTimeAbsolute ltaWhen;
    CLinearTimeDelta    ltd;

    // If arg1 is all numeric, do simple (non-sem) timed wait.
    //
    if (is_rational(event))
    {
        if (key & WAIT_UNTIL)
        {
            ltaWhen.SetSecondsString(event);
        }
        else
        {
            ltaWhen.GetUTC();
            ltd.SetSecondsString(event);
            ltaWhen += ltd;
        }
        wait_que(executor, caller, enactor, eval, true, ltaWhen, NOTHING, 0,
            cmd,
            ncargs, cargs,
            mudstate.global_regs);
        return;
    }

    // Semaphore wait with optional timeout.
    //
    char *what = parse_to(&event, '/', 0);
    init_match(executor, what, NOTYPE);
    match_everything(0);

    dbref thing = noisy_match_result();
    if (!Good_obj(thing))
    {
        return;
    }
    else if (!Controls(executor, thing) && !Link_ok(thing))
    {
        notify(executor, NOPERM_MESSAGE);
    }
    else
    {
        // Get timeout, default 0.
        //
        int atr = A_SEMAPHORE;
        bool bTimed = false;
        if (event && *event)
        {
            if (is_rational(event))
            {
                if (key & WAIT_UNTIL)
                {
                    ltaWhen.SetSecondsString(event);
                }
                else
                {
                    ltaWhen.GetUTC();
                    ltd.SetSecondsString(event);
                    ltaWhen += ltd;
                }
                bTimed = true;
            }
            else
            {
                ATTR *ap = atr_str(event);
                if (!ap)
                {
                    atr = mkattr(executor, event);
                    if (atr <= 0)
                    {
                        notify_quiet(executor, "Invalid attribute.");
                        return;
                    }
                    ap = atr_num(atr);
                }
                else
                {
                    atr = ap->number;
                }
                if (!bCanSetAttr(executor, thing, ap))
                {
                    notify_quiet(executor, NOPERM_MESSAGE);
                    return;
                }
            }
        }

        int num = add_to(thing, 1, atr);
        if (num <= 0)
        {
            // Thing over-notified, run the command immediately.
            //
            thing = NOTHING;
            bTimed = false;
        }
        wait_que(executor, caller, enactor, eval, bTimed, ltaWhen, thing, atr,
            cmd,
            ncargs, cargs,
            mudstate.global_regs);
    }
}
Beispiel #27
0
void
do_dequeue(int descr, dbref player, const char *arg1)
{
	char buf[BUFFER_LEN];
	int count;
	dbref match;
	struct match_data md;
	timequeue tmp, ptr = tqhead;


	if (*arg1 == '\0') {
		notify_nolisten(player, "What event do you want to dequeue?", 1);
	} else {
		if (!string_compare(arg1, "all")) {
			if (!Wizard(OWNER(player))) {
				notify_nolisten(player, "Permission denied", 1);
				return;
			}
			while (ptr) {
				tmp = ptr;
				tqhead = ptr = ptr->next;
				free_timenode(tmp);
				process_count--;
			}
			tqhead = NULL;
			muf_event_dequeue(NOTHING, 0);
			notify_nolisten(player, "Time queue cleared.", 1);
		} else {
			if (!number(arg1)) {
				init_match(descr, player, arg1, NOTYPE, &md);
				match_absolute(&md);
				match_everything(&md);

				match = noisy_match_result(&md);
				if (match == NOTHING) {
					notify_nolisten(player, "I don't know what you want to dequeue!", 1);
					return;
				}
				if (!valid_objref(match)) {
					notify_nolisten(player, "I don't recognize that object.", 1);
					return;
				}
				if ((!Wizard(OWNER(player))) && (OWNER(match) != OWNER(player))) {
					notify_nolisten(player, "Permission denied.", 1);
					return;
				}
				count = dequeue_prog(match, 0);
				if (!count) {
					notify_nolisten(player, "That program wasn't in the time queue.", 1);
					return;
				}
				if (count > 1) {
					snprintf(buf, sizeof(buf), "%d processes dequeued.", count);
				} else {
					snprintf(buf, sizeof(buf), "Process dequeued.");
				}
				notify_nolisten(player, buf, 1);
			} else {
				if ((count = atoi(arg1))) {
					if (!(control_process(player, count))) {
						notify_nolisten(player, "Permission denied.", 1);
						return;
					}
					if (!(dequeue_process(count))) {
						notify_nolisten(player, "No such process!", 1);
						return;
					}
					process_count--;
					notify_nolisten(player, "Process dequeued.", 1);
				} else {
					notify_nolisten(player, "What process do you want to dequeue?", 1);
				}
			}
		}
	}
	return;
}