#include <string.h> #include <ctype.h> #include <stdarg.h> #include "db.h" #include "config.h" #include "externs.h" static int ok_name P((char *)); int IS(OBJ *thing, int type, unsigned long flag) { if(!thing) return(0); if(Typeof(thing) != type) return(0); if(!(thing->flags & flag)) return(0); return(1); } int is_root(OBJ *thing) { if(root_obj) return(thing == root_obj); return(thing == find_object(config.root)); } int neighbors(OBJ *obj1, OBJ *obj2) { return((obj1->location == obj2->location)); } char *tprintf(char *fmt, ...) { char buff[4096]; va_list ap; va_start(ap, fmt); vsnprintf(buff, sizeof(buff), fmt, ap); va_end(ap); return(stack_string_alloc(buff, 0)); } int power(OBJ *thing, int level_check) { /* MORTAL flag on player makes him mortal - no arguments */ if(IS(thing, TYPE_PLAYER, PLAYER_MORTAL)) return(0); return(has_pow(thing, NULL, level_check)); } int inf_mon(OBJ *thing) { return(power(thing, POW_MONEY)); } int could_doit(OBJ *player, OBJ *thing, char *atrname) { return(eval_boolexp(player, thing, atr_get(thing, atrname))); } void did_it(OBJ *player, OBJ *thing, char *what, char *def, char *aprog) { char *d; /* Message to player */ if(what) { if(*(d = atr_get(thing, what))) { notify(player, d); } else if(def) notify(player, def); } } int can_see(OBJ *player, OBJ *thing, int can_see_loc) { /* 1) your own body isn't listed in a 'look' 2) unconnected (sleeping) players aren't listed in a 'look' 3) players set INVISIBLE aren't listed in a 'look' 4) If you don't match the LSEE attribute you can't see it */ if(player == thing || (Typeof(thing) == TYPE_PLAYER && !is_connected_raw(thing))) { return(0); } if(IS(thing, TYPE_PLAYER, PLAYER_INVISIBLE)) return(0); /* If you don't match the LSEE then you can never see it */ if(!could_doit(player, thing, "LSEE")) return(0); /* If it's dark you can't see it */ if(Typeof(thing) != TYPE_PLAYER && !(thing->flags & PUPPET) && thing->flags & DARK) { return(0); } if(can_see_loc) return(!is_dark(thing)); if(IS(thing, TYPE_THING, THING_LIGHT) && controls(thing, thing->location, POW_MODIFY)) { return(1); } else return(0); } int can_set_atr(OBJ *who, OBJ *what, ATTR *atr) { if(!can_see_atr(who, what, atr)) return(0); if(atr->flags & AF_BUILTIN) return(0); if(atr->flags & AF_NOMOD) return(0); if(!controls(who, what, POW_MODIFY)) return(0); if(atr->flags & AF_WIZARD && !power(who, POW_WATTR)) return(0); return(1); } int can_see_atr(OBJ *who, OBJ *what, ATTR *atr) { if(!string_compare(atr->name, "PASSWORD") && !is_root(who)) return(0); if(!(atr->flags & AF_OSEE) && !controls(who, what, POW_SEEATR) && !(what->flags & VISIBLE)) { return(0); } if(atr->flags & AF_DARK && !Wizard(who)) return(0); return(1); } int controls(OBJ *who, OBJ *what, int cutoff_level) { if(is_root(who)) return(1); if(!what) return(has_pow(who, what, cutoff_level)); if((cutoff_level == POW_EXAMINE || cutoff_level == POW_SEEATR) && what->flags & VISIBLE) { return(1); } if(who->owner == what->owner) return(1); if(what->flags & INHERIT_POWERS) what = what->owner; if(is_root(what) || is_root(what->owner)) return(0); if(has_pow(who, what, cutoff_level)) return(1); return(0); } OBJ *def_owner(OBJ *who) { OBJ *o; if(!*atr_get(who, "DEFOWN")) return(who->owner); o = match_object(who, atr_get(who, "DEFOWN"), TYPE_PLAYER); if(!o) { notify(who, "You have an invalid setting in your DEFOWN attribute."); return(who->owner); } if(!controls(who, o, POW_MODIFY)) { notify(who, tprintf("You don't control %s, so you can't make things owned by %s.", unparse_object(who, o), unparse_object(who, o))); return(who->owner); } return(o->owner); } void giveto(OBJ *who, int amt) { long old_amount; if(has_pow(who->owner, NULL, POW_MONEY)) return; who = who->owner; old_amount = Pennies(who); if(old_amount+amt < 0) { if((old_amount > 0) && (amt > 0)) atr_add(who, "PENNIES", tprintf("%u", (((unsigned)-2)/2))); else atr_add(who, "PENNIES", "0"); } else atr_add(who, "PENNIES", tprintf("%ld", old_amount+amt)); } int payfor(OBJ *who, int cost) { if(Guest(who) || has_pow(who->owner, NULL, POW_MONEY)) return(1); if(Pennies(who->owner) >= cost) { my_atr_add(who->owner, "PENNIES", (-cost)); return(1); } return(0); } static int my_index(char *s1, int c) { while(*s1 && (*s1 != c)) s1++; return(*s1); } int ok_thing_name(char *name) { return(ok_name(name) && !my_index(name, ';')); } int ok_exit_name(char *name) { return(ok_name(name)); } int ok_room_name(char *name) { return(ok_name(name) && !my_index(name, ';')); } static int ok_name(char *name) { return(name && *name && *name != LOOKUP_TOKEN && *name != NUMBER_TOKEN && *name != NOT_TOKEN && !my_index(name, ARG_DELIMITER) && !my_index(name, AND_TOKEN) && !my_index(name, OR_TOKEN) && !my_index(name, '@') && string_compare(name, "me") && string_compare(name, "home") && string_compare(name, "here")); } int ok_object_name(OBJ *obj, char *name) { switch(Typeof(obj)) { case TYPE_THING: return(ok_thing_name(name)); case TYPE_EXIT: return(ok_exit_name(name)); case TYPE_ROOM: return(ok_room_name(name)); } return(0); } int ok_player_name(OBJ *player, char *name, char *alias) { char *scan; OBJ *obj; if(!ok_name(name) || my_index(name, ';') || strlen(name) > config.player_name_limit) { return(0); } if(!string_compare(name, "i") || !string_compare(name, "me") || !string_compare(name, "my") || !string_compare(name, "you") || !string_compare(name, "your") || !string_compare(name, "he") || !string_compare(name, "she") || !string_compare(name, "it") || !string_compare(name, "his") || !string_compare(name, "her") || !string_compare(name, "hers") || !string_compare(name, "its") || !string_compare(name, "we") || !string_compare(name, "us") || !string_compare(name, "our") || !string_compare(name, "they") || !string_compare(name, "them") || !string_compare(name, "their") || !string_compare(name, "a") || !string_compare(name, "an") || !string_compare(name, "the") || !string_compare(name, "one") || !string_compare(name, "to") || !string_compare(name, "if") || !string_compare(name, "and") || !string_compare(name, "or") || !string_compare(name, "but") || !string_compare(name, "at") || !string_compare(name, "of") || !string_compare(name, "for") || !string_compare(name, "foo") || !string_compare(name, "so") || !string_compare(name, "this") || !string_compare(name, "that") || !string_compare(name, ">") || !string_compare(name, ".") || !string_compare(name, "-") || !string_compare(name, ">>") || !string_compare(name, "..") || !string_compare(name, "--") || !string_compare(name, "->") || !string_compare(name, ":)") || !string_compare(name, "delete") || !string_compare(name, "purge") || !string_compare(name, "check") || !string_compare(name, "new") || strchr(name, '%') || strchr(name, ' ') || !string_compare(name, "clear")) /* +mail clear. */ return(0); for(scan = name;*scan;scan++) if(!isprint(*scan) || *scan == '~') return(0); obj = match_player(NULL, name); if(obj && obj != player) return(0); if(!string_compare(name, alias)) return(0); if(player) { obj = match_player(NULL, alias); if(obj && obj != player) return(0); if(strlen(alias) > config.player_alias_limit) return(0); } if(*alias && (!ok_name(alias) || strchr(alias, ' '))) return(0); if(strlen(name) > config.player_name_limit) return(0); return(1); } int ok_password(char *password) { char *scan; if(!*password) return(0); for(scan = password;*scan;scan++) if(!(isprint(*scan))) return(0); return(1); } char *main_exit_name(OBJ *exit) { char buf[4096]; char *s; strcpy(buf, exit->name); if((s = strchr(buf, ';'))) *s = '\0'; return(stack_string_alloc(buf, 0)); } int is_dark(OBJ *thing) { switch(Typeof(thing)) { case TYPE_ROOM: if(thing->flags & DARK) return(1); break; case TYPE_PLAYER: if(thing->flags & PLAYER_INVISIBLE) return(1); break; case TYPE_THING: if(thing->flags & PUPPET) return(0); if(thing->flags & DARK) return(1); break; case TYPE_EXIT: if(thing->flags & DARK) return(1); break; } return(0); } DDATA *is_connected_raw(OBJ *who) { DDATA *d; for(d = descriptor_list;d;d = d->next) if(check_state(d, STATE_CONNECTED) && d->player == who) break; return(d); } DDATA *is_connected(OBJ *player, OBJ *who) { DDATA *d; if(*atr_get(who, "LHIDE") && !controls(player, who, POW_WHO)) if(!could_doit(player, who, "LHIDE")) return(NULL); for(d = descriptor_list;d;d = d->next) if(check_state(d, STATE_CONNECTED) && d->player == who) break; return(d); } int is_coding(OBJ *player) { DDATA *d; if(!(d = is_connected_raw(player))) return(0); return(d->mode == MODE_SOFTCODE); } DDATA *is_idle(OBJ *thing) { DDATA *d; for(d = descriptor_list;d;d = d->next) if(d->player == thing) break; if(!d) return(NULL); if(!check_state(d, STATE_CONNECTED)) return(NULL); if(d->last_time < now-300) /* 5 minutes */ return(d); return(NULL); } int my_is_vowel(char letter) { switch(toupper(letter)) { case 'A': case 'E': case 'I': case 'O': case 'U': return(1); default: return(0); } }