nakedmudv3.0/
nakedmudv3.0/lib/
nakedmudv3.0/lib/logs/
nakedmudv3.0/lib/misc/
nakedmudv3.0/lib/players/
nakedmudv3.0/lib/pymodules/
nakedmudv3.0/lib/txt/
nakedmudv3.0/lib/world/
nakedmudv3.0/lib/world/examples/
nakedmudv3.0/lib/world/examples/mproto/
nakedmudv3.0/lib/world/examples/oproto/
nakedmudv3.0/lib/world/examples/reset/
nakedmudv3.0/lib/world/examples/rproto/
nakedmudv3.0/lib/world/examples/trigger/
nakedmudv3.0/lib/world/limbo/
nakedmudv3.0/lib/world/limbo/rproto/
nakedmudv3.0/src/alias/
nakedmudv3.0/src/char_vars/
nakedmudv3.0/src/editor/
nakedmudv3.0/src/example_module/
nakedmudv3.0/src/help/
nakedmudv3.0/src/set_val/
nakedmudv3.0/src/socials/
nakedmudv3.0/src/time/
//*****************************************************************************
//
// cmd_admin.c
//
// commands and procedures available only to admins.
//
//*****************************************************************************

#include "mud.h"
#include "world.h"
#include "inform.h"
#include "character.h"
#include "room.h"
#include "handler.h"
#include "utils.h"
#include "socket.h"
#include "save.h"
#include "storage.h"



//*****************************************************************************
// commands in cmd_admin.c
//*****************************************************************************

//
// Locks the game for anyone not a member of one of the user groups we specify.
COMMAND(cmd_lockdown) {
  // no argument - check the current lockdown status
  if(!*arg) {
    if(!*mudsettingGetString("lockdown"))
      send_to_char(ch, "Lockdown is currently turned off.\r\n");
    else {
      send_to_char(ch, "Current lockdown is to members not of: %s\r\n",
		   mudsettingGetString("lockdown"));
      send_to_char(ch, "To turn off lockdown, use {clockdown off{n\r\n");
    }
  }

  // turn lockdown off
  else if(!strcasecmp(arg, "off")) {
    send_to_char(ch, "Lockdown disabled.\r\n");
    mudsettingSetString("lockdown", "");
  }

  // make sure we're not locking ourself out
  else if(!bitIsSet(charGetUserGroups(ch), arg))
    send_to_char(ch, "You cannot lock yourself out!\r\n");

  // lock out anyone not in the groups we specify
  else {
    send_to_char(ch, "MUD locked down to everyone not in groups: %s\r\n", arg);
    mudsettingSetString("lockdown", arg);

    // kick out everyone who we've just locked out
    LIST_ITERATOR *ch_i = newListIterator(mobile_list);
    ITERATE_LIST(ch, ch_i) {
      if(!charIsNPC(ch) && !bitIsSet(charGetUserGroups(ch), arg)) {
	send_to_char(ch, "The mud has just been locked down to you.\r\n");
	save_player(ch);

	// and close the socket if we have one
	if(charGetSocket(ch)) {
	  SOCKET_DATA *sock = charGetSocket(ch);
	  charSetSocket(ch, NULL);
	  socketSetChar(sock, NULL);
	  close_socket(sock, FALSE);
	}

	// do the extraction
	extract_mobile(ch);
      }
    } deleteListIterator(ch_i);
  }
}


//
// changes the number of pulses the mud experiences each second
COMMAND(cmd_pulserate) {
  if(!*arg)
    send_to_char(ch,"The mud currently has %d pulses per second.\r\n", 
		 PULSES_PER_SECOND);
  else {
    int pulserate = 0;
    if(!parse_args(ch, FALSE, cmd, arg, "int",  &pulserate) ||
       (1000 % pulserate != 0))
      send_to_char(ch, "The number of pulses per second must divide 1000.\r\n");
    else {
      mudsettingSetInt("pulses_per_second", pulserate);
      send_to_char(ch, "The mud's new pulse rate is %d pulses per second.\r\n",
		   PULSES_PER_SECOND);
    }
  }
}


//
// BOOM! Shut down the MUD
COMMAND(cmd_shutdown) {
  shut_down = TRUE;
}


//
// Perform a command multiple times
COMMAND(cmd_repeat) {
  int    repeats = 0;

  if(!parse_args(ch, TRUE, cmd, arg, "int string", &repeats, &arg))
    return;

  // make sure the integer is a valid number
  if(repeats < 1)
    send_to_char(ch, "Commands can only be repeated a positive number of time.\r\n");
  else {
    int i;
    // now, do the repeating
    for(i = 0; i < repeats; i++)
      do_cmd(ch, arg, TRUE);
  }
}


//
// tries to force the person to do something
void try_force(CHAR_DATA *ch, CHAR_DATA *vict, char *cmd) {
  if(ch == vict)
    send_to_char(ch, "Why don't you just try doing it?\r\n");
  else if(!charHasMoreUserGroups(ch, vict))
    send_to_char(ch, "But %s has just as many priviledges as you!\r\n",
		 charGetName(vict));
  else {
    send_to_char(ch,   "You force %s to '%s'\r\n", charGetName(vict), cmd);
    send_to_char(vict, "%s forces you to '%s'\r\n",
		 see_char_as(vict, ch), cmd);
    do_cmd(vict, cmd, TRUE);
  }
}


