muse1.7b4/
muse1.7b4/config/
muse1.7b4/doc/
muse1.7b4/run/
muse1.7b4/run/db/
muse1.7b4/src/
muse1.7b4/src/db/
muse1.7b4/src/files/
muse1.7b4/src/io/
muse1.7b4/src/prog/
muse1.7b4/src/util/
/* Wizard-only commands */
/* $Id: admin.c,v 1.11 1993/09/18 19:03:38 nils Exp $ */

#include "db.h"
#include "config.h"

#include "interface.h"
#include "match.h"
#include "externs.h"
#include "credits.h"

#include "admin.h"
#include "player.h"

#define  ANY_OWNER	-2

/* local function declarations */
static object_flag_type convert_flags P((dbref player, int is_wizard, char *s, object_flag_type *, object_flag_type *));

/* added 12/1/90 by jstanley to add @search command details in file game.c */
/* Ansi: void do_search(dbref player, char *arg1, char *arg3); */
void do_search(player, arg1, arg3)
     dbref player;
     char *arg1;
     char *arg3;
{
  int flag;
  char *arg2;
  dbref thing;
  dbref from;
  dbref to;
  int destitute = 1;
  char *restrict_name;
  dbref restrict_owner;
  dbref restrict_link;
  int restrict_zone;
  object_flag_type flag_mask;
  object_flag_type restrict_type;
  object_flag_type restrict_class;
  char buf[3100];
  extern char *str_index();
  
  /* parse first argument into two */
  arg2 = str_index(arg1, ' ');
  if ( arg2 != NULL )
    *arg2++ = '\0';		/* arg1, arg2, arg3 */
  else  {
    if ( *arg3 == '\0' )
      arg2 = "";		/* arg1 */
    else  {
      arg2 = arg1;	/* arg2, arg3 */
      arg1 = "";
    }
  }
  
  /* set limits on who we search */
  restrict_owner = NOTHING;
  if ( *arg1 == '\0' )
    restrict_owner = power(player,POW_EXAMINE) ? ANY_OWNER : player;
  else if ( arg1[0] == '#' )  {
    restrict_owner = atoi(&arg1[1]);
    if ( restrict_owner < 0 || db_top <= restrict_owner )
      restrict_owner = NOTHING;
    else if ( Typeof(restrict_owner) != TYPE_PLAYER )
      restrict_owner = NOTHING;
  }
  else if ( strcmp(arg1, "me") == 0 )
    restrict_owner = player;
  else
    restrict_owner = lookup_player(arg1);
  
  if ( restrict_owner == NOTHING )  {
    notify(player, tprintf("%s: No such player", arg1));
    return;
  }
  
  /* set limits on what we search for */
  flag = 0;
  flag_mask = 0;
  restrict_name = NULL;
  restrict_type = NOTYPE;
  restrict_link = NOTHING;
  restrict_zone = NOTHING;
  restrict_class = 0;
  switch (arg2[0])  {
  case '\0':
    /* the no class requested class  :)  */
    break;
  case 'c':
    if ( string_prefix("class", arg2)) {
      restrict_class=name_to_class(arg3);
      if(!restrict_class || !power(player,POW_WHO)) {
	notify(player,"unknown class!");
	return;
      }
      restrict_type=TYPE_PLAYER;
    } else flag=1;
    /*    if(restrict_class==TYPE_DIRECTOR && !power(player,TYPE_ADMIN))
	  restrict_class=TYPE_ADMIN;
	  if(restrict_class==TYPE_JUNIOR && !power(player,TYPE_ADMIN))
	  restrict_class=TYPE_OFFICIAL;*/
    break;
  case 'e':
    if ( string_prefix("exits", arg2) )  {
      restrict_name = arg3;
      restrict_type = TYPE_EXIT;
    }
    else flag = 1;
    break;
  case 'f':
    if ( string_prefix("flags", arg2) )  {
      /* convert_flags ignores previous values of
	 flag_mask and restrict_type while setting them */
      if ( ! convert_flags(player, power(player,POW_EXAMINE), arg3, /* power?XXX */
			   &flag_mask, &restrict_type) )
	return;
    }
    else flag = 1;
    break;
  case 'l':
    if(string_prefix("link",arg2)) {
      if((restrict_link=match_thing(player,arg3))==NOTHING)
	flag=1;
    } else flag=1;
    break;
  case 'n':
    if ( string_prefix("name", arg2) )
      restrict_name = arg3;
    else flag = 1;
    break;
  case 'o':
    if ( string_prefix("objects", arg2) )  {
      restrict_name = arg3;
      restrict_type = TYPE_THING;
    }
    else flag = 1;
    break;
  case 'p':
    if ( string_prefix("players", arg2) )  {
      restrict_name = arg3;
      if ( *arg1 == '\0' )
	restrict_owner = ANY_OWNER;
      restrict_type = TYPE_PLAYER;
    }
    else flag = 1;
    break;
  case 'r':
    if ( string_prefix("rooms", arg2) )  {
      restrict_name = arg3;
      restrict_type = TYPE_ROOM;
    }
    else flag = 1;
    break;
  case 't':
    if ( string_prefix("type", arg2) )  {
      if ( arg3[0] == '\0' )
	break;
      if ( string_prefix("room", arg3) )
	restrict_type = TYPE_ROOM;
      else if ( string_prefix("exit", arg3) )
	restrict_type = TYPE_EXIT;
      else if ( string_prefix("thing", arg3) )
	restrict_type = TYPE_THING;
      else if ( string_prefix("player", arg3) )  {
	if ( *arg1 == '\0' )
	  restrict_owner = ANY_OWNER;
	restrict_type = TYPE_PLAYER;
      }
      else  {
	notify(player, tprintf("%s: unknown type", arg3));
	return;
      }
    }
    else flag = 1;
    break;
  case 'z':
    if (string_prefix ("zone", arg2))
      if ((restrict_zone =match_thing(player,arg3))==NOTHING)
	flag = 1;
      else
	restrict_type = TYPE_ROOM;
    else flag=1;
    break;
  default:
    flag = 1;
  }
  if ( flag )  {
    notify(player, tprintf("%s: unknown class", arg2));
    return;
  }
  
  if (restrict_owner != ANY_OWNER)
    if (!controls (player, restrict_owner, POW_EXAMINE)) {
      notify(player, "You need a search warrant to do that!");
      return;
    }
  if (restrict_owner == ANY_OWNER && restrict_type != TYPE_PLAYER)
    if (!power (player, POW_EXAMINE)) {
      notify (player,"You need a search warrant to do that!");
      return;
    }
  
  /* make sure player has money to do the search */
  if ( ! payfor(player, SEARCH_COST) )  {
    notify(player, tprintf("Searches cost %d credits", SEARCH_COST));
    return;
  }
  
  /* room search */
  if ( restrict_type == TYPE_ROOM || restrict_type == NOTYPE )  {
    flag = 1;
    for ( thing = 0; thing < db_top; thing++ )  {
      if ( Typeof(thing) != TYPE_ROOM )
	continue;
      if ( restrict_owner != ANY_OWNER &&
	  restrict_owner != db[thing].owner )
	continue;
      if ( (db[thing].flags & flag_mask) != flag_mask )
	continue;
      if ( restrict_name != NULL )  {
	if ( ! string_prefix(db[thing].name, restrict_name) )
	  continue;
      }
      if (restrict_zone != NOTHING)
	if (restrict_zone != db[thing].zone)
	  continue;
      if(restrict_link != NOTHING && db[thing].link != restrict_link)
	continue;
      if ( flag )  {
	flag = 0;
	destitute = 0;
	notify(player, "");	/* aack! don't use a newline! */
	notify(player, "ROOMS:");
      }
      notify(player, unparse_object(player, thing));
    }
  }
  
  /* exit search */
  if ( restrict_type == TYPE_EXIT || restrict_type == NOTYPE )  {
    flag = 1;
    for ( thing = 0; thing < db_top; thing++ )  {
      if ( Typeof(thing) != TYPE_EXIT )
	continue;
      if ( restrict_owner != ANY_OWNER &&
	  restrict_owner != db[thing].owner )
	continue;
      if ( (db[thing].flags & flag_mask) != flag_mask )
	continue;
      if ( restrict_name != NULL )
	if ( ! string_prefix(db[thing].name, restrict_name) )
	  continue;
      if(restrict_link != NOTHING && db[thing].link != restrict_link)
	continue;
      
      if ( flag )  {
	flag = 0;
	destitute = 0;
	notify(player, "");	/* aack! don't use a newline! */
	notify(player, "EXITS:");
      }
      from = find_entrance(thing);
      to   = db[thing].link;
      strcpy(buf, unparse_object(player, thing));
      strcat(buf, " [from ");
      strcat(buf,
	     from == NOTHING ? "NOWHERE" : unparse_object(player, from));
      strcat(buf, " to ");
      strcat(buf,
	     to   == NOTHING ? "NOWHERE" : unparse_object(player,   to));
      strcat(buf, "]");
      notify(player, buf);
    }
  }
  
  /* object search */
  if ( restrict_type == TYPE_THING || restrict_type == NOTYPE )  {
    flag = 1;
    for ( thing = 0; thing < db_top; thing++ )  {
      if ( Typeof(thing) != TYPE_THING )
	continue;
      if(!(flag_mask&GOING)) /* we're not searching for going things */
	if ( db[thing].flags & GOING && !*atr_get(thing,A_DOOMSDAY) )  /* in case of free object */
	  continue;
      if ( restrict_owner != ANY_OWNER &&
	  restrict_owner != db[thing].owner )
	continue;
      if ( (db[thing].flags & flag_mask) != flag_mask )
	continue;
      if ( restrict_name != NULL )
	if ( ! string_prefix(db[thing].name, restrict_name) )
	  continue;
      if(restrict_link != NOTHING && db[thing].link != restrict_link)
	continue;
      
      if ( flag )  {
	flag = 0;
	destitute = 0;
	notify(player, "");	/* aack! don't use a newline! */
	notify(player, "OBJECTS:");
      }
      strcpy(buf, unparse_object(player, thing));
      strcat(buf, " [owner: ");
      strcat(buf, unparse_object(player, db[thing].owner));
      strcat(buf, "]");
      notify(player, buf);
    }
  }
  
  /* player search */
  if ( restrict_type == TYPE_PLAYER ||
      ( power(player,POW_EXAMINE) && restrict_type == NOTYPE ) )  {
    flag = 1;
    for ( thing = 0; thing < db_top; thing++ )  {
      if ( Typeof(thing) != TYPE_PLAYER )
	continue;
      if ( (db[thing].flags & flag_mask) != flag_mask )
	continue;
      /* this only applies to wizards on this option */
      if ( power(player,POW_EXAMINE) )
	if ( restrict_owner != ANY_OWNER &&
	    restrict_owner != db[thing].owner )
	  continue;
      if ( restrict_name != NULL )
	if ( ! string_prefix(db[thing].name, restrict_name) )
	  continue;
      if ( restrict_class != 0 )
	if ((!db[thing].pows) || db[thing].pows[0] != restrict_class)
	  continue;
      if(restrict_link != NOTHING && db[thing].link != restrict_link)
	continue;
      if ( flag )  {
	flag = 0;
	destitute = 0;
	notify(player,"");	/* aack! don't use newlines! */
	notify(player, "PLAYERS:");
      }
      strcpy(buf, unparse_object(player, thing));
      if ( controls(player,thing,POW_EXAMINE) ) {
	strcat(buf, " [location: ");
	strcat(buf, unparse_object(player, db[thing].location));
	strcat(buf, "]");
      }
      notify(player, buf);
    }
  }
  
  /* if nothing found matching search criteria */
  if ( destitute )
    notify(player, "Nothing found.");
}

