/* wiz.c */
#include "copyright.h"
/* Wizard-only commands */
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include "config.h"
#include "db.h"
#include "interface.h"
#include "match.h"
#include "externs.h"
#ifdef MEM_CHECK
#include "mem_check.h"
#endif
#define ANY_OWNER -2
extern char *strchr();
void do_search(player, arg1, arg3)
dbref player;
const char *arg1;
const char *arg3;
{
int flag;
char *arg2;
dbref thing;
dbref from;
dbref to;
int is_wizard;
int destitute = 1;
dbref restrict_zone;
char *restrict_name;
dbref restrict_owner;
object_flag_type flag_mask;
object_flag_type restrict_type;
char tbuf1[BUFFER_LEN];
int rcount, ecount, pcount, ocount;
struct dblist *found = NULL, *ptr = NULL, *rlist = NULL,
*elist = NULL, *olist = NULL, *plist = NULL;
/* parse first argument into two */
if (!arg1 || *arg1 == '\0')
arg1 = "me";
arg2 = strchr(arg1, ' ');
if (arg2 != NULL)
*arg2++ = '\0'; /* arg1, arg2, arg3 */
else {
if (*arg3 == '\0')
arg2 = (char *) ""; /* arg1 */
else {
arg2 = (char *) arg1; /* arg2, arg3 */
arg1 = (char *) "";
}
}
is_wizard = Wizard(player);
restrict_zone = NOTHING;
/* set limits on who we search */
restrict_owner = NOTHING;
if (*arg1 == '\0')
restrict_owner = is_wizard ? 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;
switch (arg2[0]) {
case '\0':
/* the no class requested class :) */
break;
case 'e':
if (string_prefix("exits", arg2)) {
restrict_name = (char *) 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, arg3,
&flag_mask, &restrict_type))
return;
} else
flag = 1;
break;
case 'n':
if (string_prefix("name", arg2))
restrict_name = (char *) arg3;
else
flag = 1;
break;
case 'o':
if (string_prefix("objects", arg2)) {
restrict_name = (char *) arg3;
restrict_type = TYPE_THING;
} else
flag = 1;
break;
case 'p':
if (string_prefix("players", arg2)) {
restrict_name = (char *) 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 = (char *) 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("object", 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)) {
init_match(player, arg3, TYPE_THING);
match_absolute();
restrict_zone = match_result();
} else
flag = 1;
break;
default:
flag = 1;
}
if (flag) {
notify(player, tprintf("%s: unknown class.", arg2));
return;
}
/* make sure player is authorized to do requested search */
if (!is_wizard && restrict_type != TYPE_PLAYER &&
(restrict_owner == ANY_OWNER || restrict_owner != player)) {
notify(player, "You need a search warrant to do that!");
return;
}
/* make sure player has money to do the search */
if (!payfor(player, FIND_COST)) {
notify(player, tprintf("Searches cost %d %s", FIND_COST,
((FIND_COST == 1) ? MONEY : MONIES)));
return;
}
/* the search loop here */
flag = 1;
for (thing = 0; thing < db_top; thing++) {
switch(Typeof(thing)) {
case TYPE_PLAYER:
found = plist;
break;
case TYPE_EXIT:
found = elist;
break;
case TYPE_THING:
found = olist;
break;
case TYPE_ROOM:
found = rlist;
break;
default:
continue;
}
if (restrict_type != NOTYPE && restrict_type != Typeof(thing))
continue;
if ((db[thing].flags & flag_mask) != flag_mask)
continue;
#ifdef DESTROY
if (db[thing].flags & GOING)
continue;
#endif
if (Typeof(thing) == TYPE_PLAYER) {
if (is_wizard)
if (restrict_owner != ANY_OWNER &&
restrict_owner != db[thing].owner)
continue;
} else {
if (restrict_owner != ANY_OWNER &&
restrict_owner != db[thing].owner)
continue;
}
if (restrict_name != NULL)
if (!string_match(db[thing].name, restrict_name))
continue;
if (restrict_zone != NOTHING)
if (restrict_zone != getzone(thing))
continue;
if (!found) {
flag = 0;
destitute = 0;
found = listcreate(thing);
} else
listadd(found, thing);
switch(Typeof(thing)) {
case TYPE_PLAYER:
plist = found;
break;
case TYPE_EXIT:
elist = found;
break;
case TYPE_THING:
olist = found;
break;
case TYPE_ROOM:
rlist = found;
break;
default:
break;
}
}
/* if nothing found matching search criteria */
if (destitute) {
notify(player, "Nothing found.");
return;
}
/* Walk down the list and print */
rcount = ecount = pcount = ocount = 0;
if (restrict_type == TYPE_ROOM || restrict_type == NOTYPE) {
notify(player, "\nROOMS:");
for (ptr = rlist; ptr; ptr = ptr->next) {
notify(player, unparse_object(player, ptr->obj));
rcount++;
}
}
if (restrict_type == TYPE_EXIT || restrict_type == NOTYPE) {
notify(player, "\nEXITS:");
for (ptr = elist; ptr; ptr = ptr->next) {
if(db[ptr->obj].exits == NOTHING)
from = find_entrance(thing);
else
from = db[ptr->obj].exits;
to = db[ptr->obj].location;
sprintf(tbuf1, "%s [from ", unparse_object(player, ptr->obj));
strcat(tbuf1, tprintf("%s to ", (from == NOTHING) ? "NOWHERE" :
unparse_object(player, from)));
strcat(tbuf1, tprintf("%s]", (to == NOTHING) ? "NOWHERE" :
unparse_object(player, to)));
notify(player, tbuf1);
ecount++;
}
}
if (restrict_type == TYPE_THING || restrict_type == NOTYPE) {
notify(player, "\nOBJECTS:");
for (ptr = olist; ptr; ptr = ptr->next) {
sprintf(tbuf1, "%s [owner: ", unparse_object(player, ptr->obj));
strcat(tbuf1, tprintf("%s]",
unparse_object(player, db[ptr->obj].owner)));
notify(player, tbuf1);
ocount++;
}
}
if (restrict_type == TYPE_PLAYER ||
(is_wizard && restrict_type == NOTYPE)) {
notify(player, "\nPLAYERS:");
for (ptr = plist; ptr; ptr = ptr->next) {
strcpy(tbuf1, unparse_object(player, ptr->obj));
if (is_wizard) {
strcat(tbuf1, " [location: ");
strcat(tbuf1, unparse_object(player, db[ptr->obj].location));
strcat(tbuf1, "]");
}
notify(player, tbuf1);
pcount++;
}
}
notify(player, "---------- Search Done ----------");
notify(player,
tprintf("Totals: Rooms...%d Exits...%d Objects...%d Players...%d",
rcount, ecount, ocount, pcount));
if (plist)
listfree(plist);
if (rlist)
listfree(rlist);
if(olist)
listfree(olist);
if(elist)
listfree(elist);
}
object_flag_type convert_flags(player, s, p_mask, p_type)
dbref player;
char *s;
object_flag_type *p_mask;
object_flag_type *p_type;
{
static struct {
int id, type;
object_flag_type bits;
} fdata[] = {
{ 'c', TYPE_PLAYER, PLAYER_CONNECT },
{ 'd', TYPE_THING, THING_DEST_OK },
{ 'e', NOTYPE, ENTER_OK },
{ 'g', TYPE_PLAYER, PLAYER_GAGGED },
{ 'h', NOTYPE, HALT },
{ 'i', TYPE_THING, THING_IMMORTAL },
{ 'n', TYPE_ROOM, ROOM_NO_TEL },
{ 'p', TYPE_THING, THING_PUPPET },
#ifdef ROYALTY_FLAG
{ 'r', NOTYPE , ROYALTY},
#endif
{ 't', TYPE_EXIT, EXIT_TRANSPARENT },
{ 'u', TYPE_PLAYER, PLAYER_SUSPECT },
{ 'v', TYPE_THING, THING_VERBOSE },
{ 'x', NOTYPE, TERSE },
{ 'A', TYPE_ROOM, ROOM_ABODE },
#ifdef RESTRICTED_BUILDING
{ 'B', TYPE_PLAYER, PLAYER_BUILD },
#endif
{ 'C', NOTYPE, CHOWN_OK },
{ 'D', NOTYPE, DARK },
{ 'E', TYPE_EXIT, 0 },
{ 'F', TYPE_ROOM, ROOM_FLOATING },
{ 'G', NOTYPE, GOING },
{ 'H', NOTYPE, HAVEN },
#ifdef INHERIT_FLAG
{ 'I', NOTYPE, INHERIT },
#endif
{ 'J', TYPE_ROOM, ROOM_JUMP_OK },
{ 'K', TYPE_THING, THING_KEY },
{ 'K', TYPE_EXIT, EXIT_KEY },
{ 'L', TYPE_ROOM, LINK_OK },
{ 'N', NOTYPE, NOSPOOF},
{ 'O', NOTYPE, OPAQUE },
{ 'P', TYPE_PLAYER, 0 },
{ 'Q', NOTYPE, QUIET },
{ 'R', TYPE_ROOM, 0 },
{ 'S', NOTYPE, STICKY },
{ 'T', TYPE_ROOM, ROOM_TEMPLE },
{ 'U', TYPE_PLAYER, PLAYER_DARK },
{ 'V', NOTYPE, VISUAL },
{ 'W', NOTYPE, WIZARD },
{ 'X', TYPE_THING, THING_SAFE },
{ 0, 0, 0 }
};
int i;
char last_id = ' ';
object_flag_type mask, type;
mask = 0;
type = NOTYPE;
while (*s != '\0') {
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;
}
++s;
}
/* return new mask and type */
*p_mask = mask;
*p_type = type;
return 1;
}
#ifdef WCREAT
void do_pcreate(creator, player_name, player_password)
dbref creator;
const char *player_name;
const char *player_password;
{
dbref player;
if (!Wizard(creator)) {
notify(creator, "Only wizards are allowed to create people!");
return;
}
player = create_player(player_name, player_password);
if (player == NOTHING) {
notify(creator, tprintf("failure creating '%s'", player_name));
return;
}
notify(creator, tprintf("New player '%s' created with password '%s'",
player_name, player_password));
fprintf(stderr, "CREATION: %s(#%d) created %s(#%d)\n",
db[creator].name, creator, player_name, player);
}
#endif
#ifdef QUOTA
void do_quota(player, arg1, arg2)
dbref player;
char *arg1, *arg2;
{
dbref who, thing;
ATTR *a;
int owned, limit;
if (!arg1 && !*arg1)
who = player;
else {
init_match(player, arg1, TYPE_PLAYER);
match_me();
match_player();
match_neighbor();
match_absolute();
if ((who = noisy_match_result()) == NOTHING)
return;
}
if (!Wizard(player)) {
if (*arg2 != '\0') {
notify(player, "Only wizards may change a quota.");
return;
}
if (player != who) {
notify(player, "Only wizards may look at someone else's quota.");
return;
}
}
/* 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;
}
if (Wizard(who))
notify(player, tprintf("Objects: %d Limit: UNLIMITED", owned));
else {
/* calculate and/or set new */
if (*arg2 == '\0') {
a = atr_get(who, "RQUOTA");
if(a)
limit = owned + atoi(uncompress(a->value));
else
limit = owned;
} else {
limit = atoi(arg2);
}
/* stored as a relative value */
(void) atr_add(who, "RQUOTA", tprintf("%d", limit-owned), GOD, NOTHING);
notify(player, tprintf("Objects: %d Limit: %d", owned, limit));
}
}
void do_allquota(player, arg1)
dbref player;
char *arg1;
{
int limit, owned, max;
dbref who, thing;
ATTR *a;
if (!God(player)) {
notify(player, "Who do you think you are, GOD?");
return;
}
limit = atoi(arg1);
notify(player, "working...limit is %d",limit);
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;
}
a = atr_get(who, "RQUOTA");
if(a)
max = atoi(uncompress(a->value));
else
max = 0;
notify(player, tprintf("%s: left(%d) owned(%d)",db[who].name, max, owned));
/* stored as a relative value */
(void) atr_add(who, "RQUOTA", tprintf("%d", limit-owned), GOD, NOTHING);
}
notify(player, "done.");
}
#endif QUOTA
void do_teleport(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref victim;
dbref destination;
const char *to;
dbref absroom; /* "absolute room", for NO_TEL check */
int rec = 0; /* recursion counter */
/* 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();
if ((victim = noisy_match_result()) == NOTHING) {
return;
}
to = arg2;
}
/* get destination */
if (!string_compare(to, "home")) {
destination = db[victim].exits;
} else {
init_match(player, to, TYPE_PLAYER);
match_here();
match_absolute();
match_neighbor();
match_me();
match_player();
match_exit();
destination = match_result();
}
switch (destination) {
case NOTHING:
notify(player, "No match.");
break;
case AMBIGUOUS:
notify(player, "I don't know which destination you mean!");
break;
default:
/* check victim, destination types, teleport if ok */
if(recursive_member(destination, victim, 0) || (victim == destination)) {
notify(player, "Bad destination.");
return;
}
if (!Hasprivs(player) &&
(Typeof(victim) == TYPE_EXIT ||
Typeof(victim) == TYPE_ROOM ||
((Typeof(victim) == TYPE_PLAYER) &&
(Typeof(destination) == TYPE_PLAYER)))) {
notify(player, "Bad destination.");
return;
}
/* if royal or wiz and destination is player, tel to location */
if ((Typeof(destination) == TYPE_PLAYER) &&
(Hasprivs(player)) && (Typeof(victim) == TYPE_PLAYER) &&
(destination != HOME)) {
safe_tel(victim, db[destination].location);
return;
}
/* check needed for NOTHING. Especially important for unlinked exits */
if ((absroom = db[victim].location) == NOTHING) {
if (Typeof(victim) != TYPE_EXIT) {
notify(victim, "You're in the Void. This is not a good thing.");
do_move(victim, "home", 0);
return;
}
/* if the thing is an unlinked exit, no need for NO_TEL check */
}
else {
/* valid location, perform other checks */
/* if player is inside himself, send him home */
if (absroom == victim) {
notify(player, "What are you doing inside of yourself?");
do_move(victim, "home", 0);
return;
}
/* find the "absolute" room */
while ((Typeof(absroom) != TYPE_ROOM) && (rec < 15)) {
absroom = db[absroom].location;
rec++;
}
/* if there are a lot of containers, send him home */
if (rec > 15) {
notify(victim, "You're in too many containers.");
do_move(victim, "home", 0);
return;
}
/* note that we check the NO_TEL status of the victim rather than */
/* the player that issued the command. This prevents someone in a */
/* NO_TEL room from having one of his objects @tel him out. The */
/* control check, however, is detemined by command-giving player. */
/* now check to see if the absolute room is set NO_TEL */
if ((db[absroom].flags & ROOM_NO_TEL)
&& !controls(player, absroom)
&& !Hasprivs(player)) {
notify(player, "Teleports are not allowed in this room.");
return;
}
}
if (Typeof(destination) != TYPE_EXIT) {
if (Hasprivs(player) ||
(controls(player,victim) &&
(((Typeof(destination) == TYPE_ROOM) &&
(db[destination].flags & ROOM_JUMP_OK)) ||
controls(player,destination))) ||
(controls(player, db[victim].location) &&
(controls(player, destination) ||
((Typeof(destination) == TYPE_ROOM) &&
(db[destination].flags & ROOM_JUMP_OK))))) {
safe_tel(victim, destination);
if ((victim != player) &&
!((Typeof(victim) == TYPE_THING) &&
(db[victim].flags & THING_PUPPET) &&
(db[victim].owner == db[player].owner)))
notify(player, "Teleported.");
return;
}
notify(player, "Permission denied.");
return;
} else {
if (controls(player, victim) ||
controls(player, db[victim].location)) {
do_move(victim, to, 0);
} else {
notify(victim,
tprintf("%s tries to impose his will on you and fails.",
db[player].name));
}
}
}
}
void do_force(player, what, command)
dbref player;
const char *what;
char *command;
{
dbref victim;
if ((victim = match_controlled(player, what)) == NOTHING) {
notify(player, "Sorry.");
return;
}
if ((Typeof(victim) == TYPE_ROOM) || (Typeof(victim) == TYPE_EXIT)) {
notify(player, "You can only force players and things.");
return;
}
if (Wizard(player)) {
static char pl[BUFFER_LEN], vic[BUFFER_LEN];
strcpy(pl, unparse_object(player, player));
strcpy(vic, unparse_object(player, victim));
if (db[victim].owner != db[player].owner)
fprintf(stderr, "** FORCE ** [%s: %s] %s\n", pl, vic, command);
else
fprintf(stderr, "FORCE [%s:%s] %s\n", pl, vic, command);
}
if (victim == GOD) {
notify(player, "You can't force God!");
return;
}
#ifdef INHERIT_FLAG
if (!Inherit(player) && Inherit(victim)) {
notify(player, "Authorization failed.");
return;
}
#endif
/* force victim to do command */
parse_que(victim, command, player);
}
int try_force(player, command)
dbref player;
const char *command;
{
dbref thing;
char *s;
char tbuf1[BUFFER_LEN];
/* first see if command prefixed by object # */
if (*command == '#') {
strcpy(tbuf1, command);
for (s = tbuf1; *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(tbuf1, command);
s = tbuf1 + strlen(db[thing].name);
if (!*s)
return (0);
*s++ = 0;
} else
return (0);
}
do_force(player, tbuf1, s);
return (1);
}
void do_stats(player, name)
dbref player;
const char *name;
{
dbref garbage;
dbref rooms;
dbref exits;
dbref things;
dbref players;
dbref total;
dbref i;
dbref owner;
/* 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 (!Wizard(player))
if (owner != ANY_OWNER && owner != player) {
notify(player, "You need a search warrant to do that!");
return;
}
total = rooms = exits = things = players = garbage = 0;
for (i = 0; i < db_top; i++) {
if (owner == ANY_OWNER || owner == db[i].owner) {
if (db[i].flags & GOING) {
garbage++;
} else {
total++;
switch (Typeof(i)) {
case TYPE_ROOM:
rooms++;
break;
case TYPE_EXIT:
exits++;
break;
case TYPE_THING:
things++;
break;
case TYPE_PLAYER:
players++;
break;
default:
break;
}
}
}
}
if (owner == ANY_OWNER) {
total = total + garbage;
notify(player, tprintf("%d objects = %d rooms, %d exits, %d things, %d players, %d garbage.",
total, rooms, exits, things, players, garbage));
} else {
notify(player, tprintf("%d objects = %d rooms, %d exits, %d things, %d players.",
total, rooms, exits, things, players));
}
#ifdef MEM_CHECK
if(God(player))
list_mem_check(player);
#endif
#ifdef SLOW_STATISTICS
if(God(player))
dump_malloc_data(player);
#endif
#if defined(DEBUG) && defined(USE_SMALLOC)
if(Wizard(player))
notify(player, tprintf("%d bytes memory used.", memused()));
if(God(player))
verify_sfltable(player);
#endif
}
void do_toad(player, name)
dbref player;
const char *name;
{
dbref victim;
char tbuf1[BUFFER_LEN];
if (!Wizard(player)) {
notify(player, "Only a Wizard can toad a person.");
return;
}
init_match(player, name, TYPE_PLAYER);
match_neighbor();
match_absolute();
match_player();
if ((victim = noisy_match_result()) == NOTHING)
return;
if (Typeof(victim) != TYPE_PLAYER) {
notify(player, "Try @destroy instead!");
} else if (Wizard(victim)) {
notify(player, "You can't toad a Wizard.");
} else if (db[victim].contents != NOTHING) {
notify(player,"You need to destroy their contents first.");
} else {
/* we're ok */
/* do it */
s_Pass(victim, NULL);
db[victim].flags = TYPE_THING;
db[victim].owner = player; /* you get it */
s_Pennies(victim, 1);
/* notify people */
notify(victim,
"You have been turned into a slimy toad.");
notify(player, tprintf("You toaded %s!", db[victim].name));
fprintf(stderr, "*** TOAD *** %s(#%d) toaded %s(#%d)\n",
db[player].name, player, db[victim].name, victim);
/* reset name */
delete_player(victim);
boot_off(victim);
sprintf(tbuf1,
"A wart toad named %s", db[victim].name);
SET(db[victim].name, tbuf1);
do_chownall(player, name, "");
}
}
void do_newpassword(player, name, password)
dbref player;
const char *name;
const char *password;
{
dbref victim;
if (!Wizard(player)) {
notify(player, "Your delusions of grandeur have been duly noted.");
return;
} else if ((victim = lookup_player(name)) == NOTHING) {
notify(player, "No such player.");
} else if (*password != '\0' && !ok_password(password)) {
/* Wiz can set null passwords, but not bad passwords */
notify(player, "Bad password.");
} else if (God(victim) && !God(player)) {
notify(player, "You cannot change that player's password.");
} else {
/* it's ok, do it */
s_Pass(victim, crypt(password,"XX"));
notify(player, "Password changed.");
notify(victim, tprintf("Your password has been changed by %s.",
db[player].name));
fprintf(stderr, "***NEWPASSWORD***: %s(#%d) changed password of %s(#%d)\n",
db[player].name, player, db[victim].name, victim);
}
}
void do_boot(player, name)
dbref player;
const char *name;
{
dbref victim;
if (!Wizard(player)) {
notify(player, "Only a Wizard can boot another player off!");
return;
}
init_match(player, name, TYPE_PLAYER);
match_neighbor();
match_absolute();
match_player();
if ((victim = noisy_match_result()) == NOTHING)
return;
if (God(victim)) {
notify(player, "Thunder booms in the distance.");
return;
}
if (victim == player) {
notify(player, "You're not that limber.");
return;
}
if (Typeof(victim) != TYPE_PLAYER && !God(player)) {
notify(player, "You can only boot off other players!");
} else {
static char th[BUFFER_LEN], own[BUFFER_LEN];
strcpy(th, unparse_object(player, player));
strcpy(own, unparse_object(player, victim));
fprintf(stderr, "*** BOOT *** %s booted %s\n", th, own);
/* we're ok */
/* do it */
/* notify people */
notify(player, tprintf("You booted %s off!", db[victim].name));
notify(victim, "You are politely shown to the door.");
boot_off(victim);
/* reset name */
}
}
void do_chownall(player, name, target)
dbref player;
const char *name;
const char *target;
{
int i;
dbref victim;
dbref n_target;
if(!Wizard(player)) {
notify(player,"Try asking them first!");
return;
}
init_match(player,name,TYPE_PLAYER);
match_neighbor();
match_absolute();
match_player();
if((victim = noisy_match_result()) == NOTHING)
return;
if(!target || !*target) {
n_target = NOTHING;
} else {
init_match(player, target, TYPE_PLAYER);
match_neighbor();
match_absolute();
match_player();
if((n_target = noisy_match_result()) == NOTHING)
return;
}
for(i = 0; i <= db_top; i++) {
if((db[i].owner == victim) && (Typeof(i) != TYPE_PLAYER))
db[i].owner = (n_target == NOTHING ? player : n_target);
}
notify(player, "Object ownership changed.");
}
void do_chzoneall(player, name, target)
dbref player;
const char *name;
const char *target;
{
int i;
dbref victim;
dbref zone;
if (!Wizard(player)) {
notify(player, "You do not have the power to change reality.");
return;
}
init_match(player, name, TYPE_PLAYER);
match_neighbor();
match_absolute();
match_player();
if ((victim = noisy_match_result()) == NOTHING)
return;
if (!target || !*target) {
notify(player, "No zone specified.");
return;
}
if (!string_compare(target, "none"))
zone = NOTHING;
else {
init_match(player, target, TYPE_THING);
match_neighbor();
match_possession();
match_absolute();
switch (zone = match_result()) {
case NOTHING:
notify(player, "I can't seem to find that.");
return;
case AMBIGUOUS:
notify(player, "I don't know which one you mean!");
return;
}
if (Typeof(zone) != TYPE_THING) {
notify(player, "Zones may only be defined by objects.");
return;
}
}
for (i = 0; i <= db_top; i++) {
if (db[i].owner == victim)
db[i].zone = zone;
}
notify(player, "Zone changed for all objects.");
}
extern char cf_motd_msg[BUFFER_LEN], cf_wizmotd_msg[BUFFER_LEN],
cf_nologinmotd_msg[BUFFER_LEN];
extern char *reconstruct_message();
void do_motd(player, key, arg1, arg2)
dbref player;
int key;
const char *arg1, *arg2;
{
char *message;
if(!Wizard(player) && (key != 3)) {
notify(player,
"You may get 15 minutes of fame and glory in life, but not right now.");
return;
}
message = reconstruct_message(arg1, arg2);
switch(key) {
case 1:
strcpy(cf_motd_msg, message);
notify(player, "Motd set.");
break;
case 2:
strcpy(cf_wizmotd_msg, message);
notify(player, "Wizard motd set.");
break;
case 4:
strcpy(cf_nologinmotd_msg, message);
notify(player, "Nologin motd set.");
break;
default:
notify(player, tprintf("MOTD: %s", cf_motd_msg));
if(Wizard(player)) {
notify(player, tprintf("Wiz MOTD: %s", cf_wizmotd_msg));
notify(player, tprintf("Nologin MOTD: %s", cf_nologinmotd_msg));
}
}
}
void do_login(player, state)
dbref player;
const char *state;
{
extern int login_allow;
time_t tt;
tt = time((time_t *) 0);
if(!Wizard(player)) {
notify(player, "Unable to authenticate you, sorry.");
return;
}
if(!string_compare(state, "off")) {
notify(player, "Logins disabled.");
login_allow = 0;
fprintf(stderr, "*** LOGINS DISABLED *** by %s(#%d) at %s",
db[player].name, player, ctime(&tt));
} else if (!string_compare(state, "on")) {
notify(player, "Logins enabled.");
login_allow = 1;
fprintf(stderr, "*** LOGINS ENABLED *** by %s(#%d) at %s",
db[player].name, player, ctime(&tt));
} else {
notify(player, tprintf("Logins are currently %s.",
((login_allow) ? "enabled" : "disabled")));
}
return;
}
void fun_lsearch(buff, args, privs, dumm1)
char *buff;
char *args[10];
dbref privs;
dbref dumm1;
{
/* takes arguments in the form of: player, class, restriction */
int is_wiz;
dbref restrict_owner;
char *who; char *class; char *restrict;
int flag;
object_flag_type flag_mask;
char *restrict_name;
object_flag_type restrict_type;
dbref restrict_zone;
dbref thing;
int destitute = 1;
struct dblist *found = NULL, *ptr = NULL, *list = NULL;
if (!payfor(privs, FIND_COST)) {
strcpy(buff, "#-1 NOT ENOUGH MONEY TO DO SEARCH");
return;
}
is_wiz = Wizard(privs);
who = args[0];
class = args[1];
restrict = args[2];
restrict_zone = NOTHING;
/* set limits on who we search */
restrict_owner = NOTHING;
if (!string_compare(who, "all"))
restrict_owner = is_wiz ? ANY_OWNER : privs;
else if (!string_compare(who, "me"))
restrict_owner = privs;
else
restrict_owner = lookup_player(who);
if (restrict_owner == NOTHING) {
strcpy(buff, "#-1 NO SUCH PLAYER");
return;
}
/* set limits on what we search for */
flag = 0;
flag_mask = 0;
restrict_name = NULL;
restrict_type = NOTYPE;
switch (class[0]) {
case 'e':
if (string_prefix("exits", class)) {
restrict_name = (char *) restrict;
restrict_type = TYPE_EXIT;
} else
flag = 1;
break;
case 'f':
if (string_prefix("flags", class)) {
if (!convert_flags(privs, restrict, &flag_mask, &restrict_type)) {
strcpy(buff, "#-1 UNKNOWN FLAG");
return;
}
} else
flag = 1;
break;
case 'n':
if (string_prefix("name", class))
restrict_name = (char *) restrict;
else if (!string_prefix("none", class))
flag = 1;
break;
case 'o':
if (string_prefix("objects", class)) {
restrict_name = (char *) restrict;
restrict_type = TYPE_THING;
} else
flag = 1;
break;
case 'p':
if (string_prefix("players", class)) {
restrict_name = (char *) restrict;
restrict_type = TYPE_PLAYER;
} else
flag = 1;
break;
case 'r':
if (string_prefix("rooms", class)) {
restrict_name = (char *) restrict;
restrict_type = TYPE_ROOM;
} else
flag = 1;
break;
case 't':
if (string_prefix("type", class)) {
if (!string_compare(restrict, "none"))
break;
if (string_prefix("room", restrict))
restrict_type = TYPE_ROOM;
else if (string_prefix("exit", restrict))
restrict_type = TYPE_EXIT;
else if (string_prefix("object", restrict))
restrict_type = TYPE_THING;
else if (string_prefix("player", restrict))
restrict_type = TYPE_PLAYER;
else {
strcpy(buff, "#-1 UNKNOWN TYPE");
return;
}
} else
flag = 1;
break;
case 'z':
if (string_prefix("zone", class)) {
init_match(privs, restrict, TYPE_THING);
match_absolute();
restrict_zone = match_result();
} else
flag = 1;
break;
default:
flag = 1;
}
if (flag) {
strcpy(buff, "#-1 UNKNOWN TYPE");
return;
}
/* check privs */
if (!is_wiz && restrict_type != TYPE_PLAYER &&
(restrict_owner == ANY_OWNER || restrict_owner != privs)) {
strcpy(buff, "#-1 PERMISSION DENIED");
return;
}
/* search loop */
flag = 1;
for (thing = 0; thing < db_top; thing++) {
found = list;
if (restrict_type != NOTYPE && restrict_type != Typeof(thing))
continue;
if ((db[thing].flags & flag_mask) != flag_mask)
continue;
#ifdef DESTROY
if (db[thing].flags & GOING)
continue;
#endif
if (Typeof(thing) == TYPE_PLAYER) {
if (is_wiz)
if (restrict_owner != ANY_OWNER &&
restrict_owner != db[thing].owner)
continue;
} else {
if (restrict_owner != ANY_OWNER &&
restrict_owner != db[thing].owner)
continue;
}
if (restrict_name != NULL)
if (!string_match(db[thing].name, restrict_name))
continue;
if (restrict_zone != NOTHING)
if (restrict_zone != getzone(thing))
continue;
if (!found) {
flag = 0;
destitute = 0;
found = listcreate(thing);
} else
listadd(found, thing);
list = found;
}
/* nothing found matching search criteria */
if (destitute) {
strcpy(buff, "#-1 NOTHING FOUND");
return;
}
/* go down the list and print into a buffer */
strcpy(buff, "");
for (ptr = list; ptr; ptr = ptr->next) {
if (strlen(buff) + 10 < BUFFER_LEN)
strcat(buff, tprintf("#%d ", ptr->obj));
else
strcpy(buff, "#-1 SEARCH LIST TOO LONG");
}
if (list)
listfree(list);
}