dbm/
misc/
old-docs/
/* wiz.c */

#include "copyright.h"
#include "config.h"

#include <stdio.h>
#ifdef STRING_H
#include <string.h>
#else
#include <strings.h>
#endif				/* STRING_H */
#include <ctype.h>
#if defined(ALLOCA_H) && !defined(NO_ALLOCA)
#include <alloca.h>
#endif

#include "teeny.h"

extern char     cmdwork[];

/*
 * Admin only commands.
 */

voidfunc        do_boot(player, arg)
  int             player;
  char           *arg;
{
  int             victim;

  if (!iswiz(player)) {
    notify_player(player, "You can't boot anyone!\r\n");
    return;
  }
  if (!arg || !*arg) {
    notify_player(player, "Boot whom?\r\n");
    return;
  }
  if ((victim = match_player(arg)) == -1) {
    notify_player(player, "I can't find that player.\r\n");
    return;
  }
  if (!isalive(victim)) {
    notify_player(player, "That player is not connected.\r\n");
    return;
  }
  if (isgod(victim) && !isgod(player)) {
    notify_player(player, "You can't boot God!\r\n");
    return;
  }
  notify_player(victim, "You have been booted off the game.\r\n");
  iobdisconnect(victim);
  disconnect_player(victim);
  notify_player(player, "Booted.\r\n");
}