static object_flag_type convert_flags(player, is_wizard, s, p_mask, p_type)
     dbref player;
     int is_wizard;
     char *s;
     object_flag_type *p_mask;
     object_flag_type *p_type;
{
  static struct {
    int id, type;
    object_flag_type bits;
  } fdata[] = {
    {'G',NOTYPE,GOING},{'p',NOTYPE,PUPPET},{'I',NOTYPE,INHERIT_POWERS},
    {'S',NOTYPE,STICKY},{'D',NOTYPE,DARK},{'L',NOTYPE,LINK_OK},
    {'H',NOTYPE,HAVEN},{'C',NOTYPE,CHOWN_OK},{'e',NOTYPE,ENTER_OK},
    {'s',TYPE_PLAYER,PLAYER_SLAVE},{'n',TYPE_PLAYER, PLAYER_NEWBIE},
    {'c',TYPE_PLAYER,PLAYER_CONNECT},{'K',TYPE_THING,THING_KEY},
    {'d',TYPE_THING,THING_DEST_OK},/*{'r',TYPE_THING,THING_ROBOT},*/
    {'T',TYPE_ROOM,ROOM_TEMPLE},{'J',TYPE_ROOM,ROOM_JUMP_OK},
    {'R',TYPE_ROOM,0},{'E',TYPE_EXIT,0},{'P',TYPE_PLAYER,0},
    /*{'U',NOTYPE,UNIVERSAL},*/{'v',NOTYPE,SEE_OK},
    /*{'h',TYPE_PLAYER,PLAYER_HIDE},*/{'t',TYPE_PLAYER,PLAYER_TERSE},
    {'o',NOTYPE,OPAQUE},{'q',NOTYPE,QUIET},{'f',TYPE_ROOM,ROOM_FLOATING},
    {'N',TYPE_PLAYER,PLAYER_NO_WALLS},{'m',TYPE_PLAYER,PLAYER_MORTAL},
    {'X',TYPE_THING,THING_SACROK},{'l',TYPE_THING,THING_LIGHT},
    {'l',TYPE_ROOM,EXIT_LIGHT},{'b',NOTYPE, BEARING},
    {'A',TYPE_ROOM,ROOM_AUDITORIUM},
#ifdef USE_SPACE /* Flag added by Michael Majere */
    {'Z',TYPE_ROOM,ROOM_ZEROG},
#endif
    {0,0,0}
  };
  
  int i;
  int last_id=' ';
  object_flag_type mask, type;
  
  mask = 0;
  type = NOTYPE;
  for (; *s != '\0'; s++ )  {
    /* tmp patch to stop hidden cheating */
    if ( *s == 'c' && ! is_wizard )
      continue;
    
    for ( i = 0; fdata[i].id != 0; i++ )  {
      if ( *s == fdata[i].id )  {
	/* handle object specific flag problems */
	if ( fdata[i].type != NOTYPE )  {
	  /* make sure we aren't specific to a different type */
	  if ( type != NOTYPE && type != fdata[i].type )  {
	    notify(player,
		   tprintf("Flag '%c' conflicts with '%c'.",
			   last_id, fdata[i].id));
	    return 0;
	  }
	  
	  /* make us object specific to this type */
	  type = fdata[i].type;
	  
	  /* always save last specific flag id */
	  last_id = *s;
	}
	
	/* add new flag into search mask */
	mask |= fdata[i].bits;
	
	/* stop searching for *this* flag */
	break;
      }
    }
    
    /* flag not found */
    if ( fdata[i].id == 0 )  {
      notify(player, tprintf("%c: unknown flag", (int) *s));
      return 0;
    }
  }
  
  /* return new mask and type */
  *p_mask = mask;
  *p_type = type;
  return 1;
}
/* Ansi: void do_register_purge(dbref player); */
void do_register_purge(player)
     dbref player;
{
  int type;
  dbref thing;
  
  if ( player != GOD )
    return;
  
  notify(player, " ");
  notify(player, "Working...");
  notify(player, " ");
  for ( thing = 0; thing < db_top; thing++ )
    if(Typeof(thing)==TYPE_PLAYER) {
      type = Levnm(thing);
      if ( type == CLASS_GUEST || type == CLASS_VISITOR )  {
	notify(player, tprintf("Destroying %s(#%d)",
			       db[thing].name, thing));
	destroy_player(thing);
      }
    }
  notify(player, " ");
  notify(player, "Done!");
}

