/* predicates.c */ #include "os.h" #include "copyright.h" /* Predicates for testing various conditions */ #include "config.h" #include "externs.h" #include "db.h" #include "interface.h" #include "externs.h" #include "match.h" char *tprintf (char *fmt, ...) { static char buff[BUFFER_LEN]; va_list args; va_start (args, fmt); (void) vsprintf (buff, fmt, args); va_end (args); buff[BUFFER_LEN - 1] = '\0'; return (buff); } int can_link_to (dbref who, dbref where) { return ((where >= 0 && where <= db_top) && (controls (who, where) || (db[where].flags & LINK_OK))); } int could_doit (dbref player, dbref thing) { /* no if puppet trys to get key */ if ((Typeof (player) != TYPE_PLAYER) && ((Typeof (thing) == TYPE_THING) && (db[thing].flags & THING_KEY) || (Typeof (thing) == TYPE_EXIT) && (db[thing].flags & EXIT_KEY))) return 0; if (Typeof (thing) != TYPE_ROOM && db[thing].location == NOTHING) return 0; return (eval_boolexp (player, db[thing].key, thing, 0, BASICLOCK)); } void did_it (dbref player, dbref thing, char *what, char *def, char *owhat, char *odef, char *awhat, dbref loc) { ATTR *d; char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN]; loc = (loc == NOTHING) ? db[player].location : loc; if (loc == NOTHING) return; /* message to player */ if (what && *what) { d = atr_get (thing, what); if (d) { strcpy (tbuf2, uncompress (d->value)); strcpy (tbuf1, pronoun_substitute (thing, tbuf2, thing)); notify (player, tbuf1); } else if (def && *def) notify (player, def); } /* message to neighbors */ if (!Dark (player)) { if (owhat && *owhat) { d = atr_get (thing, owhat); if (d) { strcpy (tbuf2, uncompress (d->value)); strcpy (tbuf1, pronoun_substitute (player, tbuf2, thing)); notify_except2 (db[loc].contents, player, thing, tprintf ("%s %s", db[player].name, tbuf1)); } else { if (odef && *odef) { notify_except2 (db[loc].contents, player, thing, tprintf ("%s %s", db[player].name, odef)); } } } } /* do the action attribute */ if (awhat && *awhat && (d = atr_get (thing, awhat))) { ATTR *b; strcpy (tbuf1, uncompress (d->value)); parse_que (thing, tbuf1, player); /* check if object has # of charges */ b = atr_get (thing, "CHARGES"); if (b) { int num = atoi (b->value); if (num) { (void) atr_add (thing, "CHARGES", tprintf ("%d", num - 1), db[b->creator].owner, NOTHING); } else if (!(d = atr_get (thing, "RUNOUT"))) return; strcpy (tbuf2, uncompress (d->value)); parse_que (thing, tbuf2, player); } } } int can_see (dbref player, dbref thing, int can_see_loc) { /* * 1) your own body isn't listed in a 'look' 2) exits aren't listed in a * 'look' 3) unconnected (sleeping) players aren't listed in a 'look' */ if (player == thing || Typeof (thing) == TYPE_EXIT || ((Typeof (thing) == TYPE_PLAYER) && !IS (thing, TYPE_PLAYER, PLAYER_CONNECT))) return 0; /* if the room is lit, you can see any non-dark objects */ else if (can_see_loc) return (!Dark (thing)); /* otherwise room is dark and you can't see a thing */ else return 0; } int controls (dbref who, dbref what) { /* Wizard controls everything */ /* owners control their stuff */ return (what >= 0 && what <= db_top && (Wizard (who) || (db[who].owner == db[what].owner) || ((db[what].zone != NOTHING) && (eval_boolexp (who, db[getzone (what)].enterkey, what, 0, ENTERLOCK))))); } int can_link (dbref who, dbref what) { return ((Typeof (what) == TYPE_EXIT && db[what].location == NOTHING) || controls (who, what)); } int can_pay_fees (dbref who, int pennies) { #ifdef QUOTA int pay_quota (); #endif /* QUOTA */ /* can't charge till we've verified building quota */ if (!Wizard (who) && !Wizard (db[who].owner) && Pennies (db[who].owner) < pennies) { notify (who, tprintf ("Sorry, you don't have enough %s.", MONIES)); return 0; } /* check building quota */ #ifdef QUOTA if (!pay_quota (who, QUOTA_COST)) { notify (who, "Sorry, your building quota has run out."); return 0; } #endif /* QUOTA */ /* charge */ payfor (who, pennies); return 1; } void giveto (dbref who, dbref pennies) { /* wizards don't need pennies */ if (Wizard (who) || Wizard (db[who].owner)) return; who = db[who].owner; s_Pennies (who, Pennies (who) + pennies); } int payfor (dbref who, int cost) { dbref tmp; if (Wizard (who) || Wizard (db[who].owner)) return 1; else if ((tmp = Pennies (db[who].owner)) >= cost) { s_Pennies (db[who].owner, tmp - cost); return 1; } else return 0; } #ifdef QUOTA void add_quota (dbref who, int payment) { ATTR *a; /* wizards don't need a quota */ if (Wizard (who) || Wizard (db[who].owner)) return; a = atr_get (who, "RQUOTA"); (void) atr_add (who, "RQUOTA", tprintf ("%d", ((a) ? (atoi (uncompress (a->value))) + payment : payment)), GOD, NOTHING); } int pay_quota (dbref who, int cost) { int quota = 0; ATTR *a; /* wizards don't need a quota */ if (Wizard (who) || Wizard (db[who].owner)) return 1; /* determine quota */ a = atr_get (db[who].owner, "RQUOTA"); if (a) quota = atoi (uncompress (a->value)); /* enough to build? */ quota -= cost; if (quota < 0) return 0; /* doc the quota */ (void) atr_add (who, "RQUOTA", tprintf ("%d", quota), GOD, NOTHING); return 1; } #endif /* QUOTA */ int ok_name (const char *name) { while (name && *name && isspace ((int)*name)) name++; return (name && *name && *name != LOOKUP_TOKEN && *name != NUMBER_TOKEN && *name != NOT_TOKEN && !index (name, ARG_DELIMITER) && !index (name, AND_TOKEN) && !index (name, OR_TOKEN) && string_compare (name, "me") && string_compare (name, "home") && string_compare (name, "here")); } int ok_player_name (const char *name) { const char *scan; if (!ok_name (name) || strlen (name) > PLAYER_NAME_LIMIT) return 0; for (scan = name; *scan; scan++) { if (!(isprint ((int)*scan) && !isspace ((int)*scan))) { /* was isgraph(*scan) */ return 0; } } return (lookup_player (name) == NOTHING); } int ok_password (const char *password) { const char *scan; if (*password == '\0') return 0; for (scan = password; *scan; scan++) { if (!(isprint ((int)*scan) && !isspace ((int)*scan))) { return 0; } } return 1; } static void sstrcat (char *string, char *app) { char *s; char tbuf1[BUFFER_LEN]; if ((strlen (app) + strlen (string)) >= BUFFER_LEN) return; sprintf (tbuf1, "%s", app); for (s = tbuf1; *s; s++) if ((*s == ',') || (*s == ';')) *s = ' '; strcat (string, tbuf1); } static char *percent_sub (dbref player, char *str, dbref privs) { static const char *subjective[3] = { "it", "she", "he" }; static const char *possessive[3] = { "its", "her", "his" }; static const char *objective[3] = { "it", "her", "him" }; static char result[BUFFER_LEN]; int gend; ATTR *a, *r; if (*str == '_') { r = atr_get (privs, str + 1); if (r) { if ((r->flags & AF_DARK) || ((r->flags & AF_WIZARD) && !Wizard (privs))) return (char *) ""; sprintf (result, "%s", uncompress (r->value)); return result; } else return (char *) ""; } else { *result = '\0'; switch (str[0]) { case 's': case 'S': case 'p': case 'P': case 'o': case 'O': a = atr_get (player, "SEX"); if (!a) gend = 0; else { switch (*uncompress (a->value)) { case 'M': case 'm': gend = 2; break; case 'W': case 'w': case 'F': case 'f': gend = 1; break; default: gend = 0; } } break; default: gend = 0; } switch (str[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!wptr[str[0] - '0']) return (char *) ""; else return (wptr[str[0] - '0']); /*NOTREACHED*/ break; case 's': case 'S': sprintf (result, "%s", subjective[gend]); break; case 'p': case 'P': sprintf (result, "%s", possessive[gend]); break; case 'o': case 'O': sprintf (result, "%s", objective[gend]); break; case 'n': case 'N': sprintf (result, db[player].name); break; case 'r': case 'R': return (char *) "\n"; /*NOTREACHED*/ break; case 'b': case 'B': return (char *) " "; /*NOTREACHED*/ break; case 't': case 'T': return (char *) "\t"; /*NOTREACHED*/ break; case 'v': case 'V': case 'w': case 'W': case 'x': case 'X': if (!isalpha ((int)str[1])) return str; r = atr_get (privs, str); if (r) { sprintf (result, "%s", uncompress (r->value)); return result; } else return (char *) ""; /*NOTREACHED*/ break; default: return str; /*NOTREACHED*/ break; } if (isupper ((int)*str) && islower ((int)result[0])) result[0] = toupper ((int)result[0]); else if (islower ((int)*str) && isupper ((int)result[0])) result[0] = tolower ((int)result[0]); return result; } } /* * pronoun_substitute() * * %-type substitutions for pronouns * * %s/%S for subjective pronouns (he/she/it, He/She/It) %o/%O for objective * pronouns (him/her/it, Him/Her/It) %p/%P for possessive pronouns * (his/her/its, His/Her/Its) %n/%N for the player's name. %r for a newline. * %<attrib_name> for the attribute value. */ char *pronoun_substitute (dbref player, const char *str, dbref privs /* object whose privs are used */ ) { static char buf[BUFFER_LEN]; char temp[BUFFER_LEN]; char *r, *q; if ((privs < 0) || privs >= db_top) return (char *) ""; if ((player < 0) || player >= db_top) return (char *) ""; if (strlen (str) > BUFFER_LEN - 1) return (char *) ""; r = buf; *r = '\0'; while (*str) { switch (*str) { case '[': str++; exec ((char**)&str, temp, privs, player, 0); if (strlen (buf) + strlen (temp) < BUFFER_LEN) strcat (buf, temp); r += strlen (temp); if (*str == ']') str++; break; case '%': switch (*(str + 1)) { case '%': if (r - buf < BUFFER_LEN - 1) *r++ = '%'; str += 2; break; case '[': if (r - buf < BUFFER_LEN - 1) *r++ = '['; str += 2; break; case '#': str += 2; sprintf (temp, "#%d", player); sstrcat (buf, temp); r += strlen (temp); break; case '_': str += 2; temp[0] = '_'; for (q = temp + 1; (*str && (isalnum ((int)*str) || *str == '_' || *str == '-')); *q++ = *str++); *q = '\0'; q = percent_sub (player, temp, privs); sstrcat (buf, q); r += strlen (q); break; case '!': str += 2; sprintf (temp, "#%d", privs); sstrcat (buf, temp); r += strlen (temp); break; default: str++; /* strip off the leading % sign before calling %sub */ temp[0] = *str; if (*str == 'v' || *str == 'w' || *str == 'x' || *str == 'V' || *str == 'W' || *str == 'X') { str++; temp[1] = *str; temp[2] = '\0'; } else temp[1] = '\0'; str++; q = percent_sub (player, temp, privs); sstrcat (buf, q); r += strlen (q); } break; default: if (r - buf < BUFFER_LEN - 1) { *r++ = *str; *r = '\0'; } str++; } } *r = '\0'; return buf; } /* for lack of better place the @switch code is here */ void do_switch (dbref player, char *exp, char *argv[], dbref cause) { int any = 0, a, c; char *ptrsrv[10]; if (!argv[1]) return; for (c = 0; c < 10; c++) ptrsrv[c] = wptr[c]; /* now try a wild card match of buff with stuff in coms */ for (a = 1; (a < (MAX_ARG - 1)) && argv[a] && argv[a + 1]; a += 2) if (wild_match (argv[a], exp)) { any = 1; for (c = 0; c < 10; c++) wptr[c] = ptrsrv[c]; parse_que (player, argv[a + 1], cause); } for (c = 0; c < 10; c++) wptr[c] = ptrsrv[c]; if ((a < MAX_ARG) && !any && argv[a]) parse_que (player, argv[a], cause); } dbref is_possess (dbref player, char *arg1) { dbref result1, result; char *place, *temp; if (!(place = index (arg1, ' '))) return NOTHING; temp = place; temp++; *place = '\0'; place--; place--; if (*place != '\'') return NOTHING; *place = '\0'; init_match (player, arg1, NOTYPE); match_neighbor (); match_possession (); result1 = match_result (); if (result1 == NOTHING || result1 == AMBIGUOUS) return result1; init_match (result1, temp, NOTYPE); match_possession (); result = match_result (); return result; } void page_return (dbref player, dbref target, char *type, char *message, char *def) { ATTR *d; char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN]; struct tm *ptr; time_t t; if (message && *message) { d = atr_get (target, message); if (d) { strcpy (tbuf2, uncompress (d->value)); strcpy (tbuf1, pronoun_substitute (target, tbuf2, target)); t = time (NULL); ptr = localtime (&t); notify (player, tprintf ("%s message from %s: %s", type, db[target].name, tbuf1)); notify (target, tprintf ("[%d:%02d] %s message sent to %s.", ptr->tm_hour, ptr->tm_min, type, db[player].name)); } else if (def && *def) notify (player, def); } } int nearby (dbref obj1, dbref obj2) { /* returns 1 if obj1 is "nearby" object2. "Nearby" is defined as: */ /* obj1 is in the same room as obj2, obj1 is being carried by */ /* obj2, obj1 is carrying obj2. Returns 0 if object isn't nearby */ /* and -1 if the input is invalid. */ if ((obj1 == NOTHING) || (obj2 == NOTHING)) return -1; if ((Typeof (obj1) != TYPE_THING) && (Typeof (obj1) != TYPE_PLAYER)) return -1; if ((Typeof (obj2) != TYPE_THING) && (Typeof (obj2) != TYPE_PLAYER)) return -1; if (db[obj1].location == db[obj2].location) return 1; else if (db[obj1].location == obj2) return 1; else if (db[obj2].location == obj1) return 1; else return 0; } int find_flag (char *p, dbref thing) { int f = 0; if (thing == NOTHING) return -1; switch (Typeof (thing)) { case TYPE_THING: if (string_prefix ("KEY", p)) f = THING_KEY; if (string_prefix ("SAFE", p)) f = THING_SAFE; if (string_prefix ("IMMORTAL", p)) f = THING_IMMORTAL; if (string_prefix ("VERBOSE", p)) f = THING_VERBOSE; if (string_prefix ("DESTROY_OK", p)) f = THING_DEST_OK; if (string_prefix ("PUPPET", p)) f = THING_PUPPET; if (string_prefix ("THING", p)) f = TYPE_THING; break; case TYPE_EXIT: if (string_prefix ("KEY", p)) f = EXIT_KEY; if (string_prefix ("TRANSPARENT", p)) f = EXIT_TRANSPARENT; if (string_prefix ("EXIT", p)) f = TYPE_EXIT; break; case TYPE_PLAYER: #ifdef RESTRICTED_BUILDING if (string_prefix ("BUILDER", p)) f = PLAYER_BUILD; #endif /* RESTRICTED_BUILDING */ if (string_prefix ("GAGGED", p)) f = PLAYER_GAGGED; if (string_prefix ("SUSPECT", p)) f = PLAYER_SUSPECT; if (string_prefix ("UNFINDABLE", p)) f = PLAYER_DARK; if (string_prefix ("PLAYER", p)) f = TYPE_PLAYER; if (string_prefix ("CONNECTED", p)) f = PLAYER_CONNECT; break; case TYPE_ROOM: if (string_prefix ("TEMPLE", p)) f = ROOM_TEMPLE; if (string_prefix ("ABODE", p)) f = ROOM_ABODE; if (string_prefix ("JUMP_OK", p)) f = ROOM_JUMP_OK; if (string_prefix ("LINK_OK", p)) f = LINK_OK; if (string_prefix ("FLOATING", p)) f = ROOM_FLOATING; if (string_prefix ("NO_TEL", p)) f = ROOM_NO_TEL; if (string_prefix ("ROOM", p)) f = TYPE_ROOM; break; } if (!f) { #ifdef DESTROY if (string_prefix ("GOING", p)) { f = GOING; #endif /* DESTROY */ } else if (string_prefix ("DARK", p)) { f = DARK; } else if (string_prefix ("STICKY", p)) { f = STICKY; } else if (string_prefix ("WIZARD", p)) { f = WIZARD; #ifdef ROYALTY_FLAG } else if (string_prefix ("ROYALTY", p)) { f = ROYALTY; #endif } else if (string_prefix ("ENTER_OK", p)) { f = ENTER_OK; } else if (string_prefix ("CHOWN_OK", p)) { f = CHOWN_OK; } else if (string_prefix ("VISUAL", p)) { f = VISUAL; } else if (string_prefix ("OPAQUE", p)) { f = OPAQUE; } else if (string_prefix ("NOSPOOF", p)) { f = NOSPOOF; #ifdef INHERIT_FLAG } else if (string_prefix ("INHERIT", p)) { f = INHERIT; #endif } else if (string_prefix ("HAVEN", p)) { f = HAVEN; } else if (string_prefix ("HALT", p)) { f = HALT; } else if (string_prefix ("QUIET", p)) { f = QUIET; } else if (string_prefix ("TERSE", p)) { f = TERSE; } else { f = 0; } } return f; }