#include "copyright.h"
#include "config.h"
/* commands which set parameters */
#include <stdio.h>
#include <ctype.h>
#include "db.h"
#include "params.h"
#include "match.h"
#include "interface.h"
#include "externs.h"
#include "mush.h"
#ifdef COMPRESS
#define alloc_compressed(x) dup_string(compress(x))
#else /* COMPRESS */
#define alloc_compressed(x) dup_string(x)
#endif /* COMPRESS */
static char buf[BUFFER_LEN];
dbref match_controlled(dbref player, char *name)
{
dbref match;
match_data md;
init_match(player, name, NOTYPE, &md);
match_everything(&md);
match = noisy_match_result(&md);
if(match != NOTHING && !controls(player, match))
{
notify(player, player, "Permission denied.");
return NOTHING;
}
else return match;
}
void do_name(__DO_PROTO)
{
dbref thing;
char *password;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
/* check for bad name */
if(*arg2 == '\0')
{
notify(player, player, "Give it what new name?");
return;
}
/* check for renaming a player */
if(Typeof(thing) == TYPE_PLAYER)
{
/* split off password */
for(password = arg2; *password && !isspace(*password); password++);
/* eat whitespace */
if(*password)
{
*password++ = '\0'; /* terminate name */
while(*password && isspace(*password)) password++;
}
/* check for null password */
if(!*password)
{
notify(player, player,
"You must specify a password to change a player's name.");
notify(player, player, "E.g.: name player = newname password");
return;
}
if(check_password(password,thing))
{
notify(player, player, "Incorrect password.");
return;
}
if(!ok_player_name(arg2, thing))
{
notify(player, player, "You can't give a player that name.");
return;
}
if(o_taboonames) {
if(!ok_taboo_name(thing, arg2, 1)==1 && !Wizard(player))
{
notify(player, player, "Sorry, That name is not allowed on this MUD!");
return;
}
}
/* everything ok, notify */
log_status("NAME CHANGE: %s(#%d) to %s\n", NAME(thing), thing, arg2);
sprintf(buf, "%s did a name change:", unparse_name(player));
strcat(buf, unparse_name(thing));
strcat(buf, "->");
delete_player(thing);
if (NAME(thing)) free(NAME(thing));
NAME(thing) = dup_string(arg2);
add_player(thing);
strcat(buf, unparse_name(thing));
if(o_notify_wiz) {
notify_wizards(buf);
}
DBSTORE(thing, time_modified, time(NULL));
notify(player, player, "Name set.");
return;
}
else
{
if(!ok_name(arg2))
{
notify(player, player, "That is not a reasonable name.");
DBSTORE(thing, time_modified, time(NULL));
return;
}
}
/* everything ok, change the name */
if(NAME(thing)) free(NAME(thing));
NAME(thing) = dup_string(arg2);
notify(player, player, "Name set.");
DBDIRTY(thing);
}
}
void do_describe(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
if(GET_DESC(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->desc);
DBSTORE(thing, desc, alloc_compressed(arg2));
#else
remove_property(thing, "desc", ACCESS_WI);
add_property(thing, "desc", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Description set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_fail(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
if(GET_FAIL(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->fail);
DBSTORE(thing, fail, alloc_compressed(arg2));
#else
remove_property(thing, "fail", ACCESS_WI);
add_property(thing, "fail", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_success(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
if(GET_SUCC(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->succ);
DBSTORE(thing, succ, alloc_compressed(arg2));
#else
remove_property(thing, "succ", ACCESS_WI);
add_property(thing, "succ", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
/* sets the drop message for player */
void do_drop_message(__DO_PROTO)
{
dbref thing;
if ((thing = match_controlled(player, arg1)) != NOTHING)
{
if (GET_DROP(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->drop);
DBSTORE(thing, drop, alloc_compressed(arg2));
#else
remove_property(thing, "drop", ACCESS_WI);
add_property(thing, "drop", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_osuccess(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
if(GET_OSUCC(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->osucc);
DBSTORE(thing, osucc, alloc_compressed(arg2));
#else
remove_property(thing, "osucc", ACCESS_WI);
add_property(thing, "osucc", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_ofail(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
if(GET_OFAIL(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->ofail);
DBSTORE(thing, ofail, alloc_compressed(arg2));
#else
remove_property(thing, "ofail", ACCESS_WI);
add_property(thing, "ofail", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_odrop(__DO_PROTO)
{
dbref thing;
if ((thing = match_controlled(player, arg1)) != NOTHING)
{
if (GET_ODROP(thing))
#ifndef USE_DBP_STR
free(DBFETCH(thing)->odrop);
DBSTORE(thing, odrop, alloc_compressed(arg2));
#else
remove_property(thing, "odrop", ACCESS_WI);
add_property(thing, "odrop", arg2, PERMS_COREAD | PERMS_COWRITE |
PERMS_COSRCH | PERMS_OTREAD | PERMS_OTSRCH, ACCESS_WI);
#endif
notify(player, player, "Message set.");
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
}
}
void do_lock(__DO_PROTO)
{
dbref thing;
boolexp *key;
match_data md;
init_match(player, arg1, 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;
}
break;
}
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
key = parse_boolexp(player, arg2);
if(key == TRUE_BOOLEXP) notify(player, player,
"I don't understand that key.");
else
{
/* everything ok, do it */
remove_backlocks_parse(thing, DBFETCH(thing)->key);
free_boolexp(DBFETCH(thing)->key);
DBSTORE(thing, key, key);
add_backlocks_parse(thing, DBFETCH(thing)->key);
notify(player, player, "Locked.");
}
}
void do_unlock(__DO_PROTO)
{
dbref thing;
if((thing = match_controlled(player, arg1)) != NOTHING)
{
remove_backlocks_parse(thing, DBFETCH(thing)->key);
free_boolexp(DBFETCH(thing)->key);
DBSTORE(thing, key, TRUE_BOOLEXP);
notify(player, player, "Unlocked.");
DBSTORE(thing, time_modified, time(NULL));
}
}
void do_unlink(__DO_PROTO)
{
dbref exit;
match_data md;
init_match(player, arg1, TYPE_EXIT, &md);
match_all_exits(&md);
match_here(&md);
if(Wizard(player)) match_absolute(&md);
switch(exit = match_result(&md))
{
case NOTHING:
notify(player, player, "Unlink what?");
break;
case AMBIGUOUS:
notify(player, player, "I don't know which one you mean!");
break;
default:
if(!controls(player, exit))
notify(player, player, "Permission denied.");
else
{
switch(Typeof(exit))
{
case TYPE_EXIT:
if(DBFETCH(exit)->sp.exit.ndest != 0)
{
remove_backlinks(exit);
if (!Wizard(player))
DBFETCH(OWNER(exit))->pennies += LINK_COST;
DBDIRTY(OWNER(exit));
}
DBSTORE(exit, sp.exit.ndest, 0);
if (DBFETCH(exit)->sp.exit.dest)
{
free ((void *)DBFETCH(exit)->sp.exit.dest);
DBSTORE(exit, sp.exit.dest, NULL);
}
notify(player, player, "Unlinked.");
DBSTORE(exit, time_modified, time(NULL));
break;
case TYPE_ROOM:
remove_backlinks(exit);
DBSTORE(exit, link, NOTHING);
notify(player, player, "Dropto removed.");
DBSTORE(exit, time_modified, time(NULL));
break;
default:
notify(player, player, "You can't unlink that!");
break;
}
}
}
}
void do_chown(__DO_PROTO)
{
dbref thing;
dbref owner;
match_data md;
#ifndef PLAYER_CHOWN
if(!Wizard(player))
{
notify(player, player, "Permission denied.");
return;
}
#endif /* PLAYER_CHOWN */
if (!*arg1)
{
notify(player, player,
"You must specify what you want to take ownership of.");
return;
}
init_match(player, arg1, NOTYPE, &md);
match_everything(&md);
if((thing = noisy_match_result(&md)) == NOTHING) return;
if(*arg2 && string_compare(arg2, "me"))
{
if ((owner = lookup_player(arg2)) == NOTHING)
{
notify(player, player, "I couldn't find that player.");
return;
}
}
else owner = player;
if((!Wizard(player) && player != owner) ||
(Typeof(thing) == TYPE_PLAYER) ||
(Typeof(thing) == TYPE_GARBAGE) ||
(Typeof(player) != TYPE_PLAYER) ||
(!Wizard(player) && (!(FLAGS(thing) & CHOWN_OK))))
{
notify(player, player, "Permission denied.");
return;
}
DBSTORE(thing, time_modified, time(NULL));
remove_ownerlist(thing);
DBSTORE(thing, owner, owner);
add_ownerlist(thing);
if (owner == player) notify(player, player, "Owner changed to you.");
else
{
sprintf(buf, "Owner changed to %s.", unparse_object(player, owner));
notify(player, player, buf);
}
}
/* Note: Gender code taken out. All gender references are now to be handled
by property lists...
Setting of flags and property code done here. Note that the PROP_DELIMITER
identifies when you're setting a property.
A @set <thing>= :
will clear all properties.
A @set <thing>= type:
will remove that property.
A @set <thing>= type: class
will add that property or replace it. */
void do_set(__DO_PROTO)
{
dbref thing;
char *p;
object_flag_type f;
FLAG *fst;
char buff[BUFFER_LEN];
/* find thing */
if((thing = match_controlled(player, arg1)) == NOTHING) return;
if((*arg2 == PROP_MUF) && !Wizard(player))
{
notify(player, player, "Can't set/remove a MUF property.");
return;
}
#ifdef TIMESTAMPS
DBSTORE(thing, time_modified, time(NULL));
#endif
/* move p past NOT_TOKEN if present */
for(p = arg2; *p && (*p == NOT_TOKEN || isspace(*p)); p++);
/* Now we check to see if it's a property reference */
/* if this gets changed, please also modify boolexp.c */
if (strchr(arg2, PROP_DELIMITER))
{
char *type;
char *class;
char *x; /* to preserve string location so we can free it */
char *temp;
char buff[BUFFER_LEN];
type = dup_string(arg2);
class = (char *)strchr(type, PROP_DELIMITER);
x = type;
while (isspace(*type) && (*type != PROP_DELIMITER)) type++;
if (*type == PROP_DELIMITER)
{
if (strlen (type) > 1) /* @set obj = :blah */
{
notify(player, player, "Invalid property name.");
return;
}
else /* @set obj = : */
{
/* clear all properties */
if(Safe(thing)) {
notify(player, player, "That object is set SAFE.");
return;
}
burn_proptree(DBFETCHPROP(thing));
DBSTOREPROP(thing, NULL);
notify(player, player, "ALL properties removed.");
return;
}
}
else /* @set obj = prop:val */
{
/* get rid of trailing spaces */
for (temp = class - 1; isspace(*temp); temp--);
temp++;
*temp = '\0';
}
class++; /* move to next character */
while (isspace(*class) && *class) class++;
if (!(*class))
{
switch(remove_property(thing, type,
access_rights(player, thing, NOTHING)))
{
case 0:
notify(player, player, "Property removed.");
#ifdef MUSH
if(strn_cmp("listen", type)) {
sprintf(buff, "%s loses its ears and becomes deaf.",
unparse_name(thing));
notify_except(thing, DBFETCH(thing)->location, thing, buff);
}
#endif
break;
case 1: notify(player, player, "Property not found."); break;
case 2: notify(player, player, "Permission denied."); break;
}
}
else
{
if (add_property(thing, type, class, default_perms(type),
access_rights(player, thing, NOTHING))) {
notify(player, player, "Property set.");
#ifdef MUSH
if(strn_cmp("listen", type)) {
sprintf(buff, "%s grows ears and can now hear.",
unparse_name(thing));
notify_except(thing, DBFETCH(thing)->location, thing, buff);
}
#endif
}
else
notify(player, player, "Permission denied.");
}
free((void *) x);
return;
}
/* identify flag */
if(*p == '\0')
{
notify(player, player, "You must specify a flag to set.");
return;
}
if ((fst = flag_lookup(p, thing)) == NULL)
{
notify(player, player, "I don't recognize that flag for that type object.");
return;
}
f = fst->flag;
/* check for restricted flag */
if (restricted(player, thing, f))
{
notify(player, player, "Permission denied.");
return;
}
if((f & GOD) && (*arg2 == NOT_TOKEN) && (thing == player))
{
notify(player, player, "Permission denied.");
}
if((f & WIZARD) && *arg2 == NOT_TOKEN && thing == player)
{
notify(player, player, "Permission denied.");
return;
}
/* else everything is ok, do the set */
if(*arg2 == NOT_TOKEN) {
if(!(FLAGS(thing) & f)) {
notify(player, player,
tprintf("That object was not set %s.", fst->name));
return;
}
/* reset the flag */
FLAGS(thing) &= ~f;
notify(player, player, "Flag reset.");
#ifdef MUSH
if(f == PUPPET) {
sprintf(buff, "%s loses its ears and becomes deaf.",
unparse_name(thing));
notify_except(thing, DBFETCH(thing)->location, thing, buff);
}
#endif
} else {
if(FLAGS(thing) & f) {
notify(player, player,
tprintf("That object is already set %s.", fst->name));
return;
}
/* set the flag */
#ifdef MUSH
if(f == PUPPET) {
sprintf(buff, "%s grows ears and can now hear.",
unparse_name(thing));
notify_except(thing, DBFETCH(thing)->location, thing, buff);
}
#endif
FLAGS(thing) |= f;
notify(player, player, "Flag set.");
}
DBDIRTY(thing);
}
void do_perms(__DO_PROTO)
{
dbref thing;
propdir *p;
char *val;
if ((thing = match_controlled(player, arg1)) == NOTHING) return;
val = (char *)strchr(arg2, PROP_DELIMITER);
if (val)
{
*val++ = '\0';
change_perms(thing, arg2, parse_perms(val),
access_rights(player, thing, NOTHING));
}
p = find_property(thing, arg2, access_rights(player, thing, NOTHING));
if (p)
{
sprintf (buf, "Permissions set to:(0%o)%s", p->perms,
unparse_perms(p->perms));
notify(player, player, buf);
}
else
{
if (find_property(thing, arg2, ACCESS_WI))
notify(player, player, "Permission denied.");
else notify(player, player, "Property not found.");
}
}
int ok_taboo_name(dbref player, char *name, int flag)
{
char buf[100]; /* Match player name against a black list */
FILE *fp; /* Written by Howard */
if((fp = fopen(TABOO_FILE, "r")) != NULL) {
while(fgets(buf, 100, fp) != NULL) {
buf[(strlen(buf)-1)] = '\0';
if(wild_match(buf, name)) {
if(flag)
log_status("NAME CHANGE FAILED from %s to %s\n", NAME(player), name);
else
log_status("NAME CREATE FAILED %s\n", name);
fclose(fp);
return 0;
}
}
fclose(fp);
return 1;
}
log_status("Can't open TABOO_FILE!!!!!\n");
fprintf(stderr, "Unable to open %s!\n", TABOO_FILE);
return 1;
}