/* Ansi: void do_teleport(dbref player, char *arg1, char *arg2); */
void do_teleport(player,arg1,arg2)
     dbref player;
     char *arg1;
     char *arg2;
{
  dbref victim;
  dbref destination;
  char *to;
  
  /* get victim, destination */
  if(*arg2 == '\0') {
    victim = player;
    to = arg1;
  } else {
    init_match(player, arg1, NOTYPE);
    match_neighbor();
    match_possession();
    match_me();
    match_absolute();
    match_player();
    match_exit();
    
    if ( (victim = noisy_match_result()) == NOTHING )
      return;
    to = arg2;
  }
  
  /* get destination */
  if(string_compare(to,"home")) {
    init_match(player, to, TYPE_PLAYER);
    match_here();
    match_absolute();
    match_neighbor();
    match_me();
    match_player();
    match_exit();
    destination = match_result();
  } else {
    destination=HOME;
  }
  switch(destination) {
  case NOTHING:
    notify(player,tprintf("I don't know where %s is.",to));
    break;
  case AMBIGUOUS:
    notify(player, tprintf("I don't know which %s you mean!",to));
    break;
  case HOME:
    if ( Typeof(victim) != TYPE_PLAYER && Typeof(victim) != TYPE_THING) {
      notify(player,tprintf("Can't touch %s.",to));
      return;
    }
    if ( controls(player,victim,POW_TELEPORT) ||
	controls(player,db[victim].location,POW_TELEPORT) ) {
      /* replace above 2 lines with IS() macro? */
      notify(victim,"You feel a sudden urge to leave this place and go home...");
      safe_tel(victim,destination);
      return;                     
    }
    notify(player,"Permission denied.");
    return;
  default:
    /* check victim, destination types, teleport if ok */
    if(Typeof(victim)==TYPE_ROOM) {
      notify(player,"Can't move rooms!");
      return;
    }
    if((Typeof(victim)==TYPE_EXIT &&
	(Typeof(destination)==TYPE_PLAYER ||
	 Typeof(destination)==TYPE_EXIT)) ||
       (Typeof(victim)==TYPE_PLAYER &&
	Typeof(destination)==TYPE_PLAYER)) {
      notify(player,"Bad destination.");
      return;
    }
    
    if ( Typeof(destination) != TYPE_EXIT ) {
      if ((controls(player,victim,POW_TELEPORT) ||
	   controls(player,db[victim].location,POW_TELEPORT)) &&
	  (Typeof(victim)!=TYPE_EXIT || controls(player,destination,
						 POW_MODIFY)) &&
	  (controls(player,destination,POW_TELEPORT) ||
	   IS(destination,TYPE_ROOM,ROOM_JUMP_OK))) {
	if (!check_zone(player,victim,destination,1)) { 
	  return;
	} else {
	  did_it(victim,get_zone_first(victim),A_LEAVE,NULL,A_OLEAVE,NULL,A_ALEAVE);
	  safe_tel(victim,destination);
	  did_it(victim,get_zone_first(victim),A_ENTER,NULL,A_OENTER,NULL,A_AENTER);
	  return;
	}
	safe_tel(victim,destination);
	return;                     
      }
      notify(player,"Permission denied.");
      return;
    }
    else  {  /* dest is TYPE_EXIT */
      if ( controls(player,db[victim].location,POW_TELEPORT) ||
	  controls(player,victim,POW_TELEPORT) || power(player,POW_TELEPORT) )
	if(((controls(player,db[victim].location,POW_TELEPORT) ||
	     controls(player,victim,POW_TELEPORT))
	    && controls(player,destination,POW_TELEPORT))
	   || power(player,POW_TELEPORT))
	  do_move(victim,to);
	else
	  notify(player,"Permission denied.");
    }
  }
}

