static void NDECL(check_cron) { struct tm *ltime; int minute, hour, dom, month, dow; CRONTAB *crp; char *cmd; dbref aowner; int aflags, alen; /* Convert our time to a zero basis, so the elements can be used * as indices. */ ltime = localtime(&mudstate.events_counter); minute = ltime->tm_min - FIRST_MINUTE; hour = ltime->tm_hour - FIRST_HOUR; dom = ltime->tm_mday - FIRST_DOM; month = ltime->tm_mon + 1 - FIRST_MONTH; /* must convert 0-11 to 1-12 */ dow = ltime->tm_wday - FIRST_DOW; /* Do it if the minute, hour, and month match, plus a day selection * matches. We handle stars and the day-of-month vs. day-of-week * exactly like Unix (Vixie) cron does. */ for (crp = cron_head; crp != NULL; crp = crp->next) { if (bit_test(crp->minute, minute) && bit_test(crp->hour, hour) && bit_test(crp->month, month) && (((crp->flags & DOM_STAR) || (crp->flags & DOW_STAR)) ? (bit_test(crp->dow, dow) && bit_test(crp->dom, dom)) : (bit_test(crp->dow, dow) || bit_test(crp->dom, dom)))) { cmd = atr_pget(crp->obj, crp->atr, &aowner, &aflags, &alen); if (*cmd && Good_obj(crp->obj)) { wait_que(crp->obj, crp->obj, 0, NOTHING, 0, cmd, (char **) NULL, 0, NULL); } free_lbuf(cmd); } } }
/* --------------------------------------------------------------------------- * did_it_rlevel: Have player do something to/with thing, watching the * attributes. 'what' is actually ignored, the desclist match being used * instead. */ void did_it_rlevel ( dbref player, dbref thing, int what, const UTF8 *def, int owhat, const UTF8 *odef, int awhat, int ctrl_flags, const UTF8 *args[], int nargs ) { if (MuxAlarm.bAlarmed) { return; } UTF8 *d, *buff, *act, *charges, *bp; dbref aowner; int num, aflags; int i; bool found_a_desc; reg_ref **preserve = NULL; bool need_pres = false; // Message to player. // if (0 < what) { // Get description list. // DESC_INFO *desclist = desclist_match(player, thing); found_a_desc = false; for (i = 0; i < desclist->n; i++) { // Ok, if it's A_DESC, we need to check against A_IDESC. // if ( A_IDESC == what && A_DESC == desclist->descs[i]) { d = atr_pget(thing, A_IDESC, &aowner, &aflags); } else { d = atr_pget(thing, desclist->descs[i], &aowner, &aflags); } if ('\0' != d[0]) { // No need for the 'def' message. // found_a_desc = true; if (!need_pres) { need_pres = true; preserve = PushRegisters(MAX_GLOBAL_REGS); save_global_regs(preserve); } buff = bp = alloc_lbuf("did_it.1"); mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player, AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP), args, nargs); *bp = '\0'; if ( A_HTDESC == desclist->descs[i] && Html(player)) { safe_str(T("\r\n"), buff, &bp); *bp = '\0'; notify_html(player, buff); } else { notify(player, buff); } free_lbuf(buff); } free_lbuf(d); } if (!found_a_desc) { // No desc found... try the default desc (again). // A_DESC or A_HTDESC... the worst case we look for it twice. // d = atr_pget(thing, what, &aowner, &aflags); if ('\0' != d[0]) { // No need for the 'def' message // found_a_desc = true; if (!need_pres) { need_pres = true; preserve = PushRegisters(MAX_GLOBAL_REGS); save_global_regs(preserve); } buff = bp = alloc_lbuf("did_it.1"); mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player, AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP), args, nargs); *bp = '\0'; if ( A_HTDESC == what && Html(player)) { safe_str(T("\r\n"), buff, &bp); *bp = '\0'; notify_html(player, buff); } else { notify(player, buff); } free_lbuf(buff); } else if (def) { notify(player, def); } free_lbuf(d); } } else if ( what < 0 && def) { notify(player, def); } if (isPlayer(thing)) { d = atr_pget(mudconf.master_room, get_atr(T("ASSET_DESC")), &aowner, &aflags); if (*d) { if (!need_pres) { need_pres = true; preserve = PushRegisters(MAX_GLOBAL_REGS); save_global_regs(preserve); } buff = bp = alloc_lbuf("did_it.1"); mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player, AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP), args, nargs); *bp = '\0'; notify(player, buff); free_lbuf(buff); } free_lbuf(d); } // Message to neighbors. // dbref loc; if ( 0 < owhat && Has_location(player) && Good_obj(loc = Location(player))) { d = atr_pget(thing, owhat, &aowner, &aflags); if (*d) { if (!need_pres) { need_pres = true; preserve = PushRegisters(MAX_GLOBAL_REGS); save_global_regs(preserve); } buff = bp = alloc_lbuf("did_it.2"); mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player, AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP), args, nargs); *bp = '\0'; if (*buff) { if (aflags & AF_NONAME) { notify_except2_rlevel2(loc, player, player, thing, buff); } else { notify_except2_rlevel2(loc, player, player, thing, tprintf(T("%s %s"), Name(player), buff)); } } free_lbuf(buff); } else if (odef) { if (ctrl_flags & VERB_NONAME) { notify_except2_rlevel2(loc, player, player, thing, odef); } else { notify_except2_rlevel2(loc, player, player, thing, tprintf(T("%s %s"), Name(player), odef)); } } free_lbuf(d); } else if ( owhat < 0 && odef && Has_location(player) && Good_obj(loc = Location(player))) { if (ctrl_flags & VERB_NONAME) { notify_except2_rlevel2(loc, player, player, thing, odef); } else { notify_except2_rlevel2(loc, player, player, thing, tprintf(T("%s %s"), Name(player), odef)); } } // If we preserved the state of the global registers, restore them. // if (need_pres) { restore_global_regs(preserve); PopRegisters(preserve, MAX_GLOBAL_REGS); } // Do the action attribute. // if ( awhat > 0 && IsReal(thing, player)) { act = atr_pget(thing, awhat, &aowner, &aflags); if (*act != '\0') { charges = atr_pget(thing, A_CHARGES, &aowner, &aflags); if (*charges) { num = mux_atol(charges); if (num > 0) { buff = alloc_sbuf("did_it.charges"); mux_ltoa(num-1, buff); atr_add_raw(thing, A_CHARGES, buff); free_sbuf(buff); } else { buff = atr_pget(thing, A_RUNOUT, &aowner, &aflags); if (*buff != '\0') { free_lbuf(act); act = buff; } else { free_lbuf(act); free_lbuf(buff); free_lbuf(charges); return; } } } free_lbuf(charges); CLinearTimeAbsolute lta; wait_que(thing, player, player, AttrTrace(aflags, 0), false, lta, NOTHING, 0, act, nargs, args, mudstate.global_regs); } free_lbuf(act); } }
// --------------------------------------------------------------------------- // do_wait: Command interface to wait_que // void do_wait ( dbref executor, dbref caller, dbref enactor, int eval, int key, char *event, char *cmd, char *cargs[], int ncargs ) { CLinearTimeAbsolute ltaWhen; CLinearTimeDelta ltd; // If arg1 is all numeric, do simple (non-sem) timed wait. // if (is_rational(event)) { if (key & WAIT_UNTIL) { ltaWhen.SetSecondsString(event); } else { ltaWhen.GetUTC(); ltd.SetSecondsString(event); ltaWhen += ltd; } wait_que(executor, caller, enactor, eval, true, ltaWhen, NOTHING, 0, cmd, ncargs, cargs, mudstate.global_regs); return; } // Semaphore wait with optional timeout. // char *what = parse_to(&event, '/', 0); init_match(executor, what, NOTYPE); match_everything(0); dbref thing = noisy_match_result(); if (!Good_obj(thing)) { return; } else if (!Controls(executor, thing) && !Link_ok(thing)) { notify(executor, NOPERM_MESSAGE); } else { // Get timeout, default 0. // int atr = A_SEMAPHORE; bool bTimed = false; if (event && *event) { if (is_rational(event)) { if (key & WAIT_UNTIL) { ltaWhen.SetSecondsString(event); } else { ltaWhen.GetUTC(); ltd.SetSecondsString(event); ltaWhen += ltd; } bTimed = true; } else { ATTR *ap = atr_str(event); if (!ap) { atr = mkattr(executor, event); if (atr <= 0) { notify_quiet(executor, "Invalid attribute."); return; } ap = atr_num(atr); } else { atr = ap->number; } if (!bCanSetAttr(executor, thing, ap)) { notify_quiet(executor, NOPERM_MESSAGE); return; } } } int num = add_to(thing, 1, atr); if (num <= 0) { // Thing over-notified, run the command immediately. // thing = NOTHING; bTimed = false; } wait_que(executor, caller, enactor, eval, bTimed, ltaWhen, thing, atr, cmd, ncargs, cargs, mudstate.global_regs); } }