#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 */