voidfunc        do_chown(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  int             owner, obj, flags;

  if (!iswiz(player)) {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
  if (!argone || !*argone || !argtwo || !*argtwo) {
    notify_player(player, "Chown what to who?\r\n");
    return;
  }
  if ((owner = resolve_player(player, argtwo, 1)) == -1) {
    notify_player(player, "I can't find that owner.\r\n");
    return;
  }
  if ((obj = resolve_object(player, argone, 0)) == -1) {
    if ((obj = resolve_exit(player, argone)) == -1) {
      notify_player(player, "I can't find that object.\r\n");
      return;
    }
  }
  if (obj == -2) {
    notify_player(player, "I can't tell which one you mean.\r\n");
    return;
  }
  if (get_int_elt(obj, FLAGS, &flags) == -1)
    goto chownbomb;
  if (((flags & TYPE_MASK) == TYP_PLAYER) && !isgod(player)) {
    notify_player(player, "Players always own themselves.\r\n");
    return;
  }
  /* OK. Do it. */
  stamp(obj);

  if (set_int_elt(obj, OWNER, owner) == -1)
    goto chownbomb;
  notify_player(player, "Owner changed.\r\n");
  return;

chownbomb:

  notify_bad(player);
}

voidfunc        do_dump(player)
  int             player;
{
  if (!iswiz(player)) {
    notify_player(player, "You're in a no dumping zone.\r\n");
    return;
  }
  notify_player(player, "Dumping...\r\n");
  dump_db();
}

voidfunc        do_force(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  int             obj;

  if (!iswiz(player)) {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
  if (!argone || !*argone || !argtwo || !*argtwo) {
    notify_player(player, "Force who to do what?\r\n");
    return;
  }
  if ((obj = resolve_player(player, argone, 1)) == -1) {
    notify_player(player, "I can't find that player.\r\n");
    return;
  }
  if (isgod(obj) && (player != PLAYER_GOD)) {
    notify_player(player, "You can't force God to do anything!\r\n");
    return;
  }
  handle_cmd(obj, argtwo);
  notify_player(player, "Ok.\r\n");
}

voidfunc        do_newpassword(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  int             obj;

  if (!iswiz(player)) {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
  if (!argone || !*argone) {
    notify_player(player, "Change who's password to what?\r\n");
    return;
  }
  if ((obj = resolve_player(player, argone, 1)) == -1) {
    notify_player(player, "I can't find that player.\r\n");
    return;
  }
  if (isgod(obj) && !isgod(player)) {
    notify_player(player, "You can't change God's password!\r\n");
    return;
  }
  if (!argtwo || !*argtwo) {
    notify_player(player, "Change their password to what?\r\n");
    return;
  }
  if (set_str_elt(obj, PASSWORD, (argtwo && *argtwo) ?
		  crypt(argtwo, CRYPT_KEY) : (char *) 0) == -1)
    goto newbomb;

  if (isalive(obj) && (argtwo && *argtwo)) {
    sprintf(cmdwork, "Your password has been changed to \"%s\".\r\n", argtwo);
    notify_player(obj, cmdwork);
  }
  notify_player(player, "Password changed.\r\n");
  return;

newbomb:
  notify_bad(player);
  return;
}

voidfunc        do_textdump(player, file)
  int             player;
  char           *file;
{
  if (!isgod(player)) {
    notify_player(player, "You're in a no textdumping zone.\r\n");
    return;
  }
  if (mudstat() == DUMPING) {	/* eeek */
    notify_player(player, "Come back later.\r\n");
    return;
  }
  unlock_cache();		/* whoever said text_dump() was meant to run
				 * with a locked cache?? */

  if (!file || !*file || (player != PLAYER_GOD)) {
    text_dump(DEFAULT_TEXTDUMP, 0);	/* no offset */
  } else {
    text_dump(file, 0);		/* no offset */
  }
  lock_cache();			/* handle_at_cmd() will (re)unlock it.. */

  notify_player(player, "Ok.\r\n");
}

voidfunc        do_toad(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  int             newowner, victim, total, flags, loc, list, next;
  char           *name, *buff = (char *) 0;
  char            work[128];

  if (!iswiz(player)) {
    notify_player(player, "Permission denied, doof.\r\n");
    return;
  }
  if (!argone || !*argone) {
    notify_player(player, "Whom do you want to toad?\r\n");
    return;
  }
  if (!argtwo || !*argtwo) {
    newowner = -1;
  } else {
    if ((newowner = resolve_player(player, argtwo, 1)) == -1 ||
	newowner == -2) {
      notify_player(player, "I can't find that owner.\r\n");
      return;
    }
  }

  if ((victim = resolve_player(player, argone, 1)) == -1 || victim == -2) {
    notify_player(player, "I can't find that player.\r\n");
    return;
  }
  if (isgod(victim)) {
    notify_player(player, "God may not be toaded.\r\n");
    return;
  }
  if (player == victim) {
    notify_player(player, "Toading yourself would be quite stupid.\r\n");
    return;
  }
  if (iswiz(victim) && !isgod(player)) {
    notify_player(player, "You can't toad another wizard!\r\n");
    return;
  }
  notify_player(victim, "You sense that everything you own is vanishing...\r\n");

  if (newowner != -1) {
    total = chownall(victim, newowner);
  } else {
    total = purgepossessions(victim);
  }

  if (get_int_elt(victim, FLAGS, &flags) == -1)
    goto toadbomb;
  flags &= ~TYPE_MASK;
  flags |= TYP_THING;
  if (set_int_elt(victim, FLAGS, flags) == -1)
    goto toadbomb;

  notify_player(victim, "You have been turned into a slimy toad!\r\n");
  iobdisconnect(victim);

  if (get_str_elt(victim, NAME, &name) == -1)
    goto toadbomb;
#ifdef NO_ALLOCA
  buff = ty_malloc(strlen(name) + 1, "do_toad");
#else
  buff = (char *) alloca(strlen(name) + 1);
#endif

  (void) strcpy(buff, name);	/* save a copy */

  (void) sprintf(work, "A slimy toad named %s.", buff);
  if (set_str_elt(victim, NAME, work) == -1)
    goto toadbomb;

  if (get_int_elt(victim, LOC, &loc) == -1)
    goto toadbomb;
  if (exists_object(loc)) {
    (void) strcpy(work, buff);
    (void) strcat(work, " vanishes in a puff of smoke.\r\n");
    notify_oall(victim, work);

    list_drop(victim, loc, CONTENTS_LIST);
    list_add(victim, player, CONTENTS_LIST);
    if (set_int_elt(victim, LOC, player) == -1)
      goto toadbomb;
  }
  if (get_int_elt(victim, CONTENTS, &list) == -1)
    goto toadbomb;
  while (list != -1) {
    int             home;

    if (get_int_elt(list, NEXT, &next) == -1)
      goto toadbomb;
    if (get_int_elt(list, HOME, &home) == -1) {
      list = next;
      continue;
    }
    if (!exists_object(home)) {
      int             owner;

      if (get_int_elt(list, OWNER, &owner) == -1) {
	list = next;
	continue;
      }
      if (get_int_elt(owner, HOME, &home) == -1) {
	list = next;
	continue;
      }
      if (!exists_object(home)) {
	home = STARTING_LOC;
      }
    }
    if (set_int_elt(list, LOC, home) == -1) {
      list = next;
      continue;
    }
    list_drop(list, victim, CONTENTS_LIST);
    list_add(list, home, CONTENTS_LIST);

    list = next;
  }

  if (get_int_elt(victim, EXITS, &list) == -1)
    goto toadbomb;
  if (list) {
    while (list != -1) {
      if (get_int_elt(list, NEXT, &next) == -1)
	goto toadbomb;
      recycleobj(list);
      list = next;
    }
    if (set_int_elt(victim, EXITS, -1) == -1)
      goto toadbomb;
  }
  stamp(victim);

  (void) sprintf(work, "Toaded. %d objects %s.\r\n", total, (newowner == -1) ?
		 "purged" : "chowned");
  notify_player(player, work);

  log_command("TOAD: %s(#%d) toaded by player #%d.\r\n", buff, victim, player);

#ifdef NO_ALLOCA
  ty_free(buff);
#endif

  return;

toadbomb:

  notify_bad(player);
#ifdef NO_ALLOCA
  if (buff)
    ty_free(buff);
#endif
}

voidfunc        do_wall(player, arg)
  int             player;
  char           *arg;
{
  char           *name;

  if (!iswiz(player)) {
    notify_player(player, "But what do you want to do with a wall?\r\n");
    return;
  }
  if (!arg || !*arg) {
    notify_player(player, "But what do you want with the wall?\r\n");
    return;
  }
  if (get_str_elt(player, NAME, &name) == -1)
    goto wallbomb;

  sprintf(cmdwork, "%s shouts, \"%s\"\r\n", name, arg);
  notify_wall(cmdwork);

  log_command("WALL: %s(#%d)  \"%s\"\n", name, player, arg);

  return;
wallbomb:
  notify_bad(player);
  return;
}

voidfunc        do_shutdown(player)
  int             player;
{
  if (isgod(player)) {
    set_mudstat(STOPPED);
    log_command("SHUTDOWN: by %s(#%d)\n", getname(player), player);
    notify_player(player, "Ok.\r\n");
  } else {
    notify_player(player, "Permission denied. Doof.\r\n");
  }
}

voidfunc        do_teleport(player, argone, argtwo)
  int             player;
  char           *argone;
  char           *argtwo;
{
  int             object, loc, dest, objflags, locflags, destflags;
  char           *name;

  if (!argone || !*argone) {
    notify_player(player, "Teleport what to where?\r\n");
    return;
  }
  if (!argtwo || !*argtwo) {
    object = player;
    if (!strcasecmp(argone, "home")) {
      dest = -3;
    } else {
      if ((dest = resolve_object(player, argone, 0)) == -1) {
	notify_player(player, "I can't find that destination.\r\n");
	return;
      } else if (dest == -2) {
	notify_player(player, "I don't know which destination you mean.\r\n");
	return;
      }
    }
  } else {
    if ((object = resolve_object(player, argone, iswiz(player))) == -1) {
      if ((object = resolve_exit(player, argone)) == -1) {
	notify_player(player, "I can't find what you wish to teleport.\r\n");
	return;
      }
    }
    if (object == -2) {
      notify_player(player, "I can't tell which one you wish to teleport.\r\n");
      return;
    }
    if (!strcasecmp(argtwo, "home")) {
      dest = -3;
    } else {
      if ((dest = resolve_object(player, argtwo, iswiz(player))) == -1) {
	notify_player(player, "I can't find that destination.\r\n");
	return;
      } else if (dest == -2) {
	notify_player(player, "I don't know which destination you mean.\r\n");
	return;
      }
    }
  }

  /* do it */

  if (get_int_elt(object, FLAGS, &objflags) == -1)
    goto telbomb;
  if (get_int_elt(object, LOC, &loc) == -1)
    goto telbomb;

  switch (objflags & TYPE_MASK) {
  case TYP_ROOM:		/* parent */
    if (dest != ROOT_PARENT) {
      if (!exists_object(dest) || (object == dest)) {
	notify_player(player, "Illegal parent.\r\n");
	return;
      }
      if (!isroom(dest)) {
	notify_player(player, "That's not a room!\r\n");
	return;
      }
      if (!controls(player, dest) && dest != ROOT_PARENT && !isabode(dest)) {
	notify_player(player, "Permission denied.\r\n");
	return;
      }
      if (!legal_parent_check(dest, loc)) {
	notify_player(player, "Illegal parent.\r\n");
	return;
      }
    }
    if (set_int_elt(object, LOC, dest) == -1)
      goto telbomb;
    list_drop(object, loc, ROOMS_LIST);
    list_add(object, dest, ROOMS_LIST);
    notify_player(player, "Parent set.\r\n");
    return;
  case TYP_EXIT:		/* no go */
    notify_player(player, "You can't teleport that!\r\n");
    return;
  case TYP_PLAYER:		/* our most complex */
    if (get_int_elt(loc, FLAGS, &locflags) == -1)
      goto telbomb;

    if (dest == -3) {		/* home */
      int             home;

      if (get_int_elt(object, HOME, &home) == -1)
	goto telbomb;
      if (!exists_object(home))
	home = STARTING_LOC;

      dest = home;
    }
    if (get_int_elt(dest, FLAGS, &destflags) == -1)
      goto telbomb;
    if ((!controls(player, loc) && !(locflags & JUMP_OK)) ||
	(!controls(player, dest) && !(destflags & JUMP_OK)) ||
	(!controls(player, object) && !(objflags & JUMP_OK))) {
      notify_player(player, "Permission denied.\r\n");
      return;
    }
    if ((destflags & TYPE_MASK) == TYP_EXIT) {
      notify_player(player, "You can't teleport a player to that!\r\n");
      return;
    }
    notify_player(object, "You feel a wrenching sensation...\r\n");

    if (get_str_elt(object, NAME, &name) == -1)
      goto telbomb;

    act_object(object, object, -1, (!isdark(object)) ? OTELEPORT : -1,
	       -1, (char *) 0, (char *) 0);
    if (!(locflags & DARK) && !isdark(object)) {
      sprintf(cmdwork, "%s has left.\r\n", name);
      notify_oall(object, cmdwork);
    }
    act_object(object, object, -1,
	 (!isdark(object)) ? OXTELEPORT : -1, dest, (char *) 0, (char *) 0);
    list_drop(object, loc, CONTENTS_LIST);
    list_add(object, dest, CONTENTS_LIST);
    if (set_int_elt(object, LOC, dest) == -1)
      goto telbomb;
    if (!(destflags & DARK) && !isdark(object)) {
      sprintf(cmdwork, "%s has arrived.\r\n", name);
      notify_oall(object, cmdwork);
    }
    do_look(object, (char *) 0);
    flush_room(loc);

    break;
  case TYP_THING:		/* gotta check for non-sticky drop-tos... */
    if (get_int_elt(loc, FLAGS, &locflags) == -1)
      goto telbomb;

    if (dest == -3) {
      int             home;

      if (get_int_elt(object, HOME, &home) == -1)
	goto telbomb;
      if (!exists_object(home)) {
	int             owner;

	if (get_int_elt(object, OWNER, &owner) == -1)
	  goto telbomb;
	if (get_int_elt(owner, HOME, &home) == -1)
	  goto telbomb;
	if (!exists_object(home))
	  home = STARTING_LOC;

      }
      dest = home;
    }
    if (get_int_elt(dest, FLAGS, &destflags) == -1)
      goto telbomb;

    if ((!controls(player, object) && !(objflags & JUMP_OK)) ||
	(!controls(player, dest) && !(destflags & JUMP_OK))) {
      notify_player(player, "Permission denied.\r\n");
      return;
    }
    if ((destflags & TYPE_MASK) == TYP_EXIT) {
      notify_player(player, "You can't teleport an object to an exit!\r\n");
      return;
    }
    stamp(object);

    act_object(player, object, -1, OTELEPORT, -1, (char *) 0, (char *) 0);
    act_object(player, object, -1, OXTELEPORT, dest, (char *) 0,
	       (char *) 0);
    list_drop(object, loc, CONTENTS_LIST);
    list_add(object, dest, CONTENTS_LIST);
    if (set_int_elt(object, LOC, dest) == -1)
      goto telbomb;

#if 0
    if ((destflags & TYPE_MASK) == TYP_ROOM && !(destflags & STICKY)) {
      char           *odrop;
      int             dropto;

      if (get_int_elt(dest, DROPTO, &dropto) == -1)
	goto telbomb;
      if (dropto == -3) {
	if (get_int_elt(object, HOME, &dropto) == -1)
	  goto telbomb;
	if (!exists_object(dropto)) {
	  dropto = STARTING_LOC;
	}
      }
      if (dropto != -1) {
	if (get_str_elt(object, NAME, &name) == -1)
	  goto telbomb;
	if (get_str_elt(dest, ODROP, &odrop) == -1)
	  goto telbomb;
	if (*odrop) {
	  notify_oall(object, name);
	  notify_oall(object, " ");
	  notify_oall(object, odrop);
	  notify_oall(object, "\r\n");
	} else {
	  notify_oall(object, name);
	  notify_oall(object, " falls through the floor!\r\n");
	}
	list_drop(object, dest, CONTENTS_LIST);
	list_add(object, dropto, CONTENTS_LIST);
	if (set_int_elt(object, LOC, dropto) == -1)
	  goto telbomb;
      }
    }
#endif
    break;
  default:
    goto telbomb;
  }

  notify_player(player, "Teleported.\r\n");
  return;

telbomb:

  notify_bad(player);
}

voidfunc        do_pcreate(player, argone, argtwo)
  int             player;
  char           *argone;
  char           *argtwo;
{
  int             loc, newplayer;

#ifdef GOD_ONLY_PCREATE
  if (!isgod(player)) {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
#else
  if (!iswiz(player)) {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
#endif				/* GOD_ONLY_PCREATE */
  if (!argone || !*argone || !argtwo || !*argtwo) {
    notify_player(player, "Usage: @pcreate <name> = <password>\r\n");
    return;
  }
  if (match_player(argone) != -1) {
    notify_player(player, "A player with that name already exists.\r\n");
    return;
  }
#ifndef REGISTRATION
  if (get_int_elt(player, LOC, &loc) == -1) {
    notify_player(player, "I can't get your location!\r\n");
    return;
  }
#endif				/* REGISTRATION */
  strncpy(cmdwork, argone, 16);
  if (strlen(argone) > 16)
    cmdwork[15] = '\0';
  strcat(cmdwork, " ");
  strcat(cmdwork, argtwo);
#ifndef REGISTRATION
  if ((newplayer = create_player(cmdwork, loc)) == -1) {
#else
  if ((newplayer = create_player(cmdwork, STARTING_LOC)) == -1) {
#endif				/* REGISTRATION */
    notify_player(player, "Pcreate failed.\r\n");
  } else {
    (void) sprintf(cmdwork, "Player \"%s\" created with object #%d.\r\n",
		   getname(newplayer), newplayer);
    notify_player(player, cmdwork);

    log_command("PCREATED: %s(#%d) created by %s(#%d).\n",
		getname(newplayer), newplayer, getname(player), player);
  }
}
voidfunc        do_purge(player, arg)
  int             player;
  char           *arg;
{
  int             victim;

  if (!iswiz(player)) {
    notify_player(player, "Someone doesn't want you doing that.\r\n");
    return;
  }
  if (!arg || !*arg) {
    notify_player(player, "But who's possessions do you want to purge?\r\n");
    return;
  }
  if ((victim = resolve_player(player, arg, 1)) == -1) {
    notify_player(player, "That person does not exist.\r\n");
    return;
  }
  if (isgod(victim)) {
    notify_player(player, "You may not purge God's possessions.\r\n");
    return;
  }
  sprintf(cmdwork, "Purged %d objects.\r\n", purgepossessions(victim));
  notify_player(player, cmdwork);
}
voidfunc        do_chownall(player, argone, argtwo)
  int             player;
  char           *argone;
  char           *argtwo;
{
  int             oldowner, newowner;

  if (!iswiz(player)) {
    notify_player(player, "Someone doesn't want you doing that.\r\n");
    return;
  }
  if (!argone || !*argone || !argtwo || !argtwo) {
    notify_player(player, "Usage: @chownall <oldowner> = <newowner>\r\n");
    return;
  }
  if ((oldowner = resolve_player(player, argone, 1)) == -1) {
    notify_player(player, "I can't find that person.\r\n");
    return;
  }
  if ((newowner = resolve_player(player, argtwo, 1)) == -1) {
    notify_player(player, "I couldn't find the new owner.\r\n");
    return;
  }
  if (isgod(oldowner)) {
    notify_player(player, "You may not chown all of God's possessions.\r\n");
    return;
  }
  sprintf(cmdwork, "Chowned %d objects to #%d.\r\n", chownall(oldowner, newowner),
	  newowner);
  notify_player(player, cmdwork);
}

voidfunc        do_quota(player, argone, argtwo)
  int             player;
  char           *argone;
  char           *argtwo;
{
  int             quota, victim;

  if (!argone || !*argone) {
    victim = player;
  } else {
    if ((victim = resolve_player(player, argone, iswiz(player))) == -1 ||
	victim == -2) {
      notify_player(player, "No such player.\r\n");
      return;
    }
    if (!iswiz(player) && victim != player) {
      notify_player(player, "You're simply not perceptive enough.\r\n");
      return;
    }
  }

  if (!argtwo || !*argtwo) {
    if (get_int_elt(victim, QUOTA, &quota) == -1)
      goto quotabomb;
    (void) sprintf(cmdwork, "%s  Object Quota: %d\r\n",
		   stuff_name(player, victim), quota);
    notify_player(player, cmdwork);
  } else {
    if (!iswiz(player)) {
      notify_player(player, "Contact a Wizard if your quota needs updated.\r\n");
      return;
    }
    if (!isdigit(argtwo[0])) {
      notify_player(player, "Please specify only a positive number.\r\n");
      return;
    }
    quota = atoi(argtwo);
    if (quota < 0) {
      notify_player(player, "Please specify only a positive number.\r\n");
      return;
    }
    if (set_int_elt(victim, QUOTA, quota) == -1)
      goto quotabomb;
    (void) sprintf(cmdwork, "Quota set to %d objects.\r\n", quota);
    notify_player(player, cmdwork);
  }

  return;

quotabomb:

  notify_bad(player);
}

voidfunc        do_wizzwall(player, arg)
  int             player;
  char           *arg;
{
  char           *name;

  if (!iswiz(player)) {
    notify_player(player, "Someone doesn't want you doing that.\r\n");
    return;
  }
  if (!arg || !*arg) {
    notify_player(player, "But what do you want to shout?\r\n");
    return;
  }
  if (get_str_elt(player, NAME, &name) == -1) {
    notify_bad(player);
    return;
  }
  (void) sprintf(cmdwork, "%s wizzes: %s\r\n", name, arg);
  notify_wizz(cmdwork);
}