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 "prims.h"
#include "db.h"
#include "interface.h"
#include "match.h"
#include "params.h"
#include "externs.h"
#include "money.h"
#include "mush.h"
#include <ctype.h>

/* Commands which involve speaking */

int blank(char *s);
static char buf[BUFFER_LEN];

void do_say(__DO_PROTO)
{
  dbref loc;
  
  if((loc = getloc(player)) == NOTHING) return;
  
  /* notify everybody */
  sprintf(buf, "You say, \"%s\"", argall);
  notify(player, player, buf);
  sprintf(buf, "%s says, \"%s\"", unparse_name(player), argall);
  notify_except(player, loc, player, buf);
}

void do_whisper(__DO_PROTO)
{
  dbref who;
  match_data md;
  
  init_match(player, arg1, TYPE_PLAYER, &md);
  match_neighbor(&md);
  match_me(&md);
  if(Wizard(player))
  {
    match_absolute(&md);
    match_player(&md);
  }
  switch(who = match_result(&md))
  {
    case NOTHING:
      notify(player, player, "Whisper to whom?");
      break;
    case AMBIGUOUS:
      notify(player, player, "I don't know who you mean!");
      break;
    default:
      sprintf(buf, "%s whispers, \"%s\"", unparse_name(player), arg2);
      if (!notify(player, who, buf))
      {
        sprintf(buf, "%s is not connected.", unparse_name(who));
        notify(player, player, buf);
        break;
      }
      sprintf(buf, "You whisper, \"%s\" to %s.", arg2, unparse_name(who));
      notify(player, player, buf);
      break;
  }
}

void do_pose(__DO_PROTO)
{
  dbref loc;
  
  if((loc = getloc(player)) == NOTHING) return;
  
  /* notify everybody */
  sprintf(buf, "%s %s", unparse_name(player), argall);
  notify_except(player, loc, NOTHING, buf);
}

void notify_wizards(char *message)
{
  descriptor_data *d;
  
  for(d = descriptor_list; d; d = d->next)
  {
    if (d->connected && Wizard(d->player) && (FLAGS(d->player) & MUCKER))
    {
      queue_string(d, message);
      queue_write(d, "\r\n", 2);
    }
  }
}

void do_wall(__DO_PROTO)
{
  descriptor_data *d;
  
  if (!argall || !*argall) return;
  if(Wizard(player))
  {
    log_status("WALL from %s(%d): %s\n", NAME(player), player, argall);
    sprintf (buf, "%s shouts, \"%s\"", unparse_name(player), argall);
    for(d = descriptor_list; d; d = d->next)
    {
      if (d->connected)
      {
        queue_string(d, buf);
        queue_write(d, "\r\n", 2);
      }
    }
  }
  else notify(player, player, "Permission denied.");
}

void do_gripe(__DO_PROTO)
{
  dbref loc;
  char buff[BUFFER_LEN];
  
  if (!argall || !*argall) return;
  loc = DBFETCH(player)->location;

 if(o_notify_wiz) {
    sprintf(buff, "GRIPE entered from %s(%d) in %s(%d): %s",
           NAME(player), player, NAME(loc), loc, argall);
    notify_wizards (buf);
 }
  log_gripe("%s\n", buff);
  notify(player, player, "Your complaint has been duly noted.");
}

/* doesn't really belong here, but I couldn't figure out where else */
void do_page(__DO_PROTO)
{
  dbref target;
  
  if((target = lookup_player(arg1)) == NOTHING)
  {
    notify(player, player, "I don't recognize that name.");
    return;
  }
  if (FLAGS(target) & HAVEN)
  {
    notify(player, player, "That player does not wish to be disturbed.");
    return;
  }
  if (blank(arg2))
  {
    sprintf(buf, "You sense that %s is looking for you in ",
      unparse_name(player));
    strcat(buf, unparse_name(DBFETCH(player)->location));
  }
  else
  {
    sprintf(buf, "%s pages from ", unparse_name(player));
    strcat(buf, unparse_name(DBFETCH(player)->location));
    strcat(buf, ": \"");
    strcat(buf, arg2);
    strcat(buf, "\"");
  }
  if (notify(player, target, buf))
    notify(player, player, "Your message has been sent.");
  else
  {
    sprintf(buf, "%s is not connected.", unparse_name(target));
    notify(player, player, buf);
  }
}

