#include "copyright.h" /* commands which set parameters */ #include "os.h" #include "db.h" #include "config.h" #include "match.h" #include "interface.h" #include "externs.h" #ifdef COMPRESS #define alloc_compressed(x) alloc_string(compress(x)) #else /* COMPRESS */ #define alloc_compressed(x) alloc_string(x) #endif /* COMPRESS */ #define FREE_STRING(X) X = ((X) ? (free ((void *) (X)), NULL) : NULL) static dbref match_controlled (dbref player, const char *name) { dbref match; init_match (player, name, NOTYPE); match_everything (); match = noisy_match_result (); if (match != NOTHING && !controls (player, match)) { notify (player, "Permission denied."); return NOTHING; } else { return match; } } void do_name (dbref player, const char *name, char *newname) { dbref thing; char *password; 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) { /* 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 (strcmp (db[thing].name, "guest") == 0) { notify (player, "You are only a guest here...no name changing."); return; } else if (!db[thing].password) { /* If original has no password, set one */ db[thing].password = alloc_string (password); } else if (strcmp (password, db[thing].password)) { notify (player, "Incorrect password."); return; } else if (string_compare (newname, db[thing].name) && !ok_player_name (newname)) { notify (player, "You can't give a player that name."); return; } /* everything ok, notify */ writelog ("NAME CHANGE: %s(#%d) to %s\n", db[thing].name, thing, newname); #ifdef PLAYER_LIST delete_player (thing); free ((void *) db[thing].name); db[thing].name = alloc_string (newname); add_player (thing); notify (player, "Name set."); return; #endif /* PLAYER_LIST */ } else { if (!ok_name (newname)) { notify (player, "That is not a reasonable name."); return; } } /* everything ok, change the name */ if (db[thing].name) { free ((void *) db[thing].name); } db[thing].name = alloc_string (newname); notify (player, "Name set."); } } void do_describe (dbref player, const char *name, const char *description) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].description) { free ((void *) db[thing].description); } db[thing].description = alloc_compressed (description); notify (player, "Description set."); } } void do_fail (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].fail_message) { free ((void *) db[thing].fail_message); } db[thing].fail_message = alloc_compressed (message); notify (player, "Message set."); } } void do_success (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].succ_message) { free ((void *) db[thing].succ_message); } db[thing].succ_message = alloc_compressed (message); notify (player, "Message set."); } } void do_osuccess (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].osuccess) { free ((void *) db[thing].osuccess); } db[thing].osuccess = alloc_compressed (message); notify (player, "Message set."); } } void do_ofail (dbref player, const char *name, const char *message) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { if (db[thing].ofail) { free ((void *) db[thing].ofail); } db[thing].ofail = alloc_compressed (message); notify (player, "Message set."); } } void do_lock (dbref player, const char *name, const char *keyname) { 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 */ free_boolexp (db[thing].key); db[thing].key = key; notify (player, "Locked."); } } void do_unlock (dbref player, const char *name) { dbref thing; if ((thing = match_controlled (player, name)) != NOTHING) { free_boolexp (db[thing].key); db[thing].key = TRUE_BOOLEXP; 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; init_match (player, name, NOTYPE); match_everything (); if ((thing = noisy_match_result ()) == NOTHING) { return; } else if ((owner = lookup_player (newobj)) == NOTHING && string_compare (newobj, "me")) { notify (player, "I couldn't find that player."); } else if (Typeof (thing) == TYPE_PLAYER) { notify (player, "Players always own themselves."); } else if (!Wizard (player) && ((string_compare (newobj, "me") && owner != player) || !(db[thing].flags & UNWANTED))) { notify (player, "Permission denied."); } else if (!Wizard (player) && !could_doit (player, thing)) { notify (player, "That item is locked."); } else { if (!string_compare (newobj, "me")) owner = player; db[thing].owner = owner; notify (player, "Owner changed."); } } void do_set (dbref player, const char *name, const char *flag) { dbref thing; const char *p; object_flag_type f; /* find thing */ if ((thing = match_controlled (player, name)) == NOTHING) return; /* move p past NOT_TOKEN if present */ for (p = flag; *p && (*p == NOT_TOKEN || isspace ((int)*p)); p++); /* identify flag */ if (*p == '\0') { notify (player, "You must specify a flag to set."); return; } else if (string_prefix ("LINK_OK", p)) { f = LINK_OK; } else if (string_prefix ("DARK", p)) { f = DARK; } else if (string_prefix ("STICKY", p)) { f = STICKY; } else if (string_prefix ("WIZARD", p) || string_prefix ("TINKER", p)) { f = WIZARD; } else if (string_prefix ("TEMPLE", p) || string_prefix ("JUNKPILE", p)) { f = TEMPLE; } else if (string_prefix ("HAVEN", p)) { f = HAVEN; } else if (string_prefix ("ABODE", p)) { f = ABODE; } else if (string_prefix ("UNWANTED", p)) { f = UNWANTED; #ifdef ROBOT_MODE } else if (string_prefix ("ROBOT", p) || string_prefix ("BOT", p)) { if (Typeof (thing) == TYPE_PLAYER) { if (Wizard (player)) { writelog ("ROBOT: success %s(%d) %s %s(%d)\n", db[player].name, player, *flag == NOT_TOKEN ? "reset" : "set", db[thing].name, thing); } else { writelog ("ROBOT: failed %s(%d) %s %s(%d)\n", db[player].name, player, *flag == NOT_TOKEN ? "reset" : "set", db[thing].name, thing); notify (player, #ifndef TINKER "Only a Wizard can designate a player robotic."); #else /* TINKER */ "Only a Tinker can designate a player robotic."); #endif /* TINKER */ return; } } f = ROBOT; #endif /* ROBOT_MODE */ } else if (string_prefix ("TABULAR_WHO", p)) { f = TABULAR_WHO; } else if (string_prefix ("REVERSED_WHO", p)) { f = REVERSED_WHO; #ifdef GENDER } else if (string_prefix ("MALE", p) || string_prefix ("FEMALE", p) || string_prefix ("NEUTER", p) || string_prefix ("UNASSIGNED", p)) { if (Typeof (thing) != TYPE_PLAYER) { notify (player, "Sorry, only players have gender."); return; } if (thing != player && !Wizard (player)) { notify (player, "You can only give yourself a sex-change."); return; } db[thing].flags &= ~GENDER_MASK; if (string_prefix ("UNASSIGNED", p) || *flag == NOT_TOKEN) { db[thing].flags |= (GENDER_UNASSIGNED << GENDER_SHIFT); notify (player, "Gender set to unassigned."); } else if (string_prefix ("MALE", p)) { db[thing].flags |= (GENDER_MALE << GENDER_SHIFT); notify (player, "Gender set to male."); } else if (string_prefix ("FEMALE", p)) { db[thing].flags |= (GENDER_FEMALE << GENDER_SHIFT); notify (player, "Gender set to female."); } else if (string_prefix ("NEUTER", p)) { db[thing].flags |= (GENDER_NEUTER << GENDER_SHIFT); notify (player, "Gender set to neuter."); } return; #endif /* GENDER */ #ifdef RESTRICTED_BUILDING } else if (string_prefix ("BUILDER", p) ||) { string_prefix ("CONSTRUCTOR", p) f = BUILDER; #endif /* RESTRICTED_BUILDING */ } else { notify (player, "I don't recognize that flag."); return; } /* check for restricted flag */ if (!Wizard (player) && (f == TEMPLE #ifdef RESTRICTED_BUILDING || f == BUILDER #endif /* RESTRICTED_BUILDING */ || f == DARK && (Typeof (thing) != TYPE_ROOM && Typeof (thing) != TYPE_THING))) { notify (player, "Permission denied."); return; } #ifdef GOD_PRIV if (!God (player) && f == DARK && Typeof (thing) == TYPE_PLAYER) { notify (player, "Permission denied."); return; } #endif /* GOD_PRIV */ if (!Wizard (player) && f == DARK && Typeof (thing) == TYPE_THING && db[thing].location != player) { notify (player, "You must be holding an object to set it DARK."); return; } #ifdef GOD_PRIV if (!God (player) && (f == WIZARD)) { #else if (!Wizard (player) && (f == WIZARD)) { #endif /* GOD_PRIV */ writelog ("WIZARD: failed %s(%d) %s %s(%d)\n", db[player].name, player, *flag == NOT_TOKEN ? "reset" : "set", db[thing].name, thing); notify (player, "Permission denied."); return; } if (f == WIZARD) { writelog ("WIZARD: success %s(%d) %s %s(%d)\n", db[player].name, player, *flag == NOT_TOKEN ? "reset" : "set", db[thing].name, thing); } #ifdef GOD_PRIV /* check for unGODding */ if (f == WIZARD && God (thing)) { notify (player, "Gods can not me made mortal."); return; } #else if (f == WIZARD && thing == player) { notify (player, "You cannot make yourself mortal!"); return; } #endif /* GOD_PRIV */ if (f == HAVEN && !(Typeof (thing) == TYPE_ROOM || Typeof (thing) == TYPE_PLAYER)) { notify (player, "Only rooms or players can be HAVEN."); return; } if (f == UNWANTED && Typeof (thing) == TYPE_PLAYER) { notify (player, "You should always want yourself."); return; } if ((f == TABULAR_WHO || f == REVERSED_WHO) && Typeof (thing) != TYPE_PLAYER) { notify (player, "Player preference flags can only be set on players."); return; } /* else everything is ok, do the set */ if (*flag == NOT_TOKEN) { /* reset the flag */ db[thing].flags &= ~f; notify (player, "Flag reset."); } else { /* set the flag */ db[thing].flags |= f; notify (player, "Flag set."); } } #ifdef RECYCLE /**************************************************************** * do_recycle: Allow any player to give an item away...the item * is @chowned to the "Recycler" player, and if it's a thing, * it is @linked to the home of the "Recycler" as well. ****************************************************************/ void do_recycle (dbref player, const char *name) { dbref thing, recip, i; char buf[BUFFER_LEN]; if (!name || !*name) { notify (player, "You must specify an object to @recycle."); return; } if ((thing = match_controlled (player, name)) == NOTHING) return; if (Typeof (thing) == TYPE_PLAYER) { notify (player, "You can't @recycle players."); return; } if ((recip = lookup_player (RECYCLER)) == NOTHING) { notify (player, "There is no current Recycler."); return; } /* Okay - do it */ db[thing].owner = recip; /* If its a thing, link it to the Recyclers home */ if (Typeof (thing) == TYPE_THING) { db[thing].exits = db[recip].exits; moveto (thing, db[thing].exits); } /* Clear its strings */ FREE_STRING (db[thing].name); FREE_STRING (db[thing].description); FREE_STRING (db[thing].fail_message); FREE_STRING (db[thing].ofail); FREE_STRING (db[thing].succ_message); FREE_STRING (db[thing].osuccess); sprintf (buf, "junk-%d", thing); db[thing].name = alloc_string (buf); /* unlock it */ free_boolexp (db[thing].key); db[thing].key = TRUE_BOOLEXP; /* Make it worthless */ db[thing].pennies = 1; /* Make it up for grabs */ db[thing].flags |= UNWANTED; /* Tell player we did it */ notify (player, "Object recycled."); } /**************************************************************** * do_count: count things... * players: Number of objects owned, carried * rooms: number of exits from & to, number contents ****************************************************************/ void do_count (dbref player, const char *name) { dbref thing, i, exit; char buf[BUFFER_LEN]; int owned = 0, contents = 0, from = 0, to = 0, objects = 0, rooms = 0, exits = 0; int rowned = 0, rplayers = 0, robjects = 0, rrooms = 0, rexits = 0; if (!name || !*name) { notify (player, "You must specify an object to @count."); return; } if ((thing = match_controlled (player, name)) == NOTHING) return; if (Typeof (thing) != TYPE_PLAYER && Typeof (thing) != TYPE_ROOM) { notify (player, "You can only @count people or rooms.\n"); return; } if (!payfor (player, FIND_COST)) { notify (player, "You don't have enough pennies."); return; } switch (Typeof (thing)) { case TYPE_PLAYER: for (i = 0; i < db_top; i++) { if (db[i].location == thing) contents++; if (db[i].owner == thing) { switch (Typeof (i)) { case TYPE_THING: objects++; break; case TYPE_EXIT: exits++; break; case TYPE_ROOM: rooms++; break; } owned++; } } sprintf (buf, "%s owns %d objects (%d things, %d rooms, %d exits), %d carried.", unparse_object (player, thing), owned, objects, rooms, exits, contents); notify (player, buf); break; case TYPE_ROOM: for (i = 0; i < db_top; i++) { if (db[i].location == thing) { if (Typeof (i) == TYPE_EXIT) { to++; } else { contents++; } } } DOLIST (exit, db[thing].exits) { from++; } sprintf (buf, "%s has %d entrances, %d exits, %d objects.", unparse_object (player, thing), to, from, contents); notify (player, buf); if (!Wizard (player)) break; for (i = 0; i < db_top; i++) { if (db[db[i].owner].location == thing) { switch (Typeof (i)) { case TYPE_EXIT: rexits++; break; case TYPE_ROOM: rrooms++; break; case TYPE_THING: robjects++; break; case TYPE_PLAYER: rplayers++; break; } rowned++; } } if (rplayers == 0) { sprintf (buf, "There are no players in %s.\n", unparse_object (player, thing)); } else { sprintf (buf, "The %d player%s in %s own%s %d %s: %d %s, %d %s, %d %s\n.", rplayers, (rplayers == 1) ? "" : "s", unparse_object (player, thing), (rplayers == 1) ? "s" : "", rowned, "objects", robjects, "things", rrooms, "rooms", rexits, "exits"); } notify (player, buf); break; } } #endif /* RECYCLE */