/* Note: special match, link_ok objects are considered
   controlled for this purpose */
dbref match_controlled(player,name,cutoff_level)
     dbref player;
 char *name;
     int cutoff_level;
{
  dbref match;
  
  init_match(player, name, NOTYPE);
  match_everything();
  
  match = noisy_match_result();
  if(match != NOTHING && !controls(player, match, cutoff_level)) {
    notify(player, "Permission denied.");
    return NOTHING;
  } else {
    return match;
  }
}
/* Ansi: void do_force(dbref player,char *what,char *command); */
void do_force(player,what,command)
     dbref player;
     char *what;
     char *command;
{
  dbref victim;
  
  if ((victim=match_controlled(player,what,POW_MODIFY))==NOTHING) {
    notify(player,"Sorry.");
    return;
  }                        
  
  /*  if ((Typeof(victim)==TYPE_ROOM) || (Typeof(victim)==TYPE_EXIT)) {
      notify(player,"You can only force players and things.");
      return;
      }*/

#ifdef GOD_PRIV
  if ( victim == GOD )  {
    notify(player,"You can't force god!!");
    return;
  }
#endif
  /* force victim to do command */
  parse_que(victim,command,player);
}
/* Ansi: int try_force(dbref player, char *command); */
int try_force(player,command)
     dbref player;
 char *command;
{                                   
  char buff[1024];
  dbref thing;
  char *s;
  /* first see if command prefixed by object # */
  if (*command=='#')
    {         
      strcpy(buff,command);
      for(s=buff;*s && *s!=' ';s++);
      if (!*s)
	return(0);
      *s++=0;
    }       
  else
    /* try inventory */
    if (((thing=pref_match(player,db[player].contents,command))!=NOTHING) ||
	( (db[player].location!=NOTHING) && 
	 ((thing=pref_match(player,db[db[player].location].contents,command))!=NOTHING)))
      {                    
	strcpy(buff,command);
	s=buff+strlen(db[thing].name);
	if (!*s)
	  return(0);
	*s++=0;
      }       
    else
      return(0);
  do_force(player,buff,s);
  return(1);
}
/* Ansi: void do_stats(dbref player, char *name); */
void do_stats(player,name)
     dbref player;
 char *name;
{
  extern char *type_to_name();
  dbref owner;
  int i, total;
  int obj[NUM_OBJ_TYPES];
  int pla[NUM_CLASSES];
  
  /* Patched 12/9/90 */
  if ( *name == '\0' )
    owner = ANY_OWNER;
  else if ( *name == '#' )  {
    owner = atoi(&name[1]);
    if ( owner < 0 || db_top <= owner )
      owner = NOTHING;
    else if ( Typeof(owner) != TYPE_PLAYER )
      owner = NOTHING;
  }
  else if ( strcmp(name, "me") == 0 )
    owner = player;
  else
    owner = lookup_player(name);
  if ( owner == NOTHING )  {
    notify(player, tprintf("%s: No such player", name));
    return;
  }
  if ( ! has_pow(player, owner, POW_STATS) )
    if ( owner != ANY_OWNER && owner != player )  {
      notify(player, "You need a search warrant to do that!");
      return;
    }
  
  calc_stats(owner, &total, obj, pla);
  notify(player, tprintf("%s Database Breakdown:", MUSE_NAME));
  notify(player, tprintf("%7d Total Objects", total));
  for ( i = 0; i < NUM_OBJ_TYPES; i++ )
    if(type_to_name(i) && *type_to_name(i) != ' ')
      notify(player, tprintf("%7d %ss", obj[i], type_to_name(i)));
  notify(player, tprintf("%7d %ss",
			 pla[CLASS_CITIZEN], class_to_name(CLASS_CITIZEN)));
  
#ifdef TEST_MALLOC
  if ( power(player, TYPE_HONWIZ) )  {
    /*    sprintf(buf, "Malloc count = %d.", malloc_count);*/
    notify(player, tprintf("Malloc count = %d.",malloc_count));
  }
#endif /* TEST_MALLOC */
}
/* Ansi: void do_pstats(dbref player, char *name); */
void do_pstats(player, name)
     dbref player;
 char *name;
{
  dbref owner;
  int i, total;
  int obj[NUM_OBJ_TYPES];  /* number of object types */
  int pla[NUM_CLASSES];
  
  if ( *name == '\0' )
    owner = ANY_OWNER;
  else {
    notify(player, tprintf("%s: No such player", name));
    return;
  }
  
  if ( ! power(player, POW_STATS) ) {
    notify(player, "Maybe next time. Sorry!");
    return;
  }
  
  calc_stats(owner, &total, obj, pla);
  notify(player, tprintf("%s Player Breakdown:", MUSE_NAME));
  notify(player, tprintf("%7d Players", obj[TYPE_PLAYER]));
  for(i=1;i<NUM_CLASSES;i++)
    notify(player,tprintf("%7d %ss", pla[i], class_to_name(i)));
}
/* Ansi: void calc_stats(dbref owner,int *total,int *players,int count[NUM_OBJ_TYPES]); */
void calc_stats(owner, total, obj, pla)
     dbref owner;
     register int *total;
     int obj[NUM_OBJ_TYPES];
     int pla[NUM_CLASSES];
{
  int i;
  dbref thing;
  
  /* zero out count stats */
  *total = 0;
  for ( i = 0; i < NUM_OBJ_TYPES; i++ )
    obj[i] = 0;
  for(i=0;i<NUM_CLASSES;i++)
    pla[i]=0;

  for(thing = 0; thing < db_top; thing++)
    if(owner == ANY_OWNER || owner == db[thing].owner)
      if(!(db[thing].flags&GOING)) {
	++obj[Typeof(thing)];
	if(Typeof(thing)==TYPE_PLAYER)
	  ++pla[*db[thing].pows];
	++*total;
      }
}
/* Ansi: int owns_stuff(dbref player); */
int owns_stuff(player)
     dbref player;
{
  dbref i;
  int matches = 0;
  
  for (i = 0; i < db_top; i++) {
    if (db[i].owner == player && i != player) matches++;
  }
  return matches;
}
/* Ansi: void do_wipeout(dbref player,char *arg1,char *arg3); */
void do_wipeout(player, arg1, arg3)
     dbref player;
     char *arg1;
     char *arg3;
{
  char *arg2;
  int type;
  dbref victim;
  dbref n;
  int do_all = 0;
  
  if (!power(player, POW_SECURITY)) {
    notify(player, "Sorry, only wizards may perform mass destruction.");
    return;
  }
  
  log_sensitive(tprintf("%s tries @wipeout %s=%s",unparse_object(player,player),arg1,arg3));
  
  for(arg2 = arg1; *arg2 && *arg2 != ' '; arg2++);
  if (!*arg2) {
    notify(player, "You must specify the object type to destroy.");
    return;
  }
  *arg2 = '\0';
  arg2++;
  if (strcmp(arg2, "type")) {
    notify(player, "The syntax is \"@wipeout <player> type=<obj type>\".");
    return;
  }
  victim = lookup_player(arg1);
  if (victim == NOTHING) {
    notify(player, "No idea.. who's that?");
    return;
  }
  if (!controls(player, victim, POW_MODIFY)) {
    notify(player, "permission denied! quit that!");
    return;
  }
  if (string_prefix("objects", arg3)) type = TYPE_THING;
  else if (string_prefix("rooms", arg3)) type = TYPE_ROOM;
  else if (string_prefix("exits", arg3)) type = TYPE_EXIT;
  else if (!strcmp("all", arg3)) {
    do_all = 1; type = NOTYPE;
  } else {
    notify(player, "Unknown type.");
    return;
  }
  for(n = 0; n < db_top; n++) {
    if ((db[n].owner == victim && n != victim) &&
	(Typeof(n) == type || do_all)) {
      destroy_obj (n, 60);	/* destroy in 1 minute */
    }
  }
  switch (type) {
  case TYPE_THING:
    notify(player, "Wiped out all objects.");
    notify(victim, tprintf("All your objects have been destroyed by %s.",
			   unparse_object (victim, player)));
    break;
  case TYPE_ROOM:
    notify(player, "Wiped out all rooms.");
    notify(victim, tprintf("All your rooms have been destroyed by %s.",
			   unparse_object (victim, player)));
    break;
  case TYPE_EXIT:
    notify(player, "Wiped out all exits.");
    notify(victim, tprintf("All your exits have been destroyed by %s.",
			   unparse_object(victim, player)));
    break;
  case NOTYPE:
    notify(player, "Wiped out every blessed thing.");
    notify(victim, tprintf("All your stuff has been repossessed by %s. Oh, well.",
			   unparse_object (victim, player)));
    break;
  }
}
/* Ansi: void do_chownall(dbref player,char *arg1,char *arg2); */
void do_chownall(player,arg1,arg2)
     dbref player;
     char *arg1;
     char *arg2;
{
  dbref playerA;
  dbref playerB;
  dbref n;
  
  if (!power(player, POW_SECURITY)) {
    notify(player, "Sorry, only wizards may mass chown.");
    return;
  }
  log_sensitive(tprintf("%s tries @chownall %s=%s",unparse_object(player,player),arg1,arg2));
  init_match(player, arg1, TYPE_PLAYER);
  match_neighbor();
  match_player();
  if ((playerA = noisy_match_result()) != NOTHING) {
    init_match(player, arg2, TYPE_PLAYER);
    match_neighbor();
    match_player();
    if ((playerB = noisy_match_result()) != NOTHING) {
      for (n = 0; n < db_top; n++) {
	if (db[n].owner == playerA && n != playerA) {
	  db[n].owner = playerB;
	}
      }
    }
  }
  notify(player, "Owner changed.");
}
/* Ansi: void do_poor(dbref player,char *arg1); */
void do_poor(player,arg1)
     dbref player;
     char *arg1;
{
  dbref a;
  int amt = atoi(arg1);
  
  if ( player != GOD )
    return;
  for ( a=0; a < db_top; a++)
    if ( Typeof(a) == TYPE_PLAYER )
      s_Pennies(a, amt);
}
/* Ansi: void do_allquota(dbref player,char *arg1); */
void do_allquota(player, arg1)
     dbref player;
     char *arg1;
{
  int count, limit, owned;
  char buf[20];
  dbref who, thing;
  
  if ( player != GOD ) {
    notify(player,"Don't. @allquota isn't nice.");
    return;
  }
  
  count = 0;
  notify(player, "working...");
  for ( who = 0; who < db_top; who++ )  {
    if ( Typeof(who) != TYPE_PLAYER )
      continue;
    
    /* count up all owned objects */
    owned = -1;  /* a player is never included in his own quota */
    for ( thing = 0; thing < db_top; thing++ )  {
      if ( db[thing].owner == who )
	if ((db[thing].flags&(TYPE_THING|GOING)) != (TYPE_THING|GOING))
	  ++owned;
    }
    
    limit = atoi(arg1);
    
    /* stored as a relative value */
    sprintf(buf, "%d", limit - owned);
    atr_add(who, A_RQUOTA, buf);
    sprintf(buf, "%d", limit);
    atr_add(who, A_QUOTA, buf);
    ++count;
  }
  notify(player, tprintf("done (%d players processed).", count));
}
/* Ansi: void do_newpassword(dbref player, char *name, char *password); */
void do_newpassword(player,name,password)
     dbref player;
 char *name;
 char *password;
{
  dbref victim;
  
  if((victim = lookup_player(name)) == NOTHING || Typeof(victim)!=TYPE_PLAYER) {
    notify(player, tprintf("%s: no such player.",name));
  } else if(Typeof(player)!=TYPE_PLAYER || !has_pow(player,victim,POW_NEWPASS)) {
    notify(player, "Permission denied.");
    return;
  } else if(*password != '\0' && !ok_password(password)) {
    /* Wiz can set null passwords, but not bad passwords */
    notify(player, "Bad password");
#ifdef GOD_PRIV
  } else if ( victim == GOD && player != GOD ) {
    notify(player, "You cannot change that player's password.");
#endif /* GOD_PRIV */
  } else {
    /* it's ok, do it */        
    s_Pass(victim,password);
    notify(player, "Password changed.");
    log_sensitive(tprintf("%s(%d) executed: @newpassword %s(#%d)=%s",
			  db[player].name, player, db[victim].name, victim, password));
    notify(victim, tprintf("Your password has been changed by %s.",
			   db[player].name));
  }
}
/* Ansi: void do_boot(dbref player,char *name); */
void do_boot(player,name)
     dbref player;
 char *name;
{
  dbref victim;
  
  /* player only - no inherited powers */
  
  init_match(player, name, TYPE_PLAYER);
  match_neighbor();
  match_absolute();
  match_player();
  if((victim = noisy_match_result()) == NOTHING)
    return;
  if(!has_pow(player,victim,POW_BOOT)) {
    notify(player,"Permission denied");
    return;
  }
#ifdef GOD_PRIV
  if( victim == GOD ) {
    notify(player, "You can't boot GOD!");
    return;
  }
#endif /* GOD_PRIV */
  
  if ( Typeof(victim) != TYPE_PLAYER )
    notify(player, "You can only boot off other players!");
  else {
    /* notify people */
    notify(player, tprintf("%s - Booted.", db[victim].name));
    boot_off(victim);
    log_sensitive(tprintf("%s(#%d) executed: @boot %s(#%d)",
			  db[player].name, player, db[victim].name, victim));
    notify (victim, tprintf("You have been booted by %s.",unparse_object (victim, player)));
  }
}
/* Ansi: void do_join(dbref player,char *arg1); */
void do_join(player,arg1)
     dbref player;
 char *arg1;
{
  dbref victim;
  dbref to;
  
  /* get victim, destination */
  victim = player;
  to = lookup_player(arg1);
  
  if ( ! controls(victim, to, POW_JOIN) && !controls(victim, db[to].location, POW_JOIN)) {
    notify(player, "Sorry. You don't have wings.");
    return;
  }
  
  if ( to == NOTHING )  {
    notify(player, tprintf("%s: no such player.",arg1));
    return;
  }
  
  moveto(victim, db[to].location);
}

/* Ansi: void do_summon(dbref player, char *arg1); */
void do_summon(player,arg1)
     dbref player;
 char *arg1;
{
  dbref victim;
  dbref dest;
  
  /* get victim, destination */
  dest = db[player].location;
  victim = lookup_player(arg1);
  
  if ( ! controls(player, victim,POW_SUMMON) && !controls(player, db[victim].location, POW_SUMMON)) {
    notify(player,"Sorry. That player doesn't have wings.");
    return;
  }
  
  if ( victim == NOTHING )  {
    notify(player,tprintf("%s: no such player",arg1));
    return;
  }
  
  moveto(victim, dest);
}