void spawn_listener(dbref player, dbref source, dbref program, dbref location,
  char *msg)
{
  frame *fr;
  if (Typeof(program) != TYPE_PROGRAM) return;

  strcpy(match_args, msg);
  if ((fr = new_frame(player, program, source, location, 1)))
  {
 if(o_fast_exits) {
  if (FLAGS(source) & WIZARD) {
      fr->sleeptime = time(NULL);
      fr->status = STATUS_RUN;
     } else {
      fr->status = STATUS_SLEEP;
      fr->sleeptime = time(NULL) + 1;
     }
  } else {
      fr->status = STATUS_SLEEP;
      fr->sleeptime = time(NULL) + 1;
  }
    add_frame(fr);
  }
}

void listener_sweep(dbref player, dbref first, dbref location, char *msg)
{
  int count;

  DOLIST (first, first)
  {
    if (FLAGS(first) & HAVEN)
      for (count = 0; count < DBFETCH(first)->sp.exit.ndest; count++)
      spawn_listener(player, first, DBFETCH(first)->sp.exit.dest[count],
	location, msg);
  }
}

int notify(dbref from, dbref to, char *msg)
{
  return notify_listener(from, to, DBFETCH(from)->location, msg);
}

int notify_listener(dbref player, dbref listener, dbref location, char *msg)
{
  char *name, buf1[BUFFER_LEN], buf2[BUFFER_LEN];
  int retval = 1;

  if ((FLAGS(listener) & QUELL) && Typeof(listener) != TYPE_PLAYER)
     return retval;

  sprintf(buf1, "%s", msg);
  if (FLAGS(listener) & NOSPOOF)
  {
    name = unparse_name(OWNER(player));
    if(stringn_compare(name, msg, strlen(name)) &&
      (listener != OWNER(player)))
    {
      /* uh oh, a spoof! */
      sprintf(buf2, "[%s] %s", unparse_object(listener, OWNER(player)), buf1);
      strcpy(buf1, buf2);
    }
  }
#ifdef MUSH
  notify_check(listener, buf1, 1);
#else
  retval = notify_nolisten(listener, buf1);
#endif
  listener_sweep(player, DBFETCH(listener)->exits, location, msg);
  return retval;
}

void notify_except(dbref player, dbref location, dbref exception, char *msg)
{
  dbref first;

  /* notify here... */
  notify_listener(player, location, location, msg);

  /* notify all objects/players in the player */
  if (DBFETCH(player)->location == location)
  {
    first = DBFETCH(player)->contents;

    DOLIST (first, first)
    {
      if (first != exception) notify(player, first, msg);
    }
  }

  /* notify all objects/players in the room */
  first = DBFETCH(location)->contents;

  DOLIST (first, first)
  {
    if (first != exception) notify(player, first, msg);
  }

  /* do all listen exits here */
  listener_sweep(player, DBFETCH(location)->exits, location, msg);

  /* do all listen exits on me */
  listener_sweep(player, DBFETCH(player)->exits, location, msg);
  /* do all listen exits on parents of here */
  first = DBFETCH(location)->location;
  while (first != NOTHING)
  {
    listener_sweep(player, DBFETCH(first)->exits, location, msg);
    first = DBFETCH(first)->location;
  }
}

int blank(char *s)
{
  while (*s && isspace(*s))
    s++;
  
  return !(*s);
}

void notify_except_nolisten(dbref player, dbref location, dbref exception, char *msg)
{
  dbref first;

  if (DBFETCH(player)->location == location) {
    first = DBFETCH(player)->contents;
    DOLIST (first, first) {
      if (first != exception) notify_nolisten(first, msg);
    }
  }

  first = DBFETCH(location)->contents;
  DOLIST (first, first) {
    if (first != exception) notify_nolisten(first, msg);
  }
}