/* set.c */ #include "copyright.h" /* commands which set parameters */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <sys/time.h> #include <sys/types.h> #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(player, name, newname) 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(*password); password++) ; /* eat whitespace */ if (*password) { *password++ = '\0'; /* terminate name */ while (*password && isspace(*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(player, name, keyname, locktype) 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(player, name, locktype) 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(player, name) 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(player, name, newobj) 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(player, name, newobj) 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(player, name, flag) dbref player; const char *name; const 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(*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(player, command, arg1, arg2) 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(player, it, argv) 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(player, it, argv) 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(player, object, argv) 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(player, what) 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); } }