/* set.c */ #include "os.h" #include "copyright.h" /* commands which set parameters */ #include "config.h" #include "db.h" #include "match.h" #include "interface.h" #include "externs.h" #ifdef NOCRYPT char *crypt (s, t) char *s, *t; { return (s); } #endif void do_name (dbref player, const char *name, char *newname) { dbref thing; char *password; ATTR *a; const char *d; #ifdef RWHO_SEND char tbuf1[BUFFER_LEN]; #endif if ((thing = match_controlled (player, name)) != NOTHING) { /* check for bad name */ if (*newname == '\0') { notify (player, "Give it what new name?"); return; } /* check for renaming a player */ if (Typeof (thing) == TYPE_PLAYER) { #ifdef GUEST_RESTRICT if (Guest (player)) { notify (player, "Guests may not rename themselves."); return; } #endif /* split off password */ for (password = newname; *password && !isspace ((int)*password); password++); /* eat whitespace */ if (*password) { *password++ = '\0'; /* terminate name */ while (*password && isspace ((int)*password)) password++; } /* check for null password */ if (!*password) { notify (player, "You must specify a password to change a player name."); notify (player, "E.g.: name player = newname password"); return; } else if ((a = atr_get (player, "XYXXY")) && *(d = uncompress (a->value)) && strcmp (d, password) && strcmp (crypt (password, "XX"), d)) { notify (player, "Incorrect password."); return; } else if (string_compare (newname, db[player].name) && !ok_player_name (newname)) { /* string_compare allows changing foo to Foo, etc. */ notify (player, "You can't give a player that name."); return; } /* everything ok, notify */ fprintf (stderr, "NAME CHANGE: %s(#%d) to %s\n", db[thing].name, thing, newname); if (db[thing].flags & PLAYER_SUSPECT) raw_broadcast (WIZARD, "Broadcast: Suspect %s changed name to %s.", db[thing].name, newname); #ifdef RWHO_SEND sprintf (tbuf1, "%d@%s", thing, MUDNAME); rwhocli_userlogout (tbuf1); #endif delete_player (thing); SET (db[thing].name, newname); add_player (thing); #ifdef RWHO_SEND rwhocli_userlogin (tbuf1, newname, time ((time_t *) 0)); #endif notify (player, "Name set."); return; } else { if (!ok_name (newname)) { notify (player, "That is not a reasonable name."); return; } } /* everything ok, change the name */ SET (db[thing].name, newname); notify (player, "Name set."); } } void do_lock (dbref player, const char *name, const char *keyname, int locktype) { dbref thing; struct boolexp *key; init_match (player, name, NOTYPE); match_everything (); switch (thing = match_result ()) { case NOTHING: notify (player, "I don't see what you want to lock!"); return; case AMBIGUOUS: notify (player, "I don't know which one you want to lock!"); return; default: if (!controls (player, thing)) { notify (player, "You can't lock that!"); return; } break; } key = parse_boolexp (player, keyname); if (key == TRUE_BOOLEXP) { notify (player, "I don't understand that key."); } else { /* everything ok, do it */ switch (locktype) { case BASICLOCK: free_boolexp (db[thing].key); db[thing].key = key; break; case USELOCK: free_boolexp (db[thing].usekey); db[thing].usekey = key; break; case ENTERLOCK: free_boolexp (db[thing].enterkey); db[thing].enterkey = key; break; } notify (player, "Locked."); } } void do_unlock (dbref player, const char *name, int locktype) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { switch (locktype) { case BASICLOCK: free_boolexp (db[thing].key); db[thing].key = TRUE_BOOLEXP; break; case USELOCK: free_boolexp (db[thing].usekey); db[thing].usekey = TRUE_BOOLEXP; break; case ENTERLOCK: free_boolexp (db[thing].enterkey); db[thing].enterkey = TRUE_BOOLEXP; break; } notify (player, "Unlocked."); } } void do_unlink (dbref player, const char *name) { dbref exit; init_match (player, name, TYPE_EXIT); match_exit (); match_here (); if (Wizard (player)) { match_absolute (); } switch (exit = match_result ()) { case NOTHING: notify (player, "Unlink what?"); break; case AMBIGUOUS: notify (player, "I don't know which one you mean!"); break; default: if (!controls (player, exit)) { notify (player, "Permission denied."); } else { switch (Typeof (exit)) { case TYPE_EXIT: db[exit].location = NOTHING; notify (player, "Unlinked."); break; case TYPE_ROOM: db[exit].location = NOTHING; notify (player, "Dropto removed."); break; default: notify (player, "You can't unlink that!"); break; } } } } void do_chown (dbref player, const char *name, const char *newobj) { dbref thing; dbref owner = NOTHING; init_match (player, name, TYPE_THING); match_possession (); match_here (); match_exit (); if (Wizard (player)) { match_player (); match_absolute (); } switch (thing = match_result ()) { case NOTHING: notify (player, "You don't have that!"); return; case AMBIGUOUS: notify (player, "I don't know which you mean!"); return; default: if (!*newobj || !string_compare (newobj, "me")) { owner = player; } else { if ((owner = lookup_player (newobj)) == NOTHING) { notify (player, "I couldn't find that player."); return; } } if (Typeof (thing) == TYPE_PLAYER && !God (player)) { notify (player, "Players always own themselves."); return; } else if (!controls (player, thing) && (!(db[thing].flags & CHOWN_OK) || ((Typeof (thing) == TYPE_THING) && (db[thing].location != player) && !Wizard (player))) || !controls (player, owner)) { notify (player, "Permission denied."); } else if (!payfor (player, OBJECT_COST)) { notify (player, "You don't have enough money."); } else { giveto (db[thing].owner, OBJECT_COST); if (God (player)) { db[thing].owner = owner; } else { db[thing].owner = db[owner].owner; } db[thing].zone = db[owner].zone; db[thing].flags &= ~CHOWN_OK; db[thing].flags &= ~WIZARD; #ifdef ROYALTY_FLAG db[thing].flags &= ~ROYALTY; #endif db[thing].flags &= ~INHERIT; db[thing].flags |= HALT; notify (player, "Owner changed."); } } } void do_chzone (dbref player, const char *name, const char *newobj) { dbref thing; dbref zone; if (!Wizard (player)) { notify (player, "Only wizards may change the zone of an object."); return; } init_match (player, name, NOTYPE); match_neighbor (); match_possession (); match_here (); match_exit (); match_me (); if (Wizard (player)) { match_player (); match_absolute (); } switch (thing = 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 (thing) == TYPE_PLAYER && !God (player)) { notify (player, "Only God may change a player's zone."); return; } if (!string_compare (newobj, "none")) zone = NOTHING; else { init_match (player, newobj, 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; } } db[thing].zone = zone; db[thing].flags &= ~WIZARD; #ifdef ROYALTY_FLAG db[thing].flags &= ~ROYALTY; #endif db[thing].flags &= ~INHERIT; notify (player, "Zone changed."); } void do_set (dbref player, const char *name, char *flag) { dbref thing; int res; char *p; char tbuf1[BUFFER_LEN]; object_flag_type f; int her; /* find thing */ if ((thing = match_controlled (player, name)) == NOTHING) return; if (God (thing) && !God (player)) { notify (player, "Only God can set himself!"); return; } #ifdef INHERIT_FLAG if (!Inherit (player) && Inherit (thing)) { notify (player, "Authorization failed."); return; } #endif #ifdef DESTROY /* * The GOING flag can only be affected by set in one special case--A * room that is set to be destroy may be saved. */ if (string_prefix ("!GOING", flag) && (Typeof (thing) == TYPE_ROOM) && (db[thing].flags & GOING)) { db[thing].flags ^= GOING; if (db[thing].owner > 0) notify (db[thing].owner, "Your room has been spared from destruction."); return; } #endif /* DESTROY */ her = Hearer (thing); /* check for attribute set first */ p = index (flag, ':'); if (p) { ATTR *attrb = NULL; ATTR *a = NULL; *p++ = '\0'; /* check for predefined attribute match */ attrb = atr_match (flag); /* check for _ */ if (*p == '_') { dbref thing1; char *q; q = index (p, '/'); if (!(q && *q)) { notify (player, "I need an object and an attribute."); return; } *q++ = '\0'; init_match (player, p, NOTYPE); match_everything (); thing1 = noisy_match_result (); if (thing1 == NOTHING) return; a = atr_get (thing1, q); if (!a) { notify (player, "No such attribute."); return; } strcpy (tbuf1, uncompress (a->value)); } else { strcpy (tbuf1, p); } if (attrb) { if ((attrb->flags & AF_WIZARD) && !Wizard (player)) { notify (player, "Sorry, only wizards can modify that."); return; } res = atr_add (thing, attrb->name, tbuf1, player, NOTHING); if (!res) { notify (player, "No such attribute to reset."); return; } if (res == -1) { notify (player, "That attribute cannot be changed by you."); return; } } else { res = atr_add (thing, flag, tbuf1, player, NOTHING); if (!res) { notify (player, "No such attribute to reset."); return; } if (res == -1) { notify (player, "That attribute cannot be changed by you."); return; } } /* one special case for listen */ if (attrb && !string_compare (attrb->name, "LISTEN") && !her) notify_except (db[getloc (thing)].contents, thing, tprintf ("%s grows ears and can now hear.", db[thing].name)); if (!Quiet (player) && !Quiet (thing)) notify (player, tprintf ("%s - Set.", db[thing].name)); return; } /* move p past NOT_TOKEN if present */ for (p = (char *) flag; *p && (*p == NOT_TOKEN || isspace ((int)*p)); p++); /* identify flag */ if (*p == '\0') { notify (player, "You must specify a flag to set."); return; } f = find_flag (p, thing); if (f == 0) { notify (player, "I don't recognize that flag."); return; } if (f == -1) { notify (player, "Broken function. Notify god."); return; } /* check unsettable flags */ #ifdef DESTROY if (f == GOING) { notify (player, "The GOING flag may only be used to stop the destruction of rooms."); return; } #endif if ((f == TYPE_EXIT) || (f == TYPE_PLAYER) || (f == TYPE_ROOM)) { notify (player, "You cannot set that flag."); return; } /* check for restricted flag */ if (!Wizard (player)) { switch (Typeof (thing)) { case TYPE_ROOM: if (f == ROOM_TEMPLE) { notify (player, "Permission denied."); return; } break; case TYPE_PLAYER: #ifdef RESTRICTED_BUILDING if (f == PLAYER_BUILD) { notify (player, "Permission denied."); return; } #endif /* RESTRICTED_BUILDING */ if (f == PLAYER_CONNECT) { notify (player, "You cannot set that flag."); return; } if (f == DARK) { notify (player, "Permission denied."); notify (player, "Use UNFINDABLE to hide from whereis command."); return; } if (f == PLAYER_SUSPECT) { notify (player, "Permission denied."); return; } break; case TYPE_THING: if (f == THING_IMMORTAL) { notify (player, "Permission denied."); return; } break; } } #ifdef ROYALTY_FLAG if ((f == ROYALTY) && !((Royalty (player) && Typeof (thing) != TYPE_PLAYER) || Wizard (player) || God (player))) { notify (player, "Permission denied."); return; } #endif if ((f == WIZARD) && !((Wizard (player) && db[thing].owner == player) || God (player))) { notify (player, "Permission denied."); return; } if ((Typeof (thing) == TYPE_PLAYER) && (db[thing].owner == thing) && (f == PLAYER_GAGGED) && (!Wizard (player) || Wizard (thing))) { notify (player, "You cannot gag that!"); return; } /* else everything is ok, do the set */ if (*flag == NOT_TOKEN) { /* reset the flag */ db[thing].flags &= ~f; if (f == WIZARD) fprintf (stderr, "** WIZFLAG RESET ** %s(#%d) --> %s(#%d)\n", db[player].name, player, db[thing].name, thing); #ifdef ROYALTY_FLAG if (f == ROYALTY) fprintf (stderr, "** ROYAL FLAG RESET ** %s(#%d) --> %s(#%d)\n", db[player].name, player, db[thing].name, thing); #endif #ifdef RWHO_SEND if (f == DARK && Typeof (thing) == TYPE_PLAYER) { sprintf (tbuf1, "%d@%s", thing, MUDNAME); rwhocli_userlogin (tbuf1, db[thing].name, time ((time_t *) 0)); } #endif if ((f == QUIET) || (!Quiet (player) && !Quiet (thing))) notify (player, "Flag reset."); } else { /* set the flag */ db[thing].flags |= f; if (f == WIZARD) fprintf (stderr, "** WIZFLAG SET ** %s(#%d) --> %s(#%d)\n", db[player].name, player, db[thing].name, thing); #ifdef ROYALTY_FLAG if (f == ROYALTY) fprintf (stderr, "** ROYAL FLAG SET ** %s(#%d) --> %s(#%d)\n", db[player].name, player, db[thing].name, thing); #endif #ifdef RWHO_SEND if (f == DARK && Typeof (thing) == TYPE_PLAYER) { sprintf (tbuf1, "%d@%s", thing, MUDNAME); rwhocli_userlogout (tbuf1); } #endif if ((Typeof (thing) == TYPE_THING) && (f == THING_PUPPET) && !her) { sprintf (tbuf1, "%s grows ears and can now hear.", db[thing].name); notify_except (db[db[thing].location].contents, 0, tbuf1); } if ((f == QUIET) || (!Quiet (player) && !Quiet (thing))) notify (player, "Flag set."); } } /* check for abbreviated set command */ int test_set (dbref player, char *command, char *arg1, char *arg2) { int a; char tbuf1[BUFFER_LEN]; if (command[0] != '@' && command[0] != '&') return (0); /* added to make this 2.0 compatible. with '&' equivalent to '@_' */ if (command[0] == '&') { sprintf (tbuf1, "%s:%s", command + 1, arg2); do_set (player, arg1, tbuf1); return (1); } /* first character is '@' */ /* check if it's a regular attribute */ for (a = 0; attr[a].name; a++) if (string_prefix (attr[a].name, command + 1)) { sprintf (tbuf1, "%s:%s", attr[a].name, arg2); do_set (player, arg1, tbuf1); return (1); } /* else treat it as a user-defined one */ if (command[1] != '_') return (0); sprintf (tbuf1, "%s:%s", command + 2, arg2); do_set (player, arg1, tbuf1); return (1); } void do_gedit (dbref player, char *it, char *argv[]) { ALIST *a; dbref thing; char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN]; char *q; if (!(it && *it)) { notify (player, "I need to know what you want to edit."); return; } strcpy (tbuf1, it); q = index (tbuf1, '/'); if (!(q && *q)) { notify (player, "I need to know what you want to edit."); return; } *q++ = '\0'; init_match (player, tbuf1, NOTYPE); match_everything (); thing = noisy_match_result (); if (thing == NOTHING || !controls (player, thing)) { notify (player, "Permission denied."); return; } if (*q == '_') q++; for (a = db[thing].list; a; a = AL_NEXT (a)) { strcpy (tbuf2, q); if (!AL_BAD (a) && wild_match (tbuf2, AL_NAME (a))) { sprintf (tbuf2, "%s/%s", tbuf1, AL_NAME (a)); do_edit (player, tbuf2, argv); } } } void do_edit (dbref player, char *it, char *argv[]) { dbref thing; int d, len, res; ATTR *a; char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN]; char *r, *q, *s, *val; if (!(it && *it)) { notify (player, "I need to know what you want to edit."); return; } strcpy (tbuf1, it); q = index (tbuf1, '/'); if (!(q && *q)) { notify (player, "I need to know what you want to edit."); return; } *q++ = '\0'; init_match (player, tbuf1, NOTYPE); match_everything (); thing = noisy_match_result (); if (thing == NOTHING || !controls (player, thing)) { notify (player, "Permission denied."); return; } if (!argv[1] || !*argv[1]) { notify (player, "Nothing to do."); return; } val = argv[1]; r = (argv[2]) ? argv[2] : (char *) ""; if (*q == '_') q++; a = atr_get (thing, q); if (!a) { notify (player, "No such attribute, try set instead."); return; } if ((a->flags & AF_LOCKED) && db[player].owner != db[a->creator].owner) { notify (player, "You need to control an attribute to edit it."); return; } s = (char *) uncompress (a->value); len = strlen (val); for (d = 0; (d < BUFFER_LEN) && *s;) if (strncmp (val, s, len) == 0) { if ((d + strlen (r)) < BUFFER_LEN) { strcpy (tbuf2 + d, r); d += strlen (r); s += len; } else tbuf2[d++] = *s++; } else tbuf2[d++] = *s++; tbuf2[d++] = 0; res = atr_add (thing, a->name, tbuf2, player, NOTHING); if (!res) { notify (player, "That attribute seems to have vanished!"); return; } if (res == -1) { notify (player, "You don't have the power to change that."); return; } if (!Quiet (player) && !Quiet (thing)) notify (player, tprintf ("%s - Set: %s", a->name, tbuf2)); } void do_trigger (dbref player, char *object, char *argv[]) { dbref thing; int a; char *s; char tbuf1[BUFFER_LEN]; strcpy (tbuf1, object); for (s = tbuf1; *s && (*s != '/'); s++); if (!*s) { notify (player, "I need to know what attribute to trigger."); return; } *s++ = '\0'; init_match (player, tbuf1, NOTYPE); match_everything (); thing = noisy_match_result (); if (thing == NOTHING) return; if (!controls (player, thing) && string_compare (s, "DOES")) { notify (player, "Permission denied."); return; } if (God (thing) && !God (player)) { notify (player, "You can't trigger God!"); return; } #ifdef INHERIT_FLAG if (!Inherit (player) && Inherit (thing)) { notify (player, "Authorization failed."); return; } #endif for (a = 0; a < 10; a++) wptr[a] = argv[a + 1]; did_it (player, thing, NULL, NULL, NULL, NULL, s, NOTHING); if (!Quiet (player) && !Quiet (thing)) notify (player, tprintf ("%s - Triggered.", db[thing].name)); } /* for lack of a better place, the use code is here */ void do_use (dbref player, const char *what) { dbref thing; init_match (player, what, TYPE_THING); match_neighbor (); match_possession (); match_absolute (); if ((thing = noisy_match_result ()) != NOTHING) { if (!eval_boolexp (player, db[thing].usekey, thing, 0, USELOCK)) { notify (player, "Permission denied."); return; } else did_it (player, thing, "USE", "Used.", "OUSE", NULL, "AUSE", NOTHING); } }