#include "config.h" /* Its nice to know params.h #includes config.h */
/* PLEASE go read the copyright notice contained in mush.h --Howard */
#ifdef MUSH /* Are we running any MUSH type functions? */
#include "copyright.h"
#include "params.h"
#include "db.h"
#include "interface.h"
#include "externs.h"
#include "mush.h"
#include "match.h"
#include "money.h"
#include "version.h"
#include <ctype.h>
#include <varargs.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
dbref Parent(dbref thing)
{
char *str;
dbref temp;
if(!GoodObject(thing)) return NOTHING;
str = get_property_data(thing, "*PARENT", ACCESS_WI);
if(!str)
return NOTHING;
else {
temp = atol(str);
if(!GoodObject(temp)) temp = NOTHING;
}
return temp;
}
struct dbref_list *listcreate(dbref ref)
{ /* takes a dbref and returns a pointer to the head of a dbref_list */
struct dbref_list *ptr;
ptr = (struct dbref_list *) malloc((unsigned)sizeof(struct dbref_list));
if (!ptr) panic("Out of memory.");
ptr->object = ref;
ptr->next = NULL;
return(ptr);
}
void listfree(dbref_list *head)
{ /* takes a pointer to a dbref_list and recursively frees it */
struct dbref_list *ptra = head, *ptrb;
while (ptra->next) {
ptrb = ptra->next;
free(ptra);
ptra = ptrb;
}
}
void listadd(dbref_list *head, dbref ref)
{
struct dbref_list *ptr = head;
/* takes a pointer to a dbref_list and a dbref and adds the dbref to the
* end of the list. */
while (ptr->next)
ptr = ptr->next;
ptr->next = listcreate(ref);
}
#ifdef FULL_INVIS
char *spname(dbref thing)
{
/* if FULL_INVIS is defined, dark objects and dark wizards will be
* Something and Someone, respectively.
*/
if (!Dark(thing))
return (unparse_name(thing));
else {
if (Typeof(thing) != TYPE_PLAYER)
return ("Something");
else
return ("Someone");
}
}
#else
#define spname(x) (unparse_name(x))
#endif /* FULL_INVIS */
dbref find_entrance(dbref door)
{
dbref room, thing;
for (room = 0; room < db_top; room++)
if (Typeof(room) == TYPE_ROOM) {
thing = DBFETCH(room)->exits;
while (thing != NOTHING) {
if (thing == door)
return room;
thing = DBFETCH(thing)->next;
}
}
return NOTHING;
}
void do_mset(__DO_PROTO)
{
char *tmp, *tmp1;
char string[BUFFER_LEN];
/* find arg1 -- move over command word */
for(tmp = arg1; *tmp && !isspace(*tmp); tmp++);
/* truncate command */
if(*tmp) *tmp++ = '\0';
/* move over spaces */
while(*arg1 && isspace(*arg1)) arg1++;
/* Eat any lingering spaces */
tmp1 = tmp;
while(*tmp1 && isspace(*tmp1)) tmp1++;
sprintf(string, "%s:%s", arg1, arg2);
do_set(player, tmp1, string, string);
}
/* check the current location for bugs */
void do_sweep(dbref player, char *arg1)
{
char tbuf1[BUFFER_LEN];
char *p;
dbref here = DBFETCH(player)->location;
int connect_flag = 0;
int here_flag = 0;
int inven_flag = 0;
int exit_flag = 0;
if (here == NOTHING) return;
if(arg1 && *arg1) {
if (string_prefix(arg1, "connected"))
connect_flag = 1;
else if (string_prefix(arg1, "here"))
here_flag = 1;
else if (string_prefix(arg1, "inventory"))
inven_flag = 1;
else if (string_prefix(arg1, "exits"))
exit_flag = 1;
else {
notify(player, player, "Invalid parameter.");
return;
}
}
if (!inven_flag && !exit_flag) {
notify(player, player, "Listening in ROOM:");
if(connect_flag) {
/* only worry about puppet and players who's owner's are connected */
if (Connected(here) || (Puppet(here) && Connected(OWNER(here)))) {
if(Typeof(here) == TYPE_PLAYER) {
notify(player, player, tprintf("%s is listening",
unparse_name(here)));
} else {
notify(player , player, tprintf("%s [owner: %s] is listening.",
unparse_name(here), unparse_name(OWNER(here))));
}
}
} else {
if (Hearer(here) || Listener(here)) {
if (Connected(here))
notify(player, player, tprintf("%s (this room) [speech]. (connected)",
unparse_name(here)));
else
notify(player, player, tprintf("%s (this room) [speech].",
unparse_name(here)));
}
if (Commer(here))
notify(player, player, tprintf("%s (this room) [commands].",
unparse_name(here)));
if (Audible(here))
notify(player, player, tprintf("%s (this room) [broadcasting].",
unparse_name(here)));
}
for (here = DBFETCH(here)->contents; here != NOTHING;
here = DBFETCH(here)->next) {
if(connect_flag) {
/* only worry about puppet and players who's owner's are connected */
if (Connected(here) || (Puppet(here) && Connected(OWNER(here)))) {
if(Typeof(here) == TYPE_PLAYER) {
notify(player, player, tprintf("%s is listening",
unparse_name(here)));
} else {
notify(player , player, tprintf("%s [owner: %s] is listening.",
unparse_name(here), unparse_name(OWNER(here))));
}
}
} else {
if (Hearer(here) || Listener(here)) {
if (Connected(here))
notify(player, player, tprintf("%s [speech]. (connected)",
unparse_name(here)));
else
notify(player, player, tprintf("%s [speech].", unparse_name(here)));
}
if(Commer(here))
notify(player, player, tprintf("%s [commands].", unparse_name(here)));
}
}
}
if (!connect_flag && !inven_flag &&
(Typeof(Location(player)) == TYPE_ROOM)) {
notify(player, player, "Listening EXITS:");
for (here = DBFETCH(Location(player))->exits; here != NOTHING;
here = DBFETCH(here)->next) {
if (FLAGS(here) & AUDIBLE || FLAGS(here) & HAVEN) {
strcpy(tbuf1, unparse_name(here));
for (p = tbuf1; *p && (*p != ';'); p++)
;
*p = '\0';
notify(player, player, tprintf("%s [broadcasting].", tbuf1));
}
}
}
if (!here_flag && !exit_flag) {
notify(player, player, "Listening in your INVENTORY:");
for (here = Contents(player); here != NOTHING; here = DBFETCH(here)->next) {
if(connect_flag) {
/* only worry about puppet and players who's owner's are connected */
if (Connected(here) || (Puppet(here) && Connected(OWNER(here)))) {
if(Typeof(here) == TYPE_PLAYER) {
notify(player, player, tprintf("%s is listening",
unparse_name(here)));
} else {
notify(player , player, tprintf("%s [owner: %s] is listening.",
unparse_name(here), unparse_name(OWNER(here))));
}
}
} else {
if (Hearer(here) || Listener(here)) {
if (Typeof(here) == TYPE_PLAYER && Connected(here))
notify(player, player, tprintf("%s [speech]. (connected)",
unparse_name(here)));
else
notify(player, player, tprintf("%s [speech].", unparse_name(here)));
}
if(Commer(here))
notify(player, player, tprintf("%s [commands].", unparse_name(here)));
}
}
}
}
void do_trigger(dbref player, char *objct, char *argv[])
{
dbref thing;
int a;
char *s;
char tbuf1[BUFFER_LEN];
match_data md;
strcpy(tbuf1, objct);
for(s = tbuf1; *s && (*s != '/'); s++);
if(!*s) {
notify(player, player, "I need to know what attribute to trigger.");
return;
}
*s++ = '\0';
init_match(player, tbuf1, NOTYPE, &md);
match_everything(&md);
thing = noisy_match_result(&md);
if(thing == NOTHING) return;
if (!controls(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
if (God(thing) && !God(player)) {
notify(player, player, "You can't trigger God!");
return;
}
/* trigger modifies the stack */
for (a = 0; a < 10; a++)
wptr[a] = argv[a + 1];
/* we need to call did_it because trigger uses a charge */
did_it(player, thing, NULL, NULL, NULL, NULL, s, NOTHING);
/*
if(!Quiet(player) && !Quiet(thing))
*/
notify(player, player, tprintf("%s - Triggered.", unparse_name(thing)));
}
void do_verb(dbref player, dbref cause, char *arg1, char *argv[])
{
dbref victim; /* user-defined verbs */
dbref actor;
char *sptr[10];
match_data md;
int i;
/* find the object that we want to read the attributes off
* (the object that was the victim of the command)
*/
/* our victim object can be anything */
init_match(player, arg1, NOTYPE, &md);
match_everything(&md);
victim = match_result(&md);
if (victim == NOTHING) {
notify(player, player, "What was the victim of the verb?");
return;
}
/* find the object that executes the action */
if(argv[1]) {
init_match(player, argv[1], NOTYPE, &md);
match_near_things(&md);
actor = match_result(&md);
}
else
actor = NOTHING;
if (actor == NOTHING) {
notify(player, player, "What do you want to do the verb?");
return;
}
/* Control check is fascist.
* First check: we don't want <actor> to do something involuntarily.
* Both victim and actor have to be controlled by the thing which did
* the @verb (for speed we do a WIZARD check first), or: cause controls
* actor plus the second check is passed.
* Second check: we need read access to the attributes.
* Either the player controls victim or the player
* must be priviledged, or the victim has to be VISUAL.
*/
if (!(Wizard(player) ||
(controls(player, victim) && controls(player, actor)) ||
((controls(cause, actor) && Can_Examine(player, victim))))) {
notify(player, player, "Permission denied.");
return;
}
/* we're okay. Now we copy our args into the stack, saving
* the old stack so we can restore it later.
*/
for (i = 0; i < 10; i++)
sptr[i] = wptr[i];
for (i = 0; i < 10; i++)
wptr[i] = argv[i + 7];
/* do the command, then restore the stack */
did_it(actor, victim, argv[2], argv[3], argv[4], argv[5], argv[6],
getloc(actor));
for (i = 0; i < 10; i++)
wptr[i] = sptr[i];
}
void do_poor(dbref player, char *arg1)
{
int amt = atoi(arg1);
dbref a;
if (!God(player)) {
notify(player, player, "Only God can cause financial ruin.");
return;
}
for (a = 0; a < db_top; a++)
if (Typeof(a) == TYPE_PLAYER) {
DBSTORE(a, pennies, amt);
DBDIRTY(a);
}
notify(player, player,
tprintf("The money supply of all players has been reset to %d %s.",
amt, PL_MONEY));
log_status("** POOR done ** Money supply reset to %d %s. by %s.",
amt, PL_MONEY, unparse_name(player));
}
void do_lemit(dbref player, char *tbuf1)
{
dbref room; /* give a message to the "absolute" location of an object */
int rec = 0;
/* only players and things may use this command */
if (!Mobile(player))
return;
/* prevent infinite loop if player is inside himself */
if (((room = DBFETCH(player)->location) == player) || !GoodObject(room)) {
notify(player, player, "Invalid container object.");
fprintf(stderr, "** BAD CONTAINER ** #%d is inside #%d.\n",
player, room);
return;
}
while ((Typeof(room) != TYPE_ROOM) && (rec < 15)) {
room = DBFETCH(room)->location;
rec++;
}
if (rec > 15) {
notify(player, player, "Too many containers.");
return;
} else {
notify(player, player, tprintf("You lemit: \"%s\"", tbuf1));
oemit_notify_except(DBFETCH(room)->contents, player, room, tbuf1);
}
}
void do_enter(dbref victim, char *arg1)
{
dbref dest;
match_data md;
/* get destination */
init_match(victim, arg1, NOTYPE, &md);
match_here(&md);
match_home(&md);
match_absolute(&md);
match_neighbor(&md);
match_me(&md);
match_player(&md);
dest = match_result(&md);
switch(dest) {
case NOTHING:
notify(victim, victim, "Enter what?");
return;
case AMBIGUOUS:
notify(victim, victim, "I don't know which object you mean!");
return;
}
if (parent_loop_check(victim, dest)) {
notify(victim, victim, "Permission denied.");
return;
}
if(Typeof(dest) == TYPE_GARBAGE) {
notify(victim, victim, "Can't enter garbage.");
return;
}
if(victim == dest) {
notify(victim, victim, "Sorry, you must remain beside yourself!");
return;
}
if ((((FLAGS(dest) & ENTER_OK) || controls(victim, dest)) &&
(eval_boolexp(victim, get_ue_locks(victim, dest, ENTERLOCK), dest))))
enter_room(victim, dest, DBFETCH(victim)->location);
else
did_it(victim, dest, "EFAIL", "Permission denied.", "OEFAIL",
NULL, "AEFAIL", NOTHING);
}
void do_pemit(dbref player, char *arg1, char *arg2, int silent)
{
dbref who;
match_data md;
init_match(player, arg1, NOTYPE, &md);
match_neighbor(&md);
match_possession(&md);
match_container(&md);
match_me(&md);
match_here(&md);
match_player(&md);
match_absolute(&md);
switch (who = match_result(&md)) {
case NOTHING:
notify(player, player, "I don't see that player here.");
break;
case AMBIGUOUS:
notify(player, player, "I don't know who you mean!");
break;
default:
if (Typeof(who) != TYPE_PLAYER && Typeof(who) != TYPE_THING) {
notify(player, player, "Only players and things can hear @pemits.");
break;
}
if ((player != who) && (Haven(who) && (Typeof(who) == TYPE_PLAYER))) {
notify(player, player,
tprintf("I'm sorry, but %s wishes to be left alone now.",
unparse_name(who)));
return;
}
if (!silent)
notify(player, player,
tprintf("You pemit \"%s\" to %s.", arg2, unparse_name(who)));
notify(player, who, tprintf("%s", arg2));
break;
}
}
void do_use(dbref player, char *what)
{
dbref thing;
match_data md;
init_match(player, what, TYPE_THING, &md);
match_near_things(&md);
/* if we pass the use key, do it */
if ((thing = noisy_match_result(&md)) != NOTHING)
if (!eval_boolexp(player, get_ue_locks(player, thing, USELOCK), thing)) {
notify(player, player, "Permission denied.");
return;
} else
did_it(player, thing, "USE", "Used.", "OUSE", NULL, "AUSE", NOTHING);
}
void do_wipe(dbref player, char *name)
{
dbref thing; /* obliterate all attribute from an object */
match_data md;
init_match(player, name, NOTYPE, &md);
match_nearby(&md);
if ((thing = noisy_match_result(&md)) == NOTHING) return;
/* this is too destructive of a command to be used by someone who
* doesn't own the object. Thus, the check is on Owns not controls. */
if (!Wizard(player) && (OWNER(player) != OWNER(thing))) {
notify(player, player, "Permission denied.");
return;
}
if (Safe(thing)) {
notify(player, player, "That object is set SAFE.");
return;
}
/* ICK! */
burn_proptree(DBFETCHPROP(thing));
DBSTOREPROP(thing, NULL);
DBDIRTY(thing);
notify(player, player, "Attributes wiped.");
}
void do_remit(dbref player, char *arg1, char *arg2)
{
dbref room;
match_data md;
char *rmno;
init_match(player, arg1, NOTYPE, &md);
match_here(&md);
match_absolute(&md);
match_neighbor(&md);
match_me(&md);
match_player(&md);
match_room_exits(DBFETCH(player)->location, &md);
switch (room = match_result(&md)) {
case NOTHING:
case AMBIGUOUS:
notify(player, player, "I can't find that.");
break;
default:
if (Typeof(room) == TYPE_EXIT) {
notify(player, player, "There can't be anything in that!");
break;
}
if (Typeof(room) == TYPE_PLAYER && Haven(room)) {
notify(player, player,
tprintf("I'm sorry, but %s wishes to be left alone now.",
unparse_name(room)));
break;
}
rmno = unparse_object(player, room);
notify(player, player,
tprintf("You remit, \"%s\" in %s", arg2, rmno));
oemit_notify_except(DBFETCH(room)->contents, player, room, arg2);
}
}
void do_oemit(dbref player, char *arg1, char *arg2)
{
dbref who;
dbref loc;
match_data md;
void oemit_notify_except();
init_match(player, arg1, TYPE_PLAYER, &md);
if ((loc = getloc(player)) == NOTHING)
return;
match_neighbor(&md);
match_me(&md);
switch (who = match_result(&md)) {
case NOTHING:
case AMBIGUOUS:
who = player;
default:
if (who != player)
notify_noecho(player, arg2);
oemit_notify_except(DBFETCH(loc)->contents, player, who, arg2);
}
}
void oemit_notify_except(dbref first, dbref exc1, dbref exc2, char *msg)
{
dbref loc = DBFETCH(first)->location;
dbref e;
char tbuf1[BUFFER_LEN];
if(first < 0 || first >= db_top) return;
if ((loc != exc1) && (loc != exc2))
esnotify(loc, msg, exc1);
DOLIST(first, first) {
if (first != exc1 && first != exc2) {
esnotify(first, msg, exc1);
}
}
/* do AUDIBLE stuff */
if (Audible(loc)) {
if (Typeof(loc) == TYPE_ROOM) {
strcpy(tbuf1, msg);
DOLIST(e, DBFETCH(loc)->exits) {
if (Audible(e))
propagate_sound(e, tbuf1);
}
} else {
strcpy(tbuf1, msg);
propagate_sound(loc, tbuf1);
}
}
}
void esnotify(dbref player, char *msg, dbref sender)
{
if (player < 0 || player >= db_top) return;
if (FLAGS(player) & NOSPOOF) {
#ifdef PARANOID_NOSPOOF
notify_noecho(player,
tprintf("[%s(#%d)] %s", spname(sender), sender, msg));
#else
notify_noecho(player, tprintf("[%s:] %s", spname(sender), msg));
#endif
} else {
notify_noecho(player, msg);
}
}
void do_emit(dbref player, char *tbuf1)
{
dbref loc;
if ((loc = getloc(player)) == NOTHING) return;
/* notify everybody */
notify_noecho(player, tbuf1);
emit_notify_except(DBFETCH(loc)->contents, player, tbuf1);
}
void emit_notify_except(dbref first, dbref exception, char *msg)
{
dbref loc = DBFETCH(first)->location;
dbref e;
char tbuf1[BUFFER_LEN];
if(first < 0 || first >= db_top) return;
if (loc != exception)
esnotify(loc, msg, exception);
DOLIST(first, first) {
if (first != exception) {
esnotify(first, msg, exception);
}
}
/* do AUDIBLE stuff */
if (Audible(loc)) {
if (Typeof(loc) == TYPE_ROOM) {
strcpy(tbuf1, msg);
DOLIST(e, DBFETCH(loc)->exits) {
if (Audible(e))
propagate_sound(e, tbuf1);
}
} else if (loc != exception) {
strcpy(tbuf1, msg);
propagate_sound(loc, tbuf1);
}
}
}
void do_decompile(dbref player, char *name)
{
dbref thing;
char *objct;
char tbuf[BUFFER_LEN];
char *attrib;
match_data md;
/* @decompile must always have an argument */
if (!name || !*name) {
notify(player, player, "What do you want to @decompile?");
return;
}
attrib = (char *) index(name, '/');
if (attrib)
*attrib++ = '\0';
/* find object */
init_match(player, name, NOTYPE, &md);
match_everything(&md);
if ((thing = noisy_match_result(&md)) == NOTHING)
return;
if (!Can_Examine(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
if (Typeof(thing) == TYPE_GARBAGE) {
notify(player, player, "Garbage is garbage.");
return;
}
/* if we have an attribute arg specified, wild match on it */
if (attrib && *attrib) {
decompile_atrs(player, thing, NAME(thing), attrib);
return;
}
/* else we have a full decompile */
/* determine creation and what we call the object */
switch (Typeof(thing)) {
case TYPE_PLAYER:
objct = "me";
break;
case TYPE_THING:
objct = NAME(thing);
notify(player, player, tprintf("@create %s", objct));
break;
case TYPE_ROOM:
notify(player, player, tprintf("@dig/teleport %s", NAME(thing)));
objct = "here";
break;
case TYPE_EXIT:
objct = NAME(thing);
notify(player, player, tprintf("@open %s", objct));
break;
}
if (Mobile(thing)) {
if (DBFETCH(thing)->link)
notify(player, player,
tprintf("@link %s = #%d", objct, DBFETCH(thing)->link));
else if (DBFETCH(thing)->link == HOME)
notify(player, player, tprintf("@link %s = HOME", objct));
} else {
if (GoodObject(Location(thing)))
notify(player, player,
tprintf("@tel %s = #%d", objct, Location(thing)));
else if (Location(thing) == HOME)
notify(player, player, tprintf("@tel %s = HOME", objct));
}
sprintf(tbuf, "%s", unparse_boolexp(player, DBFETCH(thing)->key));
if (strcmp(tbuf, "*UNLOCKED*"))
notify(player, player, tprintf("@lock %s = %s", objct, tbuf));
if(GET_SUCC(thing))
{
sprintf(tbuf, "@succ %s=%s", objct, GET_SUCC(thing));
notify(player, player, tbuf);
}
if(GET_FAIL(thing))
{
sprintf(tbuf, "@fail %s=%s", objct, GET_FAIL(thing));
notify(player, player, tbuf);
}
if (GET_DROP(thing))
{
sprintf(tbuf, "@drop %s=%s", objct, GET_DROP(thing));
notify(player, player, tbuf);
}
if(GET_OSUCC(thing))
{
sprintf(tbuf, "@osucc %s=%s", objct, GET_OSUCC(thing));
notify(player, player, tbuf);
}
if(GET_OFAIL(thing))
{
sprintf(tbuf, "@ofail %s=%s", objct, GET_OFAIL(thing));
notify(player, player, tbuf);
}
if(GET_ODROP(thing))
{
sprintf(tbuf, "@odrop %s=%s", objct, GET_ODROP(thing));
notify(player, player, tbuf);
}
decompile_flags(player, thing, objct);
decompile_atrs(player, thing, objct, "*");
}
void decompile_atrs(dbref player, dbref thing, char *name, char *pattern)
{
propdir *ptr;
for (ptr = DBFETCHPROP(thing); ptr; ptr = ptr->next) {
if (wild_match(pattern, ptr->name)) {
#ifdef COMPRESS
if(ptr->data)
notify(player, player, tprintf("@set %s=%s:%s", name, ptr->name,
uncompress(ptr->data)));
#else
if(ptr->data)
notify(player, player, tprintf("@set %s=%s:%s", name,
ptr->name, ptr->data));
#endif
}
}
}
void do_grep(dbref player, char *obj, char *lookfor, int flag)
{
dbref thing;
char *pattern, *tp;
match_data md;
int len;
if ((len = strlen(lookfor)) < 1) {
notify(player, player, "What pattern do you want to grep for?");
return;
}
/* find the attribute pattern */
pattern = (char *) index(obj, '/');
if (!pattern)
pattern = (char *) "*"; /* set it to global match */
else
*pattern++ = '\0';
/* now we've got the object. match for it. */
init_match(player, obj, NOTYPE, &md);
match_everything(&md);
thing = noisy_match_result(&md);
if (thing == NOTHING)
return;
if (!Can_Examine(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
notify(player, player,
tprintf("The following attributes on %s have contents matching '%s':",
unparse_name(thing), lookfor));
tp = grep_util(thing, pattern, lookfor, len);
notify(player, player, tp);
if(tp) free(tp);
}
/* returns a list of attributes which match <pattern> on <thing>
* whose contents have <lookfor> */
char *grep_util(dbref thing, char *pattern, char *lookfor, int len)
{
char *tbuf1;
char *s, *bp;
int found;
propdir *a;
tbuf1 = (char *) malloc(BUFFER_LEN + 1);
bp = tbuf1;
for (a = DBFETCHPROP(thing); a; a = a->next) {
if (wild_match(pattern, a->name)) {
s = (char *) uncompress(a->data); /* warning: static */
found = 0;
while (*s && !found) {
if (!strncmp(lookfor, s, len))
found = 1;
else
s++;
}
if (found) {
if (bp != tbuf1)
safe_chr(' ', tbuf1, &bp);
safe_str(a->name, tbuf1, &bp);
}
}
}
*bp = '\0';
return tbuf1;
}
void do_clone(dbref player, char *name)
{
dbref clone, thing;
match_data md;
init_match(player, name, NOTYPE, &md);
match_everything(&md);
thing = noisy_match_result(&md);
if ((thing == NOTHING)) return;
if (!controls(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
/* make sure owner can afford it */
switch (Typeof(thing)) {
case TYPE_THING:
if (!Builder(player)) {
notify(player, player, "Command is for builders only.");
return;
}
if (!Wizard(player)) {
if (!payfor(player, OBJECT_DEPOSIT(DBFETCH(thing)->pennies)))
notify(player, player, tprintf("You don't have enough %s.", PL_MONEY));
}
clone = new_object();
*DBFETCH(clone)= *DBFETCH(thing);
DBSTORE(clone, name, dup_string(NAME(thing)));
#ifndef USE_DBP_STR
DBSTORE(clone, desc, dup_string(GET_DESC(thing)));
DBSTORE(clone, succ, dup_string(GET_SUCC(thing)));
DBSTORE(clone, fail, dup_string(GET_FAIL(thing)));
DBSTORE(clone, drop, dup_string(GET_DROP(thing)));
DBSTORE(clone, osucc, dup_string(GET_OSUCC(thing)));
DBSTORE(clone, ofail, dup_string(GET_OFAIL(thing)));
DBSTORE(clone, odrop, dup_string(GET_ODROP(thing)));
#else
add_property(clone, "desc", GET_DESC(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_SUCC(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_FAIL(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_DROP(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_OSUCC(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_OFAIL(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
add_property(clone, "desc", GET_ODROP(thing), PERMS_COREAD | PERMS_COWRITE |
PERMS_OTREAD, ACCESS_CO);
#endif
DBSTORE(clone, pennies, DBFETCH(thing)->pennies);
DBSTORE(clone, key, copy_bool(DBFETCH(thing)->key));
DBSTORE(clone, exits, NOTHING);
copy_prop(thing, clone, access_rights(player, thing, NOTHING));
add_backlocks_parse(clone, DBFETCH(clone)->key);
add_ownerlist(clone);
add_backlinks(clone);
moveto(clone, DBFETCH(player)->location);
FLAGS(clone) &= ~WIZARD; /* Don't let cloned object inherit privs */
FLAGS(clone) &= ~GOD;
DBDIRTY(clone);
notify(player, player, tprintf("Cloned: Object #%ld.", clone));
did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING);
break;
default:
notify(player, player, "You can only clone things.");
}
}
void do_search(dbref player, char *arg1, char *arg3[])
{
int flag;
char *arg2;
dbref thing;
dbref from;
/* dbref to; */
int is_wizard;
int destitute = 1;
char *restrict_name;
dbref restrict_owner = NOTHING;
dbref restrict_zone = NOTHING;
dbref restrict_parent = NOTHING;
object_flag_type flag_mask, toggle_mask, restrict_type;
object_flag_type power_mask;
char tbuf1[BUFFER_LEN], tmp[BUFFER_LEN];
int rcount, ecount, pcount, ocount, i=0;
struct dbref_list *found = NULL, *ptr = NULL, *rlist = NULL,
*elist = NULL, *olist = NULL, *plist = NULL;
int bot = 0;
int top = db_top;
match_data md;
/*
if (o_daytime) {
notify(player, "Sorry, that command has been temporarily disabled.");
return;
}
*/
/* make sure player has money to do the search */
if (!payfor(player, LOOKUP_COST)) {
notify(player, player, tprintf("Searches cost %d %s.", LOOKUP_COST,
((LOOKUP_COST == 1) ? S_MONEY : PL_MONEY)));
return;
}
/* 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[1] || !*arg3[1])
arg2 = (char *) ""; /* arg1 */
else {
arg2 = (char *) arg1; /* arg2, arg3 */
arg1 = (char *) "";
}
}
is_wizard = Wizard(player);
/* set limits on who we search */
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, player, tprintf("%s: No such player.", arg1));
return;
}
/* set limits on what we search for */
flag = 0;
flag_mask = 0;
power_mask = 0;
toggle_mask = 0;
restrict_name = NULL;
restrict_type = NOTYPE;
switch (arg2[0]) {
case '\0':
/* the no class requested class :) */
break;
case 'e':
case 'E':
if (string_prefix("exits", arg2)) {
restrict_name = (char *) arg3[1];
restrict_type = TYPE_EXIT;
} else
flag = 1;
break;
case 'f':
case 'F':
if (string_prefix("flags", arg2)) {
/*
* convert_flags ignores previous values of flag_mask and
* restrict_type while setting them
*/
if (arg3[1] && *arg3[1] &&
!convert_flags(player, arg3[1], &flag_mask, &toggle_mask,
&restrict_type))
return;
} else
flag = 1;
break;
case 'n':
case 'N':
if (string_prefix("name", arg2))
restrict_name = (char *) arg3[1];
else
flag = 1;
break;
case 'o':
case 'O':
if (string_prefix("objects", arg2)) {
restrict_name = (char *) arg3[1];
restrict_type = TYPE_THING;
} else
flag = 1;
break;
case 'p':
case 'P':
switch (arg2[1]) {
case 'a':
case 'A':
if (string_prefix("parent", arg2)) {
if (arg3[1] && *arg3[1]) {
init_match(player, arg3[1], NOTYPE, &md);
match_absolute(&md);
restrict_parent = match_result(&md);
}
if (restrict_parent == NOTHING) {
notify(player, player, "Unknown parent.");
return;
}
} else
flag = 1;
break;
case 'l':
case 'L':
if (string_prefix("players", arg2)) {
restrict_name = (char *) arg3[1];
if (!arg1 || !*arg1)
restrict_owner = ANY_OWNER;
restrict_type = TYPE_PLAYER;
} else
flag = 1;
break;
case 'o':
case 'O':
if (string_prefix("powers", arg2)) {
/* power_mask = find_power(arg3[1]); */
power_mask = -1;
if (power_mask == -1) {
notify(player, player, "No such power to search for.");
return;
}
} else
flag = 1;
break;
default:
flag = 1;
}
break;
case 'r':
case 'R':
if (string_prefix("rooms", arg2)) {
restrict_name = (char *) arg3[1];
restrict_type = TYPE_ROOM;
} else
flag = 1;
break;
case 't':
case 'T':
if (string_prefix("type", arg2)) {
if (!arg3[1] || !*arg3[1])
break;
if (string_prefix("rooms", arg3[1]))
restrict_type = TYPE_ROOM;
else if (string_prefix("exits", arg3[1]))
restrict_type = TYPE_EXIT;
else if (string_prefix("objects", arg3[1]))
restrict_type = TYPE_THING;
else if (string_prefix("players", arg3[1])) {
if (!arg1 || !*arg1)
restrict_owner = ANY_OWNER;
restrict_type = TYPE_PLAYER;
} else {
notify(player, player, tprintf("%s: unknown type.", arg3[1]));
return;
}
} else
flag = 1;
break;
case 'z':
case 'Z':
if (string_prefix("zone", arg2)) {
if (arg3[1] && *arg3[1]) {
init_match(player, arg3[1], TYPE_THING, &md);
match_absolute(&md);
restrict_zone = match_result(&md);
}
if (restrict_zone == NOTHING) {
notify(player, player, "Unknown zone.");
return;
}
} else
flag = 1;
break;
default:
flag = 1;
}
if (flag) {
notify(player, 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, player, "You need a search warrant to do that!");
return;
}
/* find range */
if (arg3[2] && *arg3[2])
bot = atoi(arg3[2]);
if (bot < 0)
bot = 0;
if (arg3[3] && *arg3[3])
top = atoi(arg3[3]) + 1;
if (top > db_top)
top = db_top;
/* the search loop here */
flag = 1;
for (thing = bot; thing < 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 ((FLAGS(thing) & flag_mask) != flag_mask)
continue;
if (Typeof(thing) == TYPE_GARBAGE)
continue;
/*
if ((Toggles(thing) & toggle_mask) != toggle_mask)
continue;
if ((Powers(thing) & power_mask) != power_mask)
continue;
*/
if ((restrict_owner != ANY_OWNER) && (restrict_owner != OWNER(thing)))
continue;
if (restrict_name != NULL)
if (!string_match(unparse_name(thing), restrict_name))
continue;
if (restrict_parent != NOTHING)
if (restrict_parent != Parent(thing))
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, 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, player, "\nROOMS:");
for (ptr = rlist; ptr; ptr = ptr->next) {
sprintf(tbuf1, "%s [owner: ", unparse_object(player, ptr->object));
strcat(tbuf1, tprintf("%s]",
unparse_object(player, DBFETCH(ptr->object)->owner)));
notify(player, player, tbuf1);
rcount++;
}
}
if (restrict_type == TYPE_EXIT || restrict_type == NOTYPE) {
notify(player, player, "\nEXITS:");
for (ptr = elist; ptr; ptr = ptr->next) {
from = DBFETCH(ptr->object)->location;
sprintf(tbuf1, "%s [from ", unparse_object(player, ptr->object));
sprintf(tmp, "%s to ", unparse_object(player, from));
strcat(tbuf1, tmp);
if (DBFETCH(ptr->object)->sp.exit.ndest > 0) {
for (i = 0; i < DBFETCH(ptr->object)->sp.exit.ndest; i++)
strcat(tbuf1, tprintf("%s]", unparse_object(player,
(DBFETCH(ptr->object)->sp.exit.dest)[i])));
} else
strcat(tbuf1, tprintf("%s]", "NOWHERE"));
notify(player, player, tbuf1);
ecount++;
}
}
if (restrict_type == TYPE_THING || restrict_type == NOTYPE) {
notify(player, player, "\nOBJECTS:");
for (ptr = olist; ptr; ptr = ptr->next) {
sprintf(tbuf1, "%s [owner: ", unparse_object(player, ptr->object));
strcat(tbuf1, tprintf("%s]",
unparse_object(player, DBFETCH(ptr->object)->owner)));
notify(player, player, tbuf1);
ocount++;
}
}
if ((restrict_type == TYPE_PLAYER) || (restrict_type == NOTYPE)) {
notify(player, player, "\nPLAYERS:");
for (ptr = plist; ptr; ptr = ptr->next) {
strcpy(tbuf1, unparse_object(player, ptr->object));
if (is_wizard) {
strcat(tbuf1, " [location: ");
strcat(tbuf1, unparse_object(player, DBFETCH(ptr->object)->location));
strcat(tbuf1, "]");
}
notify(player, player, tbuf1);
pcount++;
}
}
notify(player, player, "---------- Search Done ----------");
notify(player, 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);
}
void do_whereis(dbref player, char *name)
{
dbref thing;
char buff[BUFFER_LEN];
if (*name == '\0') {
notify(player, player, "You must specify a valid player name.");
return;
}
if ((thing = lookup_player(name)) == NOTHING) {
notify(player, player, "That player does not seem to exist.");
return;
}
if (Unfindable(thing) || Unfindable(Location(thing))) {
notify(player, player, "That player wishes to have some privacy.");
notify(thing, thing, tprintf("%s tried to locate you and failed.",
unparse_name(player)));
return;
}
strcpy(buff, unparse_name(thing));
notify(player, player, tprintf("%s is at: %s.", buff,
unparse_object(player, DBFETCH(thing)->location)));
notify(thing, thing, tprintf("%s has just located your position.",
unparse_name(player)));
}
void do_parent(dbref player, char *name, char *parent_name)
{
dbref thing;
dbref parent;
dbref check;
match_data md;
char temp[100];
int i;
init_match(player, name, NOTYPE, &md);
match_nearby(&md);
if ((thing = noisy_match_result(&md)) == NOTHING) return;
/* players may not be parented */
if (Typeof(thing) == TYPE_PLAYER) {
notify(player, player, "Don't you like your biological parents?");
return;
}
if (!parent_name || !*parent_name || !strcasecmp(parent_name, "none"))
parent = NOTHING;
else {
init_match(player, parent_name, NOTYPE, &md);
match_everything(&md);
if ((parent = noisy_match_result(&md)) == NOTHING)
return;
}
/* do control check */
if (!controls(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
/* a player may change an object's parent to NOTHING or to an
* object he owns, or one that is LINK_OK.
*/
if ((parent != NOTHING) && !Wizard(player) &&
(OWNER(parent) != player) && !LinkOk(parent)) {
notify(player, player, "Permission denied.");
return;
}
/* check to make sure no recursion can happen */
if (parent == thing) {
notify(player, player, "A thing cannot be its own ancestor!");
return;
}
if (parent != NOTHING) {
for (i = 0, check = Parent(parent);
(i < MAX_PARENTS) && (check != NOTHING);
i++, check = Parent(check)) {
if (check == thing) {
notify(player, player, "You are not allowed to be your own ancestor!");
return;
}
}
if (i >= MAX_PARENTS) {
notify(player, player, "Too many ancestors.");
return;
}
}
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
/* everything is okay, do the change */
if(parent != NOTHING) {
sprintf(temp, "%ld", parent);
add_property(thing, "*PARENT", temp, default_perms("*PARENT"), ACCESS_WI);
sprintf(temp, "Parent changed to %s.", unparse_name(parent));
} else {
remove_property(thing, "*PARENT", ACCESS_WI);
strcpy(temp, "Parent deleted.");
}
notify(player, player, temp);
}
void do_think(dbref player, char *message)
{
/* privately tell yourself a message */
/* notify the player only, with no special fanfare */
notify(player, player, tprintf("%s", message));
}
/* scan for possible matches of user-def'ed commands */
void do_scan(dbref player, char *command, int flag)
{
#define ScanFind(p,x) \
(Can_Examine(p,x) && \
((num = atr_comm_match(x, p, '$', ':', command, 1)) != 0))
dbref thing;
int num;
if (!GoodObject(Location(player))) {
notify(player, player, "Sorry, you are in an invalid location.");
return;
}
if (!command || !*command) {
notify(player, player, "What command do you want to scan for?");
return;
}
if (flag & CHECK_NEIGHBORS) {
notify(player, player, "Matches on contents of this room:");
DOLIST(thing, DBFETCH(Location(player))->contents) {
if (ScanFind(player, thing))
notify(player, player,
tprintf("%s [%d]", unparse_object(player, thing), num));
}
}
if (flag & CHECK_HERE) {
if (ScanFind(player, Location(player)))
notify(player, player, tprintf("Matched here: %s [%d]",
unparse_object(player, Location(player)), num));
}
if (flag & CHECK_INVENTORY) {
notify(player, player, "Matches on carried objects:");
DOLIST(thing, DBFETCH(player)->contents) {
if (ScanFind(player, thing))
notify(player, player, tprintf("%s [%d]",
unparse_object(player, thing), num));
}
}
if (flag & CHECK_SELF) {
if (ScanFind(player, player))
notify(player, player, tprintf("Matched self: %s [%d]",
unparse_object(player, player), num));
}
if (flag & CHECK_ZONE) {
/*
if (Zone(Location(player)) != NOTHING) {
if (Typeof(Zone(Location(player))) == TYPE_ROOM) {
if (Location(player) != Zone(player)) {
notify(player, player, "Matches on parent room of location:");
DOLIST(thing, db[Zone(Location(player))].contents) {
if (ScanFind(player, thing))
notify(player, player, tprintf("%s [%d]",
unparse_object(player, thing), num));
}
}
} else {
if (ScanFind(player, Zone(Location(player))))
notify(player, player,
tprintf("Matched zone of location: %s [%d]",
unparse_object(player, Zone(Location(player))), num));
}
}
if ((Zone(player) != NOTHING) &&
(Zone(player) != Zone(Location(player)))) {
if (ScanFind(player, Zone(player)))
notify(player, player, tprintf("Matched personal zone: %s [%d]",
unparse_object(player, Zone(player)), num));
}
*/
notify(player, player, "Zones arn't supported on this MUD.");
}
#ifdef DO_GLOBALS
if ((flag & CHECK_GLOBAL) && (Location(player) != GLOBAL_ENVIRONMENT)) {
/* try Master Room stuff */
notify(player, player, "Matches on objects in the Master Room:");
DOLIST(thing, DBFETCH(GLOBAL_ENVIRONMENT)->contents) {
if (ScanFind(player, thing))
notify(player, player, tprintf("%s [%d]",
unparse_object(player, thing), num));
}
}
#endif /* DO_GLOBALS */
}
void do_cpattr(dbref player, char *oldpair, char *newpair[])
{
/* the command is of the format:
* @cpattr oldobj/oldattr = newobj1/newattr1, newobj2/newattr2, etc.
*/
dbref oldobj;
char tbuf1[BUFFER_LEN], tmp[BUFFER_LEN];
char *p, *a, *text;
match_data md;
int i, j;
/* must copy from something */
if (!oldpair || !*oldpair) {
notify(player, player, "What do you want to copy from?");
return;
}
/* find the old object */
strcpy(tbuf1, oldpair);
p = (char *) index(tbuf1, '/');
if (!p || !*p) {
notify(player, player,
"What object do you want to copy the attribute from?");
return;
}
*p++ = '\0';
init_match(player, tbuf1, NOTYPE, &md);
match_everything(&md);
oldobj = noisy_match_result(&md);
if (oldobj == NOTHING) return;
strcpy(tmp, p);
j=strlen(tmp);
for(i=0; i < j; i++)
if(tmp[i] == ' ') tmp[i] = '\0';
/* find the old attribute */
a = get_property_data(oldobj, tmp, access_rights(player, oldobj, NOTHING));
if (!a) {
notify(player, player, "No such attribute to copy from.");
return;
}
/* we can read it. Copy the value. */
text = a;
/* now we loop through our new object pairs and copy, calling @set. */
i=1;
while (i < MAX_MUSH_ARG && newpair[i]) {
if (!*newpair[i]) {
notify(player, player, "What do you want to copy to?");
} else {
strcpy(tbuf1, newpair[i]);
p = (char *) index(tbuf1, '/');
if (!p || !*p) {
notify(player, player,
"What object do you want to copy the attribute to?");
} else {
*p++ = '\0';
do_set(player, tbuf1, tprintf("%s:%s", p, text), tbuf1);
}
}
i++;
}
notify(player, player, "Attributes copied.");
}
void do_leave(dbref player)
{
if (Typeof(Location(player)) == TYPE_ROOM) {
notify(player, player, "You can't leave");
return;
}
enter_room(player, DBFETCH(DBFETCH(player)->location)->location,
DBFETCH(player)->location);
}
void do_mush_examine(dbref player, char *name, int brief)
{
dbref thing, content, exit_dbref;
char *tp;
char *real_name = NULL, *attrib_name = NULL;
char tbuf[BUFFER_LEN];
match_data md;
int ok = 0;
if (*name == '\0') {
if ((thing = Location(player)) == NOTHING)
return;
attrib_name = NULL;
} else {
if ((attrib_name = (char *) index(name,'/')) != NULL) {
*attrib_name = '\0';
attrib_name++;
}
real_name = (char *)name;
/* look it up */
init_match(player, real_name, NOTYPE, &md);
match_everything(&md);
if(Wizard(player))
match_absolute(&md);
/* get result */
if ((thing = noisy_match_result(&md)) == NOTHING)
return;
}
/* can't examine destructed objects */
if (Typeof(thing) == TYPE_GARBAGE) {
notify(player, player, "Garbage is garbage.");
return;
}
/* only look at some of the attributes */
if (attrib_name && *attrib_name) {
examine_properties(player, thing, attrib_name, 0);
return;
}
ok = Can_Examine(player, thing);
#ifdef EX_PUBLIC_ATTRIBS
if (!ok && !nearby(player, thing)) {
#else
if (!ok) {
#endif /* EX_PUBLIC_ATTRIBS */
/* if it's not examinable and we're not near it, we can only get the
* name and the owner.
*/
tp = tbuf;
safe_str(unparse_object(player, thing), tbuf, &tp);
safe_str((char *)" is owned by ", tbuf, &tp);
safe_str(unparse_object(player, OWNER(thing)), tbuf, &tp);
*tp = '\0';
notify(player, player, tbuf);
return;
}
if (ok) {
notify(player, player, unparse_object(player, thing));
#ifdef FLAGS_ON_EXAMINE
notify(player, player, flag_description(player, thing));
#endif
}
#ifdef EX_PUBLIC_ATTRIBS
if (!brief) {
a = atr_get_noparent(thing, "DESCRIBE");
if (a) {
r = safe_uncompress(a->value);
notify(player, player, r);
free(r);
}
}
#endif
if (ok) {
notify(player, player,
tprintf("Owner: %s Key: %s %s: %d",
unparse_name(OWNER(thing)),
unparse_boolexp(player, DBFETCH(thing)->key),
PL_MONEY, DBFETCH(thing)->pennies));
if (Typeof(thing) != TYPE_PLAYER)
notify(player, player, tprintf("Parent: %s",
unparse_object(player, Parent(thing))));
notify(player, player,
tprintf("Zone: %s", unparse_object(player, Zone(thing))));
notify(player, player, tprintf("Use Key: %s",
unparse_boolexp(player,
get_ue_locks(player, thing, USELOCK))));
if (Typeof(thing) == TYPE_ROOM)
notify(player, player, tprintf("Teleport Key: %s",
unparse_boolexp(player,
get_ue_locks(player, thing, ENTERLOCK))));
else
notify(player, player, tprintf("Enter Key: %s",
unparse_boolexp(player,
get_ue_locks(player, thing, ENTERLOCK))));
/* notify(player, player, powers_descriptions(thing)); */
#if (CHAT_SYSTEM >= 2)
if (Typeof(thing) == TYPE_PLAYER)
notify(player, player, channel_description(thing));
#endif /* CHAT_SYSTEM */
}
#ifdef EX_PUBLIC_ATTRIBS
if (!brief) {
#else
if (!brief && ok) {
#endif /* EX_PUBLIC_ATTRIBS */
examine_properties(player, thing, "", 0);
}
/* show contents */
if (Contents(thing) != NOTHING) {
notify(player, player, "Contents:");
DOLIST(content, Contents(thing)) {
if (ok || controls(player, content) ||
(!Dark(content) &&
!((Typeof(content) == TYPE_PLAYER) &&
(Connected(content)))))
notify(player, player, unparse_object(player, content));
}
}
if (!ok) {
/* if not examinable, just show obvious exits and name and owner */
if (Typeof(thing) == TYPE_ROOM)
examine_exits(player, thing, "", 0);
tp = tbuf;
safe_str(unparse_object(player, thing), tbuf, &tp);
safe_str((char *)" is owned by ", tbuf, &tp);
safe_str(unparse_object(player, OWNER(thing)), tbuf, &tp);
*tp = '\0';
notify(player, player, tbuf);
return;
}
switch (Typeof(thing)) {
case TYPE_ROOM:
/* tell him about exits */
if (DBFETCH(thing)->exits != NOTHING) {
notify(player, player, "Exits:");
DOLIST(exit_dbref, DBFETCH(thing)->exits)
notify(player, player, unparse_object(player, exit_dbref));
} else
notify(player, player, "No exits.");
/* print dropto if present */
if (Location(thing) != NOTHING) {
notify(player, player,
tprintf("Dropped objects go to: %s",
unparse_object(player, Location(thing))));
}
break;
case TYPE_THING:
case TYPE_PLAYER:
/* print home */
notify(player, player,
tprintf("Home: %s",
unparse_object(player, DBFETCH(thing)->link)));
/* print location if player can link to it */
if (Location(thing) != NOTHING)
notify(player, player,
tprintf("Location: %s",
unparse_object(player, Location(thing))));
break;
case TYPE_EXIT:
/* print source */
switch (DBFETCH(thing)->location) {
case NOTHING:
fprintf(stderr,
"*** BLEAH *** Weird exit %s(#%d) in #%d with source NOTHING.\n",
unparse_name(thing), thing, Location(thing));
break;
case HOME:
fprintf(stderr,
"*** BLEAH *** Weird exit %s(#%d) in #%d with source HOME.\n",
unparse_name(thing), thing, Location(thing));
break;
default:
notify(player, player,
tprintf("Source: %s",
unparse_object(player, DBFETCH(thing)->location)));
break;
}
/* print destination */
switch (Location(thing)) {
case NOTHING:
notify(player, player, "Destination: *UNLINKED*");
break;
case HOME:
notify(player, player, "Destination: *HOME*");
break;
default:
notify(player, player,
tprintf("Destination: %s",
unparse_object(player, Location(thing))));
break;
}
break;
default: /* do nothing */
break;
}
}
void do_mush_lock(dbref player, char *name, char *keyname, int locktype)
{
dbref thing = NOTHING;
match_data md;
boolexp *key;
char *sp;
/* check for '@lock <object>/<atr>' */
sp = (char *) index(name, '/');
if (sp) {
notify(player, player, "Please use the @permissions command instead.");
return;
}
init_match(player, name, NOTYPE, &md);
match_everything(&md);
switch ((thing = match_result(&md))) {
case NOTHING:
notify(player, player, "I don't see what you want to lock!");
return;
case AMBIGUOUS:
notify(player, player, "I don't know which one you want to lock!");
return;
default:
if (!controls(player, thing)) {
notify(player, player, "You can't lock that!");
return;
}
if (Typeof(thing) == TYPE_GARBAGE) {
notify(player, player, "Why would you want to lock garbage?");
return;
}
break;
}
if(!keyname || !*keyname) {
notify(player, player, "Empty key.");
return;
}
key = parse_boolexp(player, keyname);
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
/* do the lock */
if (key == TRUE_BOOLEXP) {
notify(player, player, "I don't understand that key.");
} else {
/* everything ok, do it */
switch (locktype) {
case BASICLOCK:
remove_backlocks_parse(thing, DBFETCH(thing)->key);
free_boolexp(DBFETCH(thing)->key);
DBSTORE(thing, key, key);
add_backlocks_parse(thing, DBFETCH(thing)->key);
break;
case USELOCK:
do_use_enterlocks(thing, keyname, locktype, 1);
break;
case ENTERLOCK:
do_use_enterlocks(thing, keyname, locktype, 1);
break;
}
notify(player, player, "Locked.");
}
}
void do_mush_unlock(dbref player, char *name, int locktype)
{
dbref thing;
char *sp;
/* check for '@unlock <object>/<atr>' */
sp = (char *) index(name, '/');
if (sp) {
notify(player, player, "Please use the @permissions command instead.");
return;
}
if ((thing = match_controlled(player, name)) != NOTHING) {
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
switch (locktype) {
case BASICLOCK:
remove_backlocks_parse(thing, DBFETCH(thing)->key);
free_boolexp(DBFETCH(thing)->key);
DBSTORE(thing, key, TRUE_BOOLEXP);
break;
case USELOCK:
do_use_enterlocks(thing, name, locktype, 0);
break;
case ENTERLOCK:
do_use_enterlocks(thing, name, locktype, 0);
break;
}
notify(player, player, "Unlocked.");
}
}
void do_debug_examine(dbref player, char *name)
{
dbref thing, tmp;
match_data md;
int i;
if (!Wizard(player)) {
notify(player, player, "Permission denied.");
return;
}
/* find it */
init_match(player, name, NOTYPE, &md);
match_everything(&md);
thing = noisy_match_result(&md);
if (thing == NOTHING) return;
if (Typeof(thing) == TYPE_GARBAGE) {
notify(player, player, "Garbage is garbage.");
return;
}
notify(player, player, unparse_object(player, thing));
notify(player, player, tprintf("Flags value: %d", FLAGS(thing)));
/* notify(player, player, tprintf("Toggles value: %d", Toggles(thing)));
notify(player, player, tprintf("Powers value: %d", Powers(thing))); */
if(DBFETCH(thing)->next != NOTHING)
notify(player, player, tprintf("Next: %d", DBFETCH(thing)->next));
if(DBFETCH(thing)->contents != NOTHING)
DOLIST(tmp, DBFETCH(thing)->contents)
notify(player, player, tprintf("Content: %d", tmp));
switch (Typeof(thing)) {
case TYPE_PLAYER:
notify(player, player, tprintf("Location: %d", DBFETCH(thing)->location));
notify(player, player, tprintf("Home: %d", DBFETCH(thing)->link));
if(DBFETCH(thing)->exits != NOTHING)
DOLIST(tmp, DBFETCH(thing)->exits)
notify(player, player, tprintf("Exit: %d", tmp));
break;
case TYPE_THING:
notify(player, player, tprintf("Location: %d", DBFETCH(thing)->location));
notify(player, player, tprintf("Home: %d", DBFETCH(thing)->link));
if(DBFETCH(thing)->exits != NOTHING)
DOLIST(tmp, DBFETCH(thing)->exits)
notify(player, player, tprintf("Exit: %d", tmp));
break;
case TYPE_EXIT:
notify(player, player, tprintf("Source: %d", DBFETCH(thing)->location));
if (DBFETCH(thing)->sp.exit.ndest > 0)
{
for (i = 0; i < DBFETCH(thing)->sp.exit.ndest; i++)
{
notify(player, player, tprintf("Destination: %s",
unparse_object_full(player, (DBFETCH(thing)->sp.exit.dest)[i])));
}
}
break;
case TYPE_ROOM:
notify(player, player, tprintf("Drop-to: %d", DBFETCH(thing)->location));
if(DBFETCH(thing)->exits != NOTHING)
DOLIST(tmp, DBFETCH(thing)->exits)
notify(player, player, tprintf("Exit: %d", tmp));
break;
default:
notify(player, player, "Bad object type.");
}
}
void do_config(dbref player, int type)
{
if (type == 2) {
notify(player, player, "Building costs:");
notify(player, player, tprintf(" Object creation....%d", OBJECT_COST));
notify(player, player, tprintf(" Room creation......%d", ROOM_COST));
notify(player, player, tprintf(" Exit creation......%d", EXIT_COST));
notify(player, player, tprintf(" Linking............%d", LINK_COST));
notify(player, player, tprintf(" Queueing cost......%d", Q_COST));
notify(player, player, tprintf(" Quota per object...%d", QUEUE_QUOTA));
notify(player, player, "Command costs:");
notify(player, player, tprintf(" page...............%d", LOOKUP_COST));
notify(player, player, tprintf(" @find..............%d", LOOKUP_COST));
notify(player, player, tprintf(" kill base cost.....%d", KILL_BASE_COST));
notify(player, player, tprintf(" kill minimum cost..%d", KILL_MIN_COST));
notify(player, player, tprintf(" kill insurance.....%d", KILL_BONUS));
return;
}
if (type == 1) {
notify(player, player, "Global parameters:");
notify(player, player, tprintf(" Logins............%s",
(!wiz_only_flag) ? "enabled" : "disabled"));
notify(player, player, tprintf(" Log commands......%s",
(o_log_commands) ? "enabled" : "disabled"));
notify(player, player, tprintf(" Log huhs..........%s",
(o_log_huhs) ? "enabled" : "disabled"));
notify(player, player, tprintf(" Log forces........%s", "enabled"));
return;
}
notify(player, player,
"Players without a BUILDER bit cannot build anything.");
if (o_lockouts)
notify(player, player, "Site lockout is enabled.");
else
notify(player, player, "Site lockout is not enabled.");
#ifdef TIMESTAMPS
notify(player, player, "Timestamps are enabled.");
#else
notify(player, player, "Timestamps are not enabled.");
#endif
#ifdef PLAYER_CHOWN
notify(player, player, "The @chown command and CHOWN_OK flag is enabled.");
#else
notify(player, player, "The @chown command and CHOWN_OK flag is not enabled.");
#endif
#ifdef COMPRESS
notify(player, player, "String compression is enabled.");
#else
notify(player, player, "String compression is not enabled.");
#endif
#ifdef GOD_PRIV
notify(player, player, "God privs are enabled.");
#else
notify(player, player, "God privs are not enabled.");
#endif
if(o_mufconnects)
notify(player, player, "MUF connects/disconnects are enabled.");
else
notify(player, player, "MUF connects/disconnects are not enabled.");
if(o_taboonames)
notify(player, player, "Player taboo names are enabled.");
else
notify(player, player, "Player taboo names are not enabled.");
if(o_registration) {
notify(player, player, "Selective player registration is in effect.");
} else {
notify(player, player, "Player registration is not in effect.");
}
notify(player, player, "Expanded flag list is shown on examines.");
#ifdef FULL_INVIS
notify(player, player, "Dark players/objects show up as Someone/Something.");
#else
notify(player, player, "Dark players/objects are not totally anonymous.");
#endif
notify(player, player, "Nospoof notification shows name and object number.");
notify(player, player,
"The location of players set UNFINDABLE can't be found.");
notify(player, player, "Players cannot @listen.");
notify(player, player,
tprintf("Player name limit is %d characters.", PLAYER_NAME_LIMIT));
#ifdef NOFORK
notify(player, player, "Forking is disabled. Game will freeze during dumps.");
#else
#ifdef USE_VFORK
notify(player, player, "Vfork is enabled. Game will freeze during dumps.");
#endif
notify(player, player, "There should be no slowdown due to database saves.");
#endif
notify(player, player, tprintf("The database is being saved every %d seconds.",
DUMP_INTERVAL));
if(o_rwho) {
notify(player, player, tprintf("The RWHO server is %s",
get_property_data((dbref) 0, RWHO_SERVER, ACCESS_WI)));
} else {
notify(player, player, "The MUCK is not connected to an RWHO server.");
}
notify(player, player, tprintf("The starting location of players is #%d.",
PLAYER_START));
notify(player, player,
tprintf("The master room is #%d.", GLOBAL_ENVIRONMENT));
notify(player, player, "There is no internal guest character.");
notify(player, player, tprintf("The maximum number of queued commands is %d.",
QUEUE_QUOTA));
notify(player, player, tprintf("Queueing commands costs %d.", Q_COST));
notify(player, player, tprintf("This server is running version %s", VERSION));
}
void do_gedit(dbref player, char *it, char *argv[])
{
propdir *a;
dbref thing;
match_data md;
char tbuf1[BUFFER_LEN];
char *p, *q;
int is_wild = 0;
if(!(it && *it)) {
notify(player, player, "I need to know what you want to edit.");
return;
}
strcpy(tbuf1, it);
q = (char *) index(tbuf1, '/');
if (!(q && *q)) {
notify(player, player, "I need to know what you want to edit.");
return;
}
*q++ = '\0';
init_match(player, tbuf1, NOTYPE, &md);
match_everything(&md);
thing = noisy_match_result(&md);
if ((thing == NOTHING) || !controls(player, thing)) {
notify(player, player, "Permission denied.");
return;
}
if(*q == '_') q++;
if (!argv[1] || !*argv[1]) {
notify(player, player, "Nothing to do.");
return;
}
/* first let's check for wildcard characters */
for (p = q; *p && !is_wild; p++)
if ((*p == '*') || (*p == '?'))
is_wild = 1;
if (!is_wild) {
/* we only have one attribute. Check for possible abbreviation,
* then edit that the attribute with that name.
*/
/* I'm not going to impliment substring matching for properties! */
do_medit(player, thing, q, argv);
} else {
/* we've got a wildcard, treat like old @gedit */
for(a = DBFETCHPROP(thing); a; a = a->next)
if(a && wild_match(q, a->name))
do_medit(player, thing, a->name, argv);
}
}
void do_medit(dbref player, dbref thing, char *q, char *argv[])
{
int d, len, res;
char *a;
char *r, *s , *val;
char tbuf1[BUFFER_LEN];
val = argv[1];
r = (argv[2]) ? argv[2] : (char *) "";
a = get_property_data(thing, q, access_rights(player, thing, NOTHING));
if(!a) {
notify(player, player, "No such attribute, try set instead.");
return;
}
/*
if ((a->flags & AF_LOCKED) && (OWNER(player) != OWNER(a->creator))) {
notify(player, player, "You need to control an attribute to edit it.");
return;
}
*/
s = a; /* warning: pointer to static buffer */
if (!strcmp(val, "$")) {
/* append */
if (strlen(s) + strlen(r) < BUFFER_LEN) {
strcpy(tbuf1, s);
strcat(tbuf1, r);
}
} else if (!strcmp(val, "^")) {
/* prepend */
if (strlen(s) + strlen(r) < BUFFER_LEN) {
strcpy(tbuf1, r);
strcat(tbuf1, s);
}
} else {
/* find and replace */
len = strlen(val);
for (d = 0; (d < BUFFER_LEN) && *s;)
if (strncmp(val, s, len) == 0) {
if ((d + strlen(r)) < BUFFER_LEN) {
strcpy(tbuf1 + d, r);
d += strlen(r);
s += len;
} else
tbuf1[d++] = *s++;
} else
tbuf1[d++] = *s++;
tbuf1[d++] = 0;
}
res = add_property(thing, q, tbuf1, default_perms(q),
access_rights(player, thing, NOTHING));
if(!res) {
notify(player, player, "That attribute seems to have vanished!");
return;
}
/*
if(res == -1) {
notify(player, player, "You don't have the power to change that.");
return;
}
if(!Quiet(player) && !Quiet(thing))
*/
notify(player, player, tprintf("%s - Set: %s", q, tbuf1));
}
#endif /* MUSH */