//
// force someone to execute a command
COMMAND(cmd_force) {
  void    *found = NULL;
  bool  multiple = FALSE; 

  if(!parse_args(ch, TRUE, cmd, arg, "ch.world.noself.multiple string",
		 &found, &multiple, &arg))
    return;

  // did we find a single character, or a list of characters?
  if(multiple == FALSE)
    try_force(ch, found, arg);
  else {
    LIST_ITERATOR *ch_i = newListIterator(found);
    CHAR_DATA   *one_ch = NULL;
    ITERATE_LIST(one_ch, ch_i) {
      try_force(ch, one_ch, arg);
    } deleteListIterator(ch_i);
    deleteList(found);
  }
}


//
// Perform a command at another room or person
COMMAND(cmd_at) {
  ROOM_DATA *room = NULL;
  void     *found = NULL;
  int  found_type = PARSE_NONE;

  if(!parse_args(ch, TRUE, cmd, arg, "{ room ch.world.noself } string",
		 &found, &found_type, &arg))
    return;

  // figure out what room we're doing the command at
  if(found_type == PARSE_ROOM)
    room = found;
  else // found_type == PARSE_CHAR
    room = charGetRoom(found);

  // transfer us over to the new room, do the command, then transfer back
  ROOM_DATA *old_room = charGetRoom(ch);
  char_from_room(ch);
  char_to_room(ch, room);
  do_cmd(ch, arg, TRUE);
  char_from_room(ch);
  char_to_room(ch, old_room);
}


//
// Go to a specific room, object, or character in the game. Rooms are referenced
// by vnum. Everything else is referenced by name.
//   usage: goto <thing>
//
//   examples:
//     goto 100             go to room number 100
//     goto jim             go to an object/person named jim
COMMAND(cmd_goto) {
  ROOM_DATA *room = NULL;
  void     *found = NULL;
  int  found_type = PARSE_NONE;

  if(!parse_args(ch, TRUE, cmd, arg, "{ room ch.world.noself }", 
		 &found, &found_type))
    return;

  // what did we find?
  if(found_type == PARSE_ROOM)
    room = found;
  else // found_type == PARSE_CHAR
    room = charGetRoom(found);

  message(ch, NULL, NULL, NULL, TRUE, TO_ROOM,
	  "$n disappears in a puff of smoke.");
  char_from_room(ch);
  char_to_room(ch, room);
  look_at_room(ch, room);
  message(ch, NULL, NULL, NULL, TRUE, TO_ROOM,
	  "$n arrives in a puff of smoke.");
}


//
// ch transfers tgt to dest
void do_transfer(CHAR_DATA *ch, CHAR_DATA *tgt, ROOM_DATA *dest) {
  if(dest == charGetRoom(tgt))
    send_to_char(ch, "%s is already %s.\r\n", charGetName(tgt),
		 (charGetRoom(ch) == dest ? "here" : "there"));
  else {
    send_to_char(tgt, "%s has transferred you to %s!\r\n",
		 see_char_as(tgt, ch), roomGetName(dest));
    message(tgt, NULL, NULL, NULL, TRUE, TO_ROOM,
	    "$n disappears in a puff of smoke.");
    char_from_room(tgt);
    char_to_room(tgt, dest);
    look_at_room(tgt, dest);
    message(tgt, NULL, NULL, NULL, TRUE, TO_ROOM,
	    "$n arrives in a puff of smoke.");
  }
}


//
// The opposite of goto. Instead of moving to a specified location, it
// takes the target to the user.
//   usage: transfer <player> [[to] room]
COMMAND(cmd_transfer) {
  void     *found = NULL;
  bool   multiple = FALSE;
  ROOM_DATA *dest = NULL;

  // if our arguments don't parse properly, 
  // parse_args will tell the person what is wrong
  if(parse_args(ch, TRUE, cmd, arg,
		"ch.world.multiple.noself | [to] room",
		&found, &multiple, &dest)) {
    // if we didn't supply a destination, use our current room
    if(dest == NULL)
      dest = charGetRoom(ch);

    // if we have multiple people, we'll have to transfer them one by one
    if(multiple == FALSE)
      do_transfer(ch, found, dest);
    else {
      LIST_ITERATOR *tgt_i = newListIterator(found);
      CHAR_DATA       *tgt = NULL;
      ITERATE_LIST(tgt, tgt_i) {
	do_transfer(ch, found, dest);
      } deleteListIterator(tgt_i);

      // we also have to delete the list that we were given
      deleteList(found);
    }
  }
}


//
// Perform a copyover
COMMAND(cmd_copyover) { 
  do_copyover(ch);
}


//
// show a list of all the PCs who are linkdead
COMMAND(cmd_linkdead) {
  LIST_ITERATOR *ch_i = newListIterator(mobile_list);
  CHAR_DATA   *one_ch = NULL;
  bool          found = FALSE;

  ITERATE_LIST(one_ch, ch_i) {
    if (!(charIsNPC(one_ch) || charGetSocket(one_ch))) {
      send_to_char(ch, "%s is linkdead.\r\n", charGetName(one_ch));
      found = TRUE;
    }
  } deleteListIterator(ch_i);

  if (!found)
    send_to_char(ch, "Noone is currently linkdead.\r\n");
}