/* checks if object has property, returns 1 if it has the property */ int has_property_strict(int descr, dbref player, dbref what, const char *type, const char *pclass, int value) { PropPtr p; const char *str; char *ptr; char buf[BUFFER_LEN]; p = get_property(what, type); if (p) { #ifdef DISKBASE propfetch(what, p); #endif if (PropType(p) == PROP_STRTYP) { str = DoNull(PropDataUNCStr(p)); ptr = do_parse_mesg(descr, player, what, str, "(Lock)", buf, (MPI_ISPRIVATE | MPI_ISLOCK)); return (equalstr((char *) pclass, ptr)); } else if (PropType(p) == PROP_INTTYP) { return (value == PropDataVal(p)); } else { return 0; } } return 0; }
/* doesn't really belong here, but I couldn't figure out where else */ void do_page(dbref player, const char *arg1, const char *arg2) { int ignored; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; dbref target; if (!payfor(player, tp_lookup_cost)) { anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies); return; } if ( strcmp(arg1, "me") ) { if ((target = lookup_player(arg1)) == NOTHING) { anotify(player, CINFO WHO_MESG); return; } } else target = player; if(Guest(player)) { if(!Mage(target)) { anotify(player, CINFO "Guests can only page " NAMEWIZ "s, type 'wizzes'."); return; } } if (FLAGS(target) & HAVEN) { anotify(player, CFAIL "That player is haven."); return; } ignored = ignoring(target, player); if(ignored == 1) { anotify(player, CFAIL "That player is ignoring you."); return; } else if(ignored == 2) { anotify(player, CINFO "That player is ignoring you."); } do_parse_mesg(player, player, arg2, "(page)", buf, MPI_ISPRIVATE); tct(buf,buf2); if (!*buf2) { sprintf(buf, CGREEN "You sense that %s is looking for you in %s.", PNAME(player), NAME(DBFETCH(player)->location)); } else { if(buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, CGREEN "%s pages \"" CYELLOW "%s %.3900s" CGREEN "\"", PNAME(player), PNAME(player), buf2); } else { sprintf(buf, CGREEN "%s pages \"" CYELLOW "%.3900s" CGREEN "\"", PNAME(player), buf2); } } if (anotify_from(player, target, buf)) anotify(player, CSUCC "Your message has been sent."); else { sprintf(buf, CINFO "%s is not connected.", PNAME(target)); anotify(player, buf); } }
/* doesn't really belong here, but I couldn't figure out where else */ void do_page(int descr, dbref player, const char *arg1, const char *arg2) { char buf[BUFFER_LEN], buf2[BUFFER_LEN]; dbref target; if (!payfor(player, tp_lookup_cost)) { anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies); return; } if (strcmp(arg1, "me")) { if ((target = lookup_player(arg1)) == NOTHING) { anotify_nolisten2(player, CINFO "Who?"); return; } } else target = player; if (Guest(player)) { if (!Mage(target)) { anotify_nolisten2(player, CINFO "Guests can only page wizards, type 'wizzes'."); return; } } if (FLAGS(target) & HAVEN) { anotify_nolisten2(player, CFAIL "That player is haven."); return; } if (Meeper(OWNER(player))) { do_parse_mesg(descr, player, player, arg2, "(page)", buf, MPI_ISPRIVATE); tct(buf, buf2); } else { tct(arg2, buf2); } if (!*buf2) { sprintf(buf, CSUCC "You sense that %s is looking for you in %s.", PNAME(player), NAME(DBFETCH(player)->location)); } else { if (buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, SYSGREEN "%s pages \"" SYSYELLOW "%s %s" SYSGREEN "\"", PNAME(player), PNAME(player), buf2); } else { sprintf(buf, SYSGREEN "%s pages \"" SYSYELLOW "%s" SYSGREEN "\"", PNAME(player), buf2); } } if (anotify_from(player, target, buf)) anotify_nolisten2(player, CSUCC "Your message has been sent."); else { sprintf(buf, CSUCC "%s is not connected.", PNAME(target)); anotify_nolisten2(player, buf); } }
char * do_parse_prop(int descr, dbref player, dbref what, const char *propname, const char *abuf, char *outbuf, int outbuflen, int mesgtyp) { const char* propval = get_property_class(what, propname); if (!propval) return NULL; if (Prop_Blessed(what, propname)) mesgtyp |= MPI_ISBLESSED; return do_parse_mesg(descr, player, what, propval, abuf, outbuf, outbuflen, mesgtyp); }
void do_pose(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; if ((loc = getloc(player)) == NOTHING) return; do_parse_mesg(player, player, message, "(pose)", buf, MPI_ISPRIVATE); tct(buf,buf2); /* notify everybody */ sprintf(buf, CAQUA "%s%s%.3900s", PNAME(player), isalpha(buf2[0]) ? " " : "", buf2); anotify_except(DBFETCH(loc)->contents, NOTHING, buf, player); }
void do_say(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; if ((loc = getloc(player)) == NOTHING) return; do_parse_mesg(player, player, message, "(say)", buf, MPI_ISPRIVATE); tct(buf,buf2); /* Notify player */ sprintf(buf, CAQUA "You say, \"" CYELLOW "%.3900s" CAQUA "\"", buf2); anotify(player, buf); /* notify everybody else */ sprintf(buf, CAQUA "%s says, \"" CYELLOW "%.3900s" CAQUA "\"", PNAME(player), buf2); anotify_except(DBFETCH(loc)->contents, player, buf, player); }
int notify_html_listeners(int descr, dbref who, dbref xprog, dbref obj, dbref room, const char *msg, int isprivate) { char buf[BUFFER_LEN], *nohbuf, *noabuf, buf2[BUFFER_LEN]; dbref ref; if (obj == NOTHING) return 0; nohbuf = html_escape(msg); noabuf = tct(buf2, nohbuf); if (tp_listeners && (tp_listeners_obj || Typeof(obj) == TYPE_ROOM)) { listenqueue(descr, who, room, obj, obj, xprog, "_listen", nohbuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_olisten", nohbuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~listen", nohbuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~olisten", nohbuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@listen", nohbuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@olisten", nohbuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "_alisten", noabuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_aolisten", noabuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~alisten", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~aolisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@alisten", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@aolisten", noabuf, tp_listen_mlev, 0, 1); /* Loop up the environment only if tp_listeners_env is set and obj * is a room. Runs once otherwise. -brevantes */ if (tp_listeners_env && (Typeof(obj) == TYPE_ROOM) ) { obj = DBFETCH(obj)->location; for (;obj != NOTHING;obj = DBFETCH(obj)->location) { listenqueue(descr, who, room, obj, obj, xprog, "_listen", nohbuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_olisten", nohbuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~listen", nohbuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~olisten", nohbuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@listen", nohbuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@olisten", nohbuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "_alisten", noabuf, tp_listen_mlev, 1, 0); listenqueue(descr, who, room, obj, obj, xprog, "_aolisten", noabuf, tp_listen_mlev, 0, 0); listenqueue(descr, who, room, obj, obj, xprog, "~alisten", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "~aolisten", noabuf, tp_listen_mlev, 0, 1); listenqueue(descr, who, room, obj, obj, xprog, "@alisten", noabuf, tp_listen_mlev, 1, 1); listenqueue(descr, who, room, obj, obj, xprog, "@aolisten", noabuf, tp_listen_mlev, 0, 1); } return 0; } } if (tp_zombies && (Typeof(obj) == TYPE_THING) && !isprivate && !(FLAGS(obj) & QUELL)) { if (FLAGS(obj) & VEHICLE) { if (getloc(who) == getloc(obj)) { char pbuf[BUFFER_LEN]; const char *prefix; prefix = GETOECHO(obj); if (prefix && *prefix) { prefix = do_parse_mesg(-1, who, obj, prefix, "(@Oecho)", pbuf, MPI_ISPRIVATE); } if (!prefix || !*prefix) prefix = "Outside>"; sprintf(buf, "%s %.*s", prefix, (int) (BUFFER_LEN - 2 - strlen(prefix)), msg); ref = DBFETCH(obj)->contents; while (ref != NOTHING) { #ifdef IGNORE_SUPPORT if (!ignorance(who, ref)) #endif /* IGNORE_SUPPORT */ notify_html_nolisten(ref, buf, isprivate); ref = DBFETCH(ref)->next; } } } } if (Typeof(obj) == TYPE_PLAYER || Typeof(obj) == TYPE_THING) { #ifdef IGNORE_SUPPORT if (ignorance(who, obj)) return 0; #endif if ( !isprivate && Typeof(obj) == TYPE_THING && FLAGS(obj) & ZOMBIE && LOCATION(obj) == LOCATION(OWNER(obj)) ) return 0; return notify_html_nolisten(obj, msg, isprivate); } else { return 0; } }
void do_whisper(int descr, dbref player, const char *arg1, const char *arg2) { dbref who; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; struct match_data md; if (Guest(player)) { anotify_fmt(player, CFAIL "%s", tp_noguest_mesg); return; } init_match(descr, player, arg1, TYPE_PLAYER, &md); match_neighbor(&md); match_me(&md); if (Mage(player) && Typeof(player) == TYPE_PLAYER) { match_absolute(&md); match_player(&md); } switch (who = match_result(&md)) { case NOTHING: anotify_nolisten2(player, CINFO "Who?"); break; case AMBIGUOUS: anotify_nolisten2(player, CINFO "I don't know who you mean!"); break; default: if (Meeper(OWNER(player))) { do_parse_mesg(descr, player, player, arg2, "(whisper)", buf, MPI_ISPRIVATE); tct(buf, buf2); } else { tct(arg2, buf2); } if (buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, SYSBLUE "%s whispers, \"" SYSPURPLE "%s %s" SYSBLUE "\"", PNAME(player), PNAME(player), buf2 + 1); if (!anotify_from(player, who, buf)) { sprintf(buf, SYSBLUE "%s is not connected.", PNAME(who)); anotify_nolisten2(player, buf); break; } sprintf(buf, SYSBLUE "You whisper, \"" SYSPURPLE "%s %s" SYSBLUE "\" to %s.", PNAME(player), buf2 + 1, PNAME(who)); anotify(player, buf); break; } else { sprintf(buf, SYSBLUE "%s whispers, \"" SYSPURPLE "%s" SYSBLUE "\"", PNAME(player), buf2); if (!anotify_from(player, who, buf)) { sprintf(buf, SYSBLUE "%s is not connected.", PNAME(who)); anotify_nolisten2(player, buf); break; } sprintf(buf, SYSBLUE "You whisper, \"" SYSPURPLE "%s" SYSBLUE "\" to %s.", buf2, PNAME(who)); anotify(player, buf); break; } } }
void do_whisper(dbref player, const char *arg1, const char *arg2) { int ignored; dbref who; char buf[BUFFER_LEN], buf2[BUFFER_LEN]; struct match_data md; if(Guest(player)) { anotify(player, CFAIL NOGUEST_MESG); return; } init_match(player, arg1, TYPE_PLAYER, &md); match_neighbor(&md); match_me(&md); if (Mage(player) && Typeof(player) == TYPE_PLAYER) { match_absolute(&md); match_player(&md); } switch (who = match_result(&md)) { case NOTHING: case AMBIGUOUS: anotify(player, CINFO WHO_MESG); break; default: ignored = ignoring(who, player); if(ignored == 1) { anotify(player, CFAIL "That player is ignoring you."); return; } else if(ignored == 2) { anotify(player, CINFO "That player is ignoring you."); } do_parse_mesg(player, player, arg2, "(whisper)", buf, MPI_ISPRIVATE); tct(buf,buf2); if (buf2[0] == ':' || buf2[0] == ';') { sprintf(buf, CBLUE "%s whispers, \"" CPURPLE "%s %.3900s" CBLUE "\"", PNAME(player), PNAME(player), buf2+1); if (!anotify_from(player, who, buf)) { sprintf(buf, CBLUE "%s is not connected.", PNAME(who)); anotify(player, buf); break; } sprintf(buf, CBLUE "You whisper, \"" CPURPLE "%s %.3900s" CBLUE "\" to %s.", PNAME(player), buf2+1, PNAME(who)); anotify(player, buf); break; } else { sprintf(buf, CBLUE "%s whispers, \"" CPURPLE "%.3900s" CBLUE "\"", PNAME(player), buf2); if (!anotify_from(player, who, buf)) { sprintf(buf, CBLUE "%s is not connected.", PNAME(who)); anotify(player, buf); break; } sprintf(buf, CBLUE "You whisper, \"" CPURPLE "%.3900s" CBLUE "\" to %s.", buf2, PNAME(who)); anotify(player, buf); break; } } }
int ansi_notify_listeners(dbref who, dbref xprog, dbref obj, dbref room, const char *msg, int isprivate, int parseansi) { const char *lmsg; char buf[BUFFER_LEN]; dbref ref; if (obj == NOTHING) return 0; /* Gag jerks, but not wizards or selves */ if((who != obj) && (ignoring(obj, who) == 1)) return 0; if(parseansi > 0) { buf[0] = '\0'; unparse_ansi(buf, msg, parseansi); lmsg = buf; } else lmsg = msg; if (tp_listeners && (tp_listeners_obj || Typeof(obj) == TYPE_ROOM)) { listenqueue(who,room,obj,obj,xprog,"@listen",lmsg, tp_listen_mlev,1,1); listenqueue(who,room,obj,obj,xprog,"~listen",lmsg, tp_listen_mlev,1,1); listenqueue(who,room,obj,obj,xprog,"~olisten",lmsg,tp_listen_mlev,0,1); listenqueue(who,room,obj,obj,xprog,"_listen",lmsg, tp_listen_mlev,1,tp_mortal_mpi_listen_props); listenqueue(who,room,obj,obj,xprog,"_olisten",lmsg,tp_listen_mlev,0,tp_mortal_mpi_listen_props); } if ((Typeof(obj) == TYPE_THING || Typeof(obj) == TYPE_PLAYER) && !isprivate) { if (!(FLAGS(obj) & QUELL)) { if (getloc(who) == getloc(obj)) { char pbuf[BUFFER_LEN]; const char *prefix; prefix = GETOECHO(obj); if (prefix && *prefix) { prefix = do_parse_mesg(who, obj, prefix, "(@Oecho)", pbuf, MPI_ISPRIVATE ); } if (!prefix || !*prefix) prefix = "Outside>"; sprintf(buf, "%s %.*s", prefix, (int)(BUFFER_LEN - 2 - strlen(prefix)), msg ); ref = DBFETCH(obj)->contents; while(ref != NOTHING) { if(obj != OWNER(ref)) /* Don't tell us what we already know */ ansi_notify_nolisten(ref, buf, isprivate, parseansi); ref = DBFETCH(ref)->next; } } } } if (Typeof(obj) == TYPE_PLAYER || Typeof(obj) == TYPE_THING) { return ansi_notify_nolisten(obj, msg, isprivate, parseansi); } else return 0; }
void next_timequeue_event(void) { struct frame *tmpfr; int tmpbl, tmpfg; timequeue lastevent, event; int maxruns = 0; int forced_pid = 0; time_t rtime; time(&rtime); lastevent = tqhead; while ((lastevent) && (rtime >= lastevent->when) && (maxruns < 10)) { lastevent = lastevent->next; maxruns++; } while (tqhead && (tqhead != lastevent) && (maxruns--)) { if (tqhead->typ == TQ_MUF_TYP && tqhead->subtyp == TQ_MUF_READ) { break; } event = tqhead; tqhead = tqhead->next; process_count--; forced_pid = event->eventnum; event->eventnum = 0; if (event->typ == TQ_MPI_TYP) { char cbuf[BUFFER_LEN]; int ival; strcpyn(match_args, sizeof(match_args), event->str3 ? event->str3 : ""); strcpyn(match_cmdname, sizeof(match_cmdname), event->command ? event->command : ""); ival = (event->subtyp & TQ_MPI_OMESG) ? MPI_ISPUBLIC : MPI_ISPRIVATE; if (event->subtyp & TQ_MPI_BLESSED) { ival |= MPI_ISBLESSED; } if (event->subtyp & TQ_MPI_LISTEN) { ival |= MPI_ISLISTENER; do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIlisten)", cbuf, sizeof(cbuf), ival); } else if ((event->subtyp & TQ_MPI_SUBMASK) == TQ_MPI_DELAY) { do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIdelay)", cbuf, sizeof(cbuf), ival); } else { do_parse_mesg(event->descr, event->uid, event->trig, event->called_data, "(MPIqueue)", cbuf, sizeof(cbuf), ival); } if (*cbuf) { if (!(event->subtyp & TQ_MPI_OMESG)) { notify_filtered(event->uid, event->uid, cbuf, 1); } else { char bbuf[BUFFER_LEN]; dbref plyr; snprintf(bbuf, sizeof(bbuf), ">> %.4000s %.*s", NAME(event->uid), (int)(4000 - strlen(NAME(event->uid))), pronoun_substitute(event->descr, event->uid, cbuf)); plyr = DBFETCH(event->loc)->contents; for (; plyr != NOTHING; plyr = DBFETCH(plyr)->next) { if (Typeof(plyr) == TYPE_PLAYER && plyr != event->uid) notify_filtered(event->uid, plyr, bbuf, 0); } } } } else if (event->typ == TQ_MUF_TYP) { if (Typeof(event->called_prog) == TYPE_PROGRAM) { if (event->subtyp == TQ_MUF_DELAY) { /* Uncomment when DBFETCH "does" something */ /* FIXME: DBFETCH(event->uid); */ tmpbl = PLAYER_BLOCK(event->uid); tmpfg = (event->fr->multitask != BACKGROUND); interp_loop(event->uid, event->called_prog, event->fr, 0); if (!tmpfg) { PLAYER_SET_BLOCK(event->uid, tmpbl); } } else if (event->subtyp == TQ_MUF_TIMER) { struct inst temp; temp.type = PROG_INTEGER; temp.data.number = event->when; event->fr->timercount--; muf_event_add(event->fr, event->called_data, &temp, 0); } else if (event->subtyp == TQ_MUF_TREAD) { handle_read_event(event->descr, event->uid, NULL); } else { strcpyn(match_args, sizeof(match_args), event->called_data ? event->called_data : ""); strcpyn(match_cmdname, sizeof(match_cmdname), event->command ? event->command : ""); tmpfr = interp(event->descr, event->uid, event->loc, event->called_prog, event->trig, BACKGROUND, STD_HARDUID, forced_pid); if (tmpfr) { interp_loop(event->uid, event->called_prog, tmpfr, 0); } } } } event->fr = NULL; free_timenode(event); } }
void propqueue(int descr, dbref player, dbref where, dbref trigger, dbref what, dbref xclude, const char *propname, const char *toparg, int mlev, int mt) { const char *tmpchar; const char *pname; dbref the_prog; char buf[BUFFER_LEN]; char exbuf[BUFFER_LEN]; the_prog = NOTHING; tmpchar = NULL; /* queue up program referred to by the given property */ if (((the_prog = get_property_dbref(what, propname)) != NOTHING) || (tmpchar = get_property_class(what, propname))) { if ((tmpchar && *tmpchar) || the_prog != NOTHING) { if (tmpchar) { if (*tmpchar == '&') { the_prog = AMBIGUOUS; } else if (*tmpchar == NUMBER_TOKEN && number(tmpchar + 1)) { the_prog = (dbref) atoi(++tmpchar); } else if (*tmpchar == REGISTERED_TOKEN) { the_prog = find_registered_obj(what, tmpchar); } else if (number(tmpchar)) { the_prog = (dbref) atoi(tmpchar); } else { the_prog = NOTHING; } } else { if (the_prog == AMBIGUOUS) the_prog = NOTHING; } if (the_prog != AMBIGUOUS) { if (the_prog < 0 || the_prog >= db_top) { the_prog = NOTHING; } else if (Typeof(the_prog) != TYPE_PROGRAM) { the_prog = NOTHING; } else if ((OWNER(the_prog) != OWNER(player)) && !(FLAGS(the_prog) & LINK_OK)) { the_prog = NOTHING; } else if (MLevel(the_prog) < mlev) { the_prog = NOTHING; } else if (MLevel(OWNER(the_prog)) < mlev) { the_prog = NOTHING; } else if (the_prog == xclude) { the_prog = NOTHING; } } if (propq_level < 8) { propq_level++; if (the_prog == AMBIGUOUS) { char cbuf[BUFFER_LEN]; int ival; strcpyn(match_args, sizeof(match_args), ""); strcpyn(match_cmdname, sizeof(match_cmdname), toparg); ival = (mt == 0) ? MPI_ISPUBLIC : MPI_ISPRIVATE; if (Prop_Blessed(what, propname)) ival |= MPI_ISBLESSED; do_parse_mesg(descr, player, what, tmpchar + 1, "(MPIqueue)", cbuf, sizeof(cbuf), ival); if (*cbuf) { if (mt) { notify_filtered(player, player, cbuf, 1); } else { char bbuf[BUFFER_LEN]; dbref plyr; snprintf(bbuf, sizeof(bbuf), ">> %.4000s", pronoun_substitute(descr, player, cbuf)); plyr = DBFETCH(where)->contents; while (plyr != NOTHING) { if (Typeof(plyr) == TYPE_PLAYER && plyr != player) notify_filtered(player, plyr, bbuf, 0); plyr = DBFETCH(plyr)->next; } } } } else if (the_prog != NOTHING) { struct frame *tmpfr; strcpyn(match_args, sizeof(match_args), toparg ? toparg : ""); strcpyn(match_cmdname, sizeof(match_cmdname), "Queued event."); tmpfr = interp(descr, player, where, the_prog, trigger, BACKGROUND, STD_HARDUID, 0); if (tmpfr) { interp_loop(player, the_prog, tmpfr, 0); } } propq_level--; } else { notify_nolisten(player, "Propqueue stopped to prevent infinite loop.", 1); } } } strcpyn(buf, sizeof(buf), propname); if (is_propdir(what, buf)) { strcatn(buf, sizeof(buf), "/"); while ((pname = next_prop_name(what, exbuf, sizeof(exbuf), buf))) { strcpyn(buf, sizeof(buf), pname); propqueue(descr, player, where, trigger, what, xclude, buf, toparg, mlev, mt); } } }
void prim_parseprop(PRIM_PROTOTYPE) { const char *temp; char *ptr; struct inst *oper1 = NULL; /* prevents re-entrancy issues! */ struct inst *oper2 = NULL; /* prevents re-entrancy issues! */ struct inst *oper3 = NULL; /* prevents re-entrancy issues! */ struct inst *oper4 = NULL; /* prevents re-entrancy issues! */ char buf[BUFFER_LEN]; char type[BUFFER_LEN]; CHECKOP(4); oper4 = POP(); /* int */ oper2 = POP(); /* arg str */ oper1 = POP(); /* propname str */ oper3 = POP(); /* object dbref */ if (mlev < 3) abort_interp("Mucker level 3 or greater required."); if (oper3->type != PROG_OBJECT) abort_interp("Non-object argument. (1)"); if (!valid_object(oper3)) abort_interp("Invalid object. (1)"); if (oper2->type != PROG_STRING) abort_interp("String expected. (3)"); if (oper1->type != PROG_STRING) abort_interp("String expected. (2)"); if (!oper1->data.string) abort_interp("Empty string argument (2)"); if (oper4->type != PROG_INTEGER) abort_interp("Integer expected. (4)"); if (oper4->data.number < 0 || oper4->data.number > 1) abort_interp("Integer of 0 or 1 expected. (4)"); CHECKREMOTE(oper3->data.objref); { int len = oper1->data.string->length; if (!prop_read_perms(ProgUID, oper3->data.objref, oper1->data.string->data, mlev)) abort_interp("Permission denied."); if (mlev < 3 && !permissions(player, oper3->data.objref) && prop_write_perms(ProgUID, oper3->data.objref, oper1->data.string->data, mlev)) abort_interp("Permission denied."); strcpyn(type, sizeof(type), oper1->data.string->data); while (len-- > 0 && type[len] == PROPDIR_DELIMITER) { type[len] = '\0'; } temp = get_property_class(oper3->data.objref, type); #ifdef LOG_PROPS log2file("props.log", "#%d (%d) GETPROPSTR: o=%d n=\"%s\" s=\"%s\"", program, pc->line, oper3->data.objref, type, temp); #endif } ptr = (oper2->data.string) ? oper2->data.string->data : ""; if (temp) { result = 0; if (oper4->data.number) result |= MPI_ISPRIVATE; if (Prop_Blessed(oper3->data.objref, type)) result |= MPI_ISBLESSED; ptr = do_parse_mesg(fr->descr, player, oper3->data.objref, temp, ptr, buf, sizeof(buf), result); CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushString(ptr); } else { CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushNullStr; } }
void prim_parsepropex(PRIM_PROTOTYPE) { struct inst* oper1 = NULL; /* prevents reentrancy issues! */ struct inst* oper2 = NULL; /* prevents reentrancy issues! */ struct inst* oper3 = NULL; /* prevents reentrancy issues! */ struct inst* oper4 = NULL; /* prevents reentrancy issues! */ stk_array* vars; const char* mpi; char* str = 0; array_iter idx; extern int varc; /* from msgparse.c */ int mvarcnt = 0; char* buffers = NULL; int novars; int hashow = 0; int i; int len; char tname[BUFFER_LEN]; char buf[BUFFER_LEN]; CHECKOP(4); oper4 = POP(); /* int:Private */ oper3 = POP(); /* dict:Vars */ oper2 = POP(); /* str:Prop */ oper1 = POP(); /* ref:Object */ if (mlev < 3) abort_interp("Mucker level 3 or greater required."); if (oper1->type != PROG_OBJECT) abort_interp("Non-object argument. (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument. (2)"); if (oper3->type != PROG_ARRAY) abort_interp("Non-array argument. (3)"); if (oper3->data.array && (oper3->data.array->type != ARRAY_DICTIONARY)) abort_interp("Dictionary array expected. (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument. (4)"); if (!valid_object(oper1)) abort_interp("Invalid object. (1)"); if (!oper2->data.string) abort_interp("Empty string argument. (2)"); if ((oper4->data.number != 0) && (oper4->data.number != 1)) abort_interp("Integer of 0 or 1 expected. (4)"); CHECKREMOTE(oper1->data.objref); if (!prop_read_perms(ProgUID, oper1->data.objref, oper2->data.string->data, mlev)) abort_interp("Permission denied."); len = oper2->data.string->length; strcpyn(tname, sizeof(tname), oper2->data.string->data); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } mpi = get_property_class(oper1->data.objref, tname); vars = oper3->data.array; novars = array_count(vars); if (check_mvar_overflow(novars)) abort_interp("Out of MPI variables. (3)"); if (array_first(vars, &idx)) { do { array_data* val = array_getitem(vars, &idx); if (idx.type != PROG_STRING) { CLEAR(&idx); abort_interp("Only string keys supported. (3)"); } if (idx.data.string == NULL) { CLEAR(&idx); abort_interp("Empty string keys not supported. (3)"); } if (strlen(idx.data.string->data) > MAX_MFUN_NAME_LEN) { CLEAR(&idx); abort_interp("Key too long to be an MPI variable. (3)"); } switch(val->type) { case PROG_INTEGER: case PROG_FLOAT: case PROG_OBJECT: case PROG_STRING: case PROG_LOCK: break; default: CLEAR(&idx); abort_interp("Only integer, float, dbref, string and lock values supported. (3)"); break; } if (string_compare(idx.data.string->data, "how") == 0) hashow = 1; } while(array_next(vars, &idx)); } if (mpi && *mpi) { if (novars > 0) { mvarcnt = varc; if ((buffers = (char*)malloc(novars * BUFFER_LEN)) == NULL) abort_interp("Out of memory."); if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); array_data* val; val = array_getitem(vars, &idx); switch(val->type) { case PROG_INTEGER: snprintf(var_buf, BUFFER_LEN, "%i", val->data.number); break; case PROG_FLOAT: snprintf(var_buf, BUFFER_LEN, "%g", val->data.fnumber); break; case PROG_OBJECT: snprintf(var_buf, BUFFER_LEN, "#%i", val->data.objref); break; case PROG_STRING: strncpy(var_buf, DoNullInd(val->data.string), BUFFER_LEN); break; case PROG_LOCK: strncpy(var_buf, unparse_boolexp(ProgUID, val->data.lock, 1), BUFFER_LEN); break; default: var_buf[0] = '\0'; break; } var_buf[BUFFER_LEN - 1] = '\0'; new_mvar(idx.data.string->data, var_buf); } while(array_next(vars, &idx)); } } result = 0; if (oper4->data.number) result |= MPI_ISPRIVATE; if (Prop_Blessed(oper1->data.objref, oper2->data.string->data)) result |= MPI_ISBLESSED; if (hashow) result |= MPI_NOHOW; str = do_parse_mesg(fr->descr, player, oper1->data.objref, mpi, "(parsepropex)", buf, sizeof(buf), result); if (novars > 0) { if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); struct inst temp; temp.type = PROG_STRING; temp.data.string = alloc_prog_string(var_buf); array_setitem(&vars, &idx, &temp); CLEAR(&temp); } while(array_next(vars, &idx)); } free(buffers); varc = mvarcnt; } } oper3->data.array = NULL; CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushArrayRaw(vars); PushString(str); }