dmuck0.15-beta/docs/muf/
dmuck0.15-beta/game/
dmuck0.15-beta/game/logs/
dmuck0.15-beta/game/muf/
dmuck0.15-beta/game/muf/text/
#include "copyright.h"
#include "config.h"
#include "mush.h"
#include <sys/time.h>
#include <sys/resource.h>

#include "db.h"
#include "params.h"
#include "interface.h"
#include "match.h"
#include "externs.h"
#include "money.h"

extern time_t time_started;
extern frame *frame_list;
static char buf[BUFFER_LEN];

void do_backlinks(__DO_PROTO)
{
  dbref object;
  dbref_list *drl;
  match_data md;
  
  /* get victim, destination */
  if(*arg1 == '\0') object = player;
  else
  {
    init_match(player, arg1, NOTYPE, &md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_player(&md);
    
    if((object = noisy_match_result(&md)) == NOTHING) return;
  }
  
  if (!controls(player, object))
  {
    notify(player, player, "Permission denied.");
    return;
  }
  notify(player, player, "Backlinks:");
  for(drl = DBFETCH(object)->backlinks; drl; drl = drl->next)
    notify(player, player, unparse_object(player, drl->object));
}

void do_backlocks(__DO_PROTO)
{
  dbref object;
  dbref_list *drl;
  match_data md;
  
  /* get victim, destination */
  if(*arg1 == '\0') object = player;
  else
  {
    init_match(player, arg1, NOTYPE, &md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_player(&md);
    
    if((object = noisy_match_result(&md)) == NOTHING) return;
  }
  
  if (!controls(player, object))
  {
    notify(player, player, "Permission denied.");
    return;
  }

  notify(player, player, "Backlocks:");
  for(drl = DBFETCH(object)->backlocks; drl; drl = drl->next)
    notify(player, player, unparse_object(player, drl->object));
}

void do_teleport(__DO_PROTO)
{
  dbref victim;
  dbref destination;
  dbref loc;
  char *to;
  match_data md;
  
  /* get victim, destination */
  if(*arg2 == '\0')
  {
    victim = player;
    to = arg1;
  }
  else
  {
    init_match(player, arg1, NOTYPE, &md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_player(&md);
    
    if((victim = noisy_match_result(&md)) == NOTHING) return;
    to = arg2;
  }

  if(Typeof(victim) == TYPE_EXIT) {
     notify(player, player, "Permission denied.  Use @attach instead.");
     return;
   }

  /* get destination */
  init_match(player, to, NOTYPE, &md);
  match_here(&md);
  match_home(&md);
  match_absolute(&md);
  match_neighbor(&md);
  match_me(&md);
  if(Wizard(player)) match_player(&md);

  destination = match_result(&md);

  switch(destination)
  {
    case NOTHING:
      notify(player, player, "Send it where?");
      return;
    case AMBIGUOUS:
      notify(player, player, "I don't know which destination you mean!");
      return;
    case HOME:
      destination = DBFETCH(victim)->link;
  }

  if (parent_loop_check(victim, destination))
  {
    notify(player, player, "Permission denied.");
    return;
  }

 if(Typeof(victim) == TYPE_GARBAGE) {
    notify(player,player,"Can't teleport garbage.");
    return;
  }                        
  
  if (((FLAGS(player) & WIZARD) ||
    ((can_link_to(player, NOTYPE, destination) ||
    (FLAGS(destination) & JUMP_OK)) &&
    controls(player, victim))) &&
    Typeof(destination) != TYPE_PROGRAM)
  {
    notify(victim, victim, "You feel a wrenching sensation...");
#ifdef MUSH
    loc = DBFETCH(victim)->location;
    did_it(victim, victim, NULL, NULL, "OXTPORT", NULL, NULL, loc);
#endif
    switch (Typeof(victim))
    {
      case TYPE_THING:
      case TYPE_PROGRAM:
        /* check for non-sticky dropto */
        if((Typeof(destination) == TYPE_ROOM) &&
	  (DBFETCH(destination)->link != NOTHING) &&
	  !(FLAGS(destination) & STICKY))
          destination = DBFETCH(destination)->link;
      default:
        enter_room(victim, destination, DBFETCH(victim)->location);
#ifdef MUSH
	did_it(victim, victim, "TPORT", NULL, "OTPORT", NULL, "ATPORT",
		 DBFETCH(destination)->location);
#endif
        notify(player, player, "Teleported.");
    }
  }
  else {
#ifdef MUSH
	did_it(player, destination, "EFAIL", "Permission denied.", 
	       "OEFAIL", NULL, "AEFAIL", DBFETCH(player)->location);
#else
       notify(player, player, "Permission denied.");
#endif
  }
}

void do_force(__DO_PROTO)
{
  dbref victim;
  match_data md;
  
  if(*arg1 == '\0') victim = player;
  else
  {
    init_match(player, arg1, NOTYPE, &md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_player(&md);
    
    if((victim = noisy_match_result(&md)) == NOTHING) return;
  }
  
  if (!controls(player, victim))
  {
    notify(player, player, "Permission denied.");
    return;
  }
  
  if (!arg2 || !*arg2) return;
  log_status("FORCED: %s(%ld) by %s(%ld): %s\n", NAME(victim),
    victim, NAME(player), player, arg2);
  /* force victim to do command */
 if(Typeof(victim) == TYPE_PLAYER)  {
    sprintf (buf, "%s forced you to type %s.", unparse_name(player), arg2);
    notify (victim, victim, buf);
  }

  if(Typeof(victim) == TYPE_PLAYER)
  {
 if(o_notify_wiz) {
    sprintf (buf, "%s forced ", unparse_name(player));
    strcat(buf, unparse_name(victim));
    strcat(buf, ":");
    strcat(buf, arg2);
    notify_wizards(buf);
    }
  }
#ifdef MUSH
  mush_interp =1;
  process_command(victim, arg2, victim);
  mush_interp =0;
#else
  process_command(victim, arg2, victim);
#endif
}

void do_stats(__DO_PROTO)
{
  int rooms = 0, exits = 0, things = 0, players = 0, programs = 0,
      total = 0, garbage = 0, frames = 0;
  frame *fr;
  dbref i, obj;
  match_data md;
  int pid, psize;
#ifdef HAVE_GETRUSAGE 
  struct rusage usage;
#endif
  char *sitename;

  if (strlen(arg1))
  {
    init_match(player, arg1, NOTYPE, &md);
    match_all_exits(&md);
    match_neighbor(&md);
    match_possession(&md);
    if(Wizard(player))
    {
      match_absolute(&md);
      match_player(&md);
    }
    match_here(&md);
    match_me(&md);

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

    if (!controls(player, obj))
    {
      notify (player, player, "Permission denied.");
      return;
    }

    switch (Typeof(obj))
    {
      case TYPE_PLAYER:
        for(i = obj; i != NOTHING; i = DBFETCH(i)->nextowned)
        {
	  total++;
          switch(Typeof(i))
          {
            case TYPE_ROOM:
              rooms++;
              break;
            case TYPE_EXIT:
              exits++;
              break;
            case TYPE_THING:
              things++;
              break;
            case TYPE_PLAYER:
              players++;
              break;
            case TYPE_PROGRAM:
	      programs++;
              break;
            case TYPE_GARBAGE:
	      garbage++;
              break;
          }
        }

	for (fr = frame_list, frames = 0; fr; fr = fr->next)
	{
	  if (fr->player == obj) frames++;
	}

        sprintf (buf, "Stats for %s:", unparse_name(obj));
        notify(player, player, buf);

        sprintf(buf," Rooms   : (%6.2f%%) %5d   Exits    : (%6.2f%%) %5d",
		DO_PERCENT(rooms),DO_PERCENT(exits));
        notify(player, player, buf);

        sprintf(buf," Things  : (%6.2f%%) %5d   Programs : (%6.2f%%) %5d",
		DO_PERCENT(things),DO_PERCENT(programs));
        notify(player, player, buf);

        sprintf(buf," Players : (%6.2f%%) %5d   Processes: (       ) %5d",
		DO_PERCENT(players), frames);
        notify(player, player, buf);

        sprintf(buf," Garbage : (%6.2f%%) %5d   Total    : (100.00%%) %5d",
		DO_PERCENT(garbage),total);
        notify(player, player, buf);

        notify(player, player, " ");
        break;
    }
#ifdef TIMESTAMPS
    sprintf(buf,"CREATED       : %s",
      asctime(localtime(&DBFETCH(obj)->time_created)));
    buf[strlen(buf)-1] = '\0';
    notify(player, player, buf);

    sprintf(buf,"LAST MODIFIED : %s",
      asctime(localtime(&DBFETCH(obj)->time_modified)));
    buf[strlen(buf)-1] = '\0';
    notify(player, player, buf);

    sprintf(buf,"LAST USED     : %s",
      asctime(localtime(&DBFETCH(obj)->time_used)));
    buf[strlen(buf)-1] = '\0';
    notify(player, player, buf);
#endif
  }
  else
  {
    for (i = 0; i < db_top; i++)
    {
      switch(Typeof(i))
      {
        case TYPE_ROOM: total++; rooms++; break;
        case TYPE_EXIT: total++; exits++; break;
        case TYPE_THING: total++; things++;
          break;
        case TYPE_PLAYER: total++; players++;
          break;
        case TYPE_PROGRAM: total++; programs++; break;
        case TYPE_GARBAGE: total++; garbage++; break;
      }
    }
    for (fr = frame_list, frames = 0; fr; fr = fr->next, frames++);
    sprintf(buf, "%s stats:", (sitename =
      get_property_data((dbref) 0, RWHO_NAME, ACCESS_WI)) ?
      sitename : "Universe");
    notify(player, player, buf);

    sprintf(buf, " Rooms   : (%6.2f%%) %5d   Exits    : (%6.2f%%) %5d",
		DO_PERCENT(rooms),DO_PERCENT(exits));
    notify(player, player, buf);

    sprintf(buf, " Things  : (%6.2f%%) %5d   Programs : (%6.2f%%) %5d",
		DO_PERCENT(things),DO_PERCENT(programs));
    notify(player, player, buf);

    sprintf(buf, " Players : (%6.2f%%) %5d   Processes: (       ) %5d",
		DO_PERCENT(players), frames);
    notify(player, player, buf);

    sprintf(buf, " Garbage : (%6.2f%%) %5d   Total    : (100.00%%) %5d",
		DO_PERCENT(garbage),total);
    notify(player, player, buf);

    notify(player, player, " ");
  
    sprintf(buf,"Up since: %s", asctime(localtime(&time_started)));
    buf[strlen(buf)-1] = '\0';
    notify(player, player, buf);
    
    if (Wizard(player))
    {
      pid=getpid();
#ifdef HAVE_GETPAGESIZE
      psize=getpagesize();
#endif
        sprintf(buf, "Peak number of players...........%d", maxplayer);
	notify(player, player, buf);
	sprintf(buf, "Process ID.......................%ld", pid);
	notify(player, player, buf);
#ifdef HAVE_GETRUSAGE 
      if(getrusage(RUSAGE_SELF, &usage) != -1)
      {
	sprintf(buf, "User time used (CPU secs)........%ld.%ld",
          usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 10000);
	notify(player, player, buf);
	sprintf(buf, "System time used(CPU secs).......%ld.%ld",
          usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 10000);
	notify(player, player, buf);
#ifdef HAVE_GETPAGESIZE
	sprintf(buf, "Resident memory (bytes)..........%ld",
          usage.ru_maxrss * psize);
	notify(player, player, buf);
#endif
	sprintf(buf, "Page faults (No I/O).............%ld", usage.ru_minflt);
	notify(player, player, buf);
	sprintf(buf, "Page faults (I/O)................%ld", usage.ru_majflt);
	notify(player, player, buf);
	sprintf(buf, "Swapped..........................%ld", usage.ru_nswap);
	notify(player, player, buf);
	sprintf(buf, "Input services...................%ld", usage.ru_inblock);
	notify(player, player, buf);
	sprintf(buf, "Output services..................%ld", usage.ru_oublock);
	notify(player, player, buf);
	sprintf(buf, "Messages/Bytes sent..............%ld/%ld", 
                usage.ru_msgsnd, 0);
	notify(player, player, buf);
	sprintf(buf, "Messages/Bytes received..........%ld/%ld", 
                usage.ru_msgrcv, 0);
	notify(player, player, buf);
	sprintf(buf, "Signals received.................%ld", usage.ru_nsignals);
	notify(player, player, buf);
	sprintf(buf, "Voluntarily context switches.....%ld", usage.ru_nvcsw);
	notify(player, player, buf);
	sprintf(buf, "Involuntarily context switches...%ld", usage.ru_nivcsw);
	notify(player, player, buf);
      }
#endif
    }
  }
}

void do_boot(__DO_PROTO)
{
  dbref victim;
  match_data md;
  
  init_match(player, arg1, TYPE_PLAYER, &md);
  match_neighbor(&md);
  match_me(&md);
  match_absolute(&md);
  match_player(&md);
  
  victim = last_match_result(&md);
  victim = (victim == NOTHING) ? lookup_player(arg1) : victim;

  if (victim == NOTHING)
  {
    notify(player, player, "That player does not exist.");
    return;
  }

  if(!controls(player, victim) || (Typeof(victim) != TYPE_PLAYER))
  {
    notify(player, player, "Permission denied.");
    return;
  }

  sprintf (buf, "You have been booted off of the game by %s.",
    unparse_name(player));
  notify(victim, victim, buf);
  if (boot_off(victim))
  {
 if(o_notify_wiz) {
    sprintf (buf, "%s booted ", unparse_name(player));
    strcat (buf, unparse_name(victim));
    strcat (buf, ".");
    notify_wizards(buf);
  }
    log_status("BOOTED: %s(%ld) by %s(%ld)\n", NAME(victim),
      victim, NAME(player), player);
    if (victim != player)
    {
      sprintf(buf, "You booted %s off!", unparse_name(victim));
      notify(player, player, buf);
    }
  }
  else
  {
    sprintf(buf, "%s is not connected.", unparse_name(victim));
    notify(player, player, buf);
  }
}

void toad(dbref player, dbref recipient)
{
  dbref stuff;
  dbref_list *list, *tmp;

  boot_off(player);

  /* change ownership on all the stuff */
  for (stuff = player; stuff != NOTHING; stuff = DBFETCH(stuff)->nextowned)
  {
    DBSTORE(stuff, owner, recipient);
  }

  for(stuff = recipient; DBFETCH(stuff)->nextowned != NOTHING;
    stuff = DBFETCH(stuff)->nextowned);
  DBSTORE(stuff, nextowned, player);

  /* link all objects now linked to the player to the recipient */
  while (DBFETCH(player)->backlinks &&
    ((Typeof(DBFETCH(player)->backlinks->object)) == TYPE_THING))
  {
    tmp = DBFETCH(player)->backlinks;
    DBSTORE(player, backlinks, tmp->next);
    DBSTORE(tmp->object, link, recipient);
    add_backlinks(tmp->object);
    free(tmp);
  }

  for (list = DBFETCH(player)->backlinks; list && list->next; list = list->next)
  {
    if (Typeof(list->next->object) == TYPE_THING)
    {
      tmp = list->next;
      list->next = tmp->next;
      DBSTORE(tmp->object, link, recipient);
      add_backlinks(tmp->object);
      free(tmp);
    }
  }

  /* and now send all objects currently on the player to their home */
  send_contents(player, HOME);

  /* may as well reclaim the password property */

  if(DBFETCH(player)->sp.player.password)
  {
    free(DBFETCH(player)->sp.player.password);
    DBSTORE(player, sp.player.password, NULL);
  }

  /* thou art now a toad!  ZZZzzzzzZZap! */
  FLAGS(player) = TYPE_THING;

  /* make the toad an invaluable object */
  DBFETCH(player)->pennies = 1;
    
  /* remove the player from the hash table */
  delete_player(player);

  /* change the name */
  sprintf(buf, "a slimy toad named %s", unparse_name(player));
  free(NAME(player));
  DBSTORE(player, name, dup_string(buf));
}

void do_toad(__DO_PROTO)
{
  dbref victim;
  dbref recipient;
  match_data md;
  
  init_match(player, arg1, NOTYPE, &md);
  match_neighbor(&md);
  match_possession(&md);
  match_me(&md);
  match_here(&md);
  match_absolute(&md);
  match_player(&md);
  victim = last_match_result(&md);
  victim = (victim == NOTHING) ? lookup_player(arg1) : victim;

  if(victim == NOTHING) {
    notify(player, player, "No such player.");
    return;
  }

#ifdef GOD_PRIV
  if (!(FLAGS(player) & GOD))
  {
    notify(player, player, "Permission denied.");
    return;
  }
#endif

  if ((Typeof(victim) != TYPE_PLAYER) || (!controls(player, victim)) ||
    (player == victim)) {
    notify(player, player, "Permission denied.");
    return;
  }

  if (!*arg2) recipient = NOTHING;
  else
  {
    init_match(player, arg2, NOTYPE, &md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_player(&md);
    recipient = last_match_result(&md);
    recipient = (recipient == NOTHING) ? lookup_player(arg2) : recipient;
  }

  if (recipient == NOTHING)
  {
    notify(player, player, "Recipient not found...making you recipient.");
    recipient = player;
  }

  if ((Typeof(recipient) != TYPE_PLAYER) || (!controls(player, recipient)))
  {
    notify(player, player, "Permission denied.");
    return;
  }
  
  if(Wizard(victim))
  {
    notify(player, player, "You can't turn a Wizard into a toad.");
    return;
  }

  /* notify people */
  sprintf (buf, "You have been turned into a toad by %s!",
    unparse_name(player));
  notify(victim, victim, buf);
  sprintf(buf, "You turned %s into a toad!", unparse_name(victim));
  notify(player, player, buf);

 if(o_notify_wiz) {
    sprintf (buf, "%s toaded ", unparse_name(player));
    strcat(buf, unparse_name(victim));
    strcat(buf, ".");
    notify_wizards(buf);
 }

  log_status("TOADED: %s(%ld) by %s(%ld)\n", NAME(victim), victim,
    NAME(player), player);
  toad(victim, recipient);
}

void do_trimdb(__DO_PROTO)
{
  dbref old_db_top = db_top;

  if (!(Wizard(player)))
  {
    notify_nolisten(player, "Permission denied.");
  } else {
    for ( db_top--; Typeof(db_top) == TYPE_GARBAGE; db_top-- );
    db_top++;
    sprintf(buf, "Trimming database from %d to %d.", old_db_top, db_top);
    notify_nolisten(player,buf);
  }
}

void do_newpassword(__DO_PROTO)
{
  dbref victim;
  match_data md;
  
  init_match(player, arg1, NOTYPE, &md);
  match_neighbor(&md);
  match_possession(&md);
  match_me(&md);
  match_here(&md);
  match_absolute(&md);
  match_player(&md);
  victim = last_match_result(&md);
  victim = (victim == NOTHING) ? lookup_player(arg1) : victim;
  if ((Typeof(victim) != TYPE_PLAYER) || !Wizard(player))
  {
    notify(player, player, "Permission denied.");
    return;
  }
  
  /* nuke .last property on player */
  add_property(player, ".last", "@newpassword", default_perms(".last"),
    ACCESS_CO);

  if(!ok_password(arg2))
  {
    notify(player, player, "Bad password.");
    return;
  }

  if(DBFETCH(victim)->sp.player.password)
    free(DBFETCH(victim)->sp.player.password);

  DBSTORE(victim, sp.player.password, make_password(arg2));

  notify(player, player, "Password changed.");
  sprintf(buf, "Your password has been changed by %s.",
    unparse_name(player));
  notify(victim, victim, buf);

 if(o_notify_wiz) {
    sprintf (buf, "%s newpassworded ", unparse_name(player));
    strcat(buf, unparse_name(victim));
    strcat(buf, ".");
    notify_wizards(buf);
 }

  log_status("NEWPASS'ED: %s(%ld) by %s(%ld)\n", NAME(victim), victim,
    NAME(player), player);
}

void do_pcreate(__DO_PROTO)
{
  dbref newguy;
  
  if (!(FLAGS(player) & 
#ifdef GOD_PRIV
    GOD))
#else
    WIZARD))
#endif
  {
    notify(player, player, "Permission denied.");
    return;
  }
  
  newguy = create_player(arg1, arg2, player);
  if (newguy == NOTHING) notify(player, player, "Create failed.");
  else
  {
    add_property(player, ".last", "@pcreate", default_perms(".last"),
      ACCESS_CO);

 if(o_notify_wiz) {
    sprintf(buf, "%s has created player ", unparse_name(player));
    strcat(buf, unparse_name(newguy));
    notify_wizards(buf);
    log_status("PCREATED %s(%ld) by %s(%ld)\n",
               NAME(newguy), newguy, NAME(player), player);
    sprintf(buf,"Player %s created as object #%ld.", NAME(newguy), newguy);
    notify(player, player, buf);
  }
if(o_player_user_functions) {
  FLAGS(newguy) |= NOCOMMAND;
  DBDIRTY(newguy);
   }
  }
}

void do_login(__DO_PROTO)        /* Allow/Disallow logins in the server     */
{                                /* Quick function done by Howard  Feel     */
 if(!Wizard(player)) {           /* free to fancy it up as much as you like */
    notify(player, player, "Permission denied.");
    return;
   }

  if (!strncmp (argall, "off", 3)) {
        wiz_only_flag = 1;
        notify(player, player, "Non Wizard logins have been DISABLED.");
     }   
  else if (!strncmp (argall, "on", 2)) {
        wiz_only_flag = 0;
        notify(player, player, "Non Wizard logins are now ENABLED.");
     }   
  else {
        if(wiz_only_flag == 1)
          notify(player, player, "Non Wizard login are currently DISABLED.");
        else
          notify(player, player, "Non Wizard login are currently ENABLED.");
     }   
}     

void do_reset(__DO_PROTO)
{
    if(Wizard(player)) { 
      notify(player, player, "Resetting lists.  This will take a moment.");
      reset_lists();
      notify(player, player, "Done.");
    } else
        notify(player, player, "Permission denied.");
}

#ifdef USE_DBP
void do_db_sync(__DO_PROTO)
{
  if (!(God(player))) 
    notify_nolisten(player, "Permission denied.");
  else {
    notify_nolisten(player, "Synchronizing the cache to disk......");
    dbp_sync();
  }
}

void do_db_flush(__DO_PROTO)
{
  if (!(God(player)))
    notify_nolisten(player, "Permission denied.");
  else {
    notify_nolisten(player, "Flushing the cache and updating the disk.....");
    dbp_flush();
  }
}
#endif