00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include <signal.h>
00009
00010 #include "mudconf.h"
00011 #include "config.h"
00012 #include "db.h"
00013 #include "htab.h"
00014 #include "interface.h"
00015 #include "match.h"
00016 #include "externs.h"
00017 #include "attrs.h"
00018 #include "flags.h"
00019 #include "powers.h"
00020 #include "command.h"
00021 #include "alloc.h"
00022 #include "functions.h"
00023 #include "cque.h"
00024 #include "mmdb.h"
00025
00026 extern int a_Queue(dbref, int);
00027 extern void s_Queue(dbref, int);
00028 extern int QueueMax(dbref);
00029
00030 static rbtree obq = NULL;
00031
00032 static int objqe_compare(dbref left, dbref right, void *arg)
00033 {
00034 return (right - left);
00035 }
00036
00037 int cque_init()
00038 {
00039 obq = rb_init((void *) objqe_compare, NULL);
00040 return 1;
00041 };
00042
00043 static OBJQE *cque_find(dbref player)
00044 {
00045 OBJQE *tmp = NULL;
00046
00047 if(obq == NULL) {
00048 cque_init();
00049 }
00050
00051 tmp = rb_find(obq, (void *) player);
00052
00053 if(!tmp && Good_obj(player)) {
00054 tmp = malloc(sizeof(OBJQE));
00055 tmp->obj = player;
00056 tmp->cque = NULL;
00057 tmp->ctail = NULL;
00058 tmp->next = NULL;
00059 tmp->queued = 0;
00060 tmp->wait_que = NULL;
00061 tmp->pending_que = NULL;
00062 rb_insert(obq, (void *) player, tmp);
00063 }
00064
00065 return tmp;
00066 }
00067
00068 static BQUE *cque_peek(dbref player)
00069 {
00070 OBJQE *tmp;
00071 tmp = cque_find(player);
00072 return tmp->cque;
00073 }
00074
00075 static BQUE *cque_deque(dbref player)
00076 {
00077 OBJQE *tmp;
00078 BQUE *cmd;
00079
00080 tmp = cque_find(player);
00081 if(!tmp)
00082 return NULL;
00083
00084 dassert(tmp);
00085
00086 if(!tmp->cque)
00087 return NULL;
00088
00089 cmd = tmp->cque;
00090 if(!cmd->next) {
00091 tmp->cque = tmp->ctail = NULL;
00092 } else {
00093 tmp->cque = cmd->next;
00094 }
00095 return cmd;
00096 }
00097
00098 static void cque_enqueue(dbref player, BQUE * cmd)
00099 {
00100 BQUE *point, *trail;
00101 OBJQE *current, *blocker;
00102 struct timeval tv;
00103 OBJQE *tmp;
00104
00105 cmd->next = NULL;
00106
00107 tv.tv_sec = cmd->waittime - mudstate.now;
00108 tv.tv_usec = 0;
00109
00110 if(cmd->sem == NOTHING) {
00111
00112
00113
00114
00115
00116 if(cmd->waittime <= mudstate.now) {
00117 cmd->waittime = 0;
00118 tmp = cque_find(player);
00119
00120 dassert(tmp);
00121
00122 if(!tmp->ctail) {
00123 tmp->cque = tmp->ctail = cmd;
00124 cmd->next = NULL;
00125 } else {
00126 tmp->ctail->next = cmd;
00127 tmp->ctail = cmd;
00128 tmp->ctail->next = NULL;
00129 }
00130
00131 if(!tmp->queued) {
00132 if(!mudstate.qhead) {
00133 mudstate.qhead = mudstate.qtail = tmp;
00134 tmp->next = NULL;
00135 } else {
00136 mudstate.qtail->next = tmp;
00137 mudstate.qtail = tmp;
00138 mudstate.qtail->next = NULL;
00139 }
00140 tmp->queued = 1;
00141 }
00142 } else {
00143 evtimer_add(&cmd->ev, &tv);
00144 for(point = mudstate.qwait, trail = NULL;
00145 point && point->waittime <= cmd->waittime;
00146 point = point->next) {
00147 trail = point;
00148 }
00149 cmd->next = point;
00150 if(trail != NULL)
00151 trail->next = cmd;
00152 else
00153 mudstate.qwait = cmd;
00154 }
00155 } else {
00156 cmd->next = NULL;
00157 if(mudstate.qsemlast != NULL)
00158 mudstate.qsemlast->next = cmd;
00159 else
00160 mudstate.qsemfirst = cmd;
00161 mudstate.qsemlast = cmd;
00162 }
00163 }
00164
00165 static void wakeup_wait_que(int fd, short event, void *arg)
00166 {
00167 BQUE *pending = (BQUE *) arg;
00168 BQUE *point, trail;
00169
00170 if(mudstate.qwait == pending) {
00171 mudstate.qwait = pending->next;
00172 } else {
00173 for(point = mudstate.qwait; point; point = point->next) {
00174 if(point->next == pending) {
00175 point->next = point->next->next;
00176 break;
00177 }
00178 }
00179 }
00180
00181 pending->waittime = 0;
00182 cque_enqueue(pending->player, pending);
00183 }
00184
00185 static int dump_bqe(struct mmdb_t *mmdb, BQUE *bqe) {
00186 if(bqe == NULL) {
00187 mmdb_write_uint32(mmdb, 0);
00188 return 1;
00189 }
00190 mmdb_write_uint32(mmdb, 1);
00191 mmdb_write_uint32(mmdb, bqe->player);
00192 mmdb_write_uint32(mmdb, bqe->cause);
00193 mmdb_write_uint32(mmdb, bqe->sem);
00194 mmdb_write_uint32(mmdb, bqe->waittime-mudstate.now);
00195 mmdb_write_uint32(mmdb, bqe->attr);
00196 mmdb_write_string(mmdb, bqe->text);
00197 mmdb_write_string(mmdb, bqe->comm);
00198 mmdb_write_uint32(mmdb, NUM_ENV_VARS);
00199 for(int i = 0; i < NUM_ENV_VARS; i++) {
00200 mmdb_write_string(mmdb, bqe->env[i]);
00201 }
00202 mmdb_write_uint32(mmdb, NUM_ENV_VARS);
00203 for(int i = 0; i < NUM_ENV_VARS; i++) {
00204 mmdb_write_string(mmdb, bqe->scr[i]);
00205 }
00206 mmdb_write_uint32(mmdb, bqe->nargs);
00207 dump_bqe(mmdb, bqe->next);
00208 return 1;
00209 }
00210
00211 static int dump_objqe(void *key, void *data, int depth, void *arg) {
00212 struct mmdb_t *mmdb = (struct mmdb_t *)arg;
00213 OBJQE *coq = (OBJQE *)data;
00214 mmdb_write_uint32(mmdb, coq->obj);
00215 dump_bqe(mmdb, coq->cque);
00216 return 1;
00217 }
00218
00219
00220 void cque_dump_restart(struct mmdb_t *mmdb) {
00221 if(obq == NULL) {
00222 cque_init();
00223 }
00224 mmdb_write_uint32(mmdb, rb_size(obq));
00225 if(rb_size(obq) > 0) {
00226 rb_walk(obq, WALK_INORDER, dump_objqe, mmdb);
00227 }
00228 dump_bqe(mmdb, mudstate.qwait);
00229 dump_bqe(mmdb, mudstate.qsemfirst);
00230 }
00231
00232 static void load_bqe(struct mmdb_t *mmdb) {
00233 int exists, count;
00234 struct timeval tv;
00235 BQUE *tmp;
00236 exists = mmdb_read_uint32(mmdb);
00237 if(!exists)
00238 return;
00239 tmp = malloc(sizeof(BQUE));
00240 memset(tmp, 0, sizeof(BQUE));
00241
00242 evtimer_set(&tmp->ev, wakeup_wait_que, tmp);
00243
00244 tmp->player = mmdb_read_uint32(mmdb);
00245 tmp->cause = mmdb_read_uint32(mmdb);
00246 tmp->sem = mmdb_read_uint32(mmdb);
00247 tmp->waittime = mudstate.now + mmdb_read_uint32(mmdb);
00248 tmp->attr = mmdb_read_uint32(mmdb);
00249 tmp->text = mmdb_read_string(mmdb);
00250 tmp->comm = mmdb_read_string(mmdb);
00251 count = mmdb_read_uint32(mmdb);
00252 if(count != NUM_ENV_VARS)
00253 printk("brain damage, count(%d) != NUM_ENV_VARS(%d)", count, NUM_ENV_VARS);
00254 for(int i = 0; i < count; i++) {
00255 if(i < NUM_ENV_VARS)
00256 tmp->env[i] = mmdb_read_string(mmdb);
00257 else
00258 free(mmdb_read_string(mmdb));
00259 }
00260 count = mmdb_read_uint32(mmdb);
00261 if(count != NUM_ENV_VARS)
00262 printk("brain damage, count(%d) != NUM_ENV_VARS(%d)", count, NUM_ENV_VARS);
00263 for(int i = 0; i < count; i++) {
00264 if(i < NUM_ENV_VARS)
00265 tmp->scr[i] = mmdb_read_string(mmdb);
00266 else
00267 free(mmdb_read_string(mmdb));
00268 }
00269 tmp->nargs = mmdb_read_uint32(mmdb);
00270 cque_enqueue(tmp->player, tmp);
00271 load_bqe(mmdb);
00272 }
00273
00274 static void load_objqe(struct mmdb_t *mmdb) {
00275 int object;
00276 OBJQE *coq;
00277 object = mmdb_read_uint32(mmdb);
00278 coq = cque_find(object);
00279 load_bqe(mmdb);
00280 }
00281
00282
00283 void cque_load_restart(struct mmdb_t *mmdb) {
00284 int count;
00285 count = mmdb_read_uint32(mmdb);
00286 for(int i = 0; i < count; i++) {
00287 load_objqe(mmdb);
00288 }
00289 load_bqe(mmdb);
00290 load_bqe(mmdb);
00291 }
00292
00293 #if 0
00294 void cque_dump_restart(FILE *f) {
00295 OBJQE *coq;
00296 BQUE *bqe;
00297 if(!mudstate.qhead) {
00298 fprintf(f, "%d\n", 0);
00299 return;
00300 }
00301 for(coq = mudstate.qhead; coq != NULL; coq = coq->next) {
00302 fprintf("%d\n", coq->obj);
00303 for(bqe = coq->cque; bqe != NULL; bqe = bqe->next) {
00304 fprintf(f, "1\n");
00305 fprintf(f, "%d\n%d\n%d\n", bqe->player, bqe->cause, bqe->sem);
00306 fprintf(f, "%d\n%d\n", bqe->waittime - mudstate.now, bqe->attr);
00307 fprintf(f, "");
00308 }
00309 }
00310 #endif
00311
00312
00313
00314
00315
00316
00317 static int add_to(dbref player, int am, int attrnum)
00318 {
00319 int num, aflags;
00320 dbref aowner;
00321 char buff[20];
00322 char *atr_gotten;
00323
00324 num = atoi(atr_gotten = atr_get(player, attrnum, &aowner, &aflags));
00325 free_lbuf(atr_gotten);
00326 num += am;
00327 if(num)
00328 sprintf(buff, "%d", num);
00329 else
00330 *buff = '\0';
00331 atr_add_raw(player, attrnum, buff);
00332 return (num);
00333 }
00334
00335
00336
00337
00338
00339
00340 static int que_want(BQUE * entry, dbref ptarg, dbref otarg)
00341 {
00342 if((ptarg != NOTHING) && (ptarg != Owner(entry->player)))
00343 return 0;
00344 if((otarg != NOTHING) && (otarg != entry->player))
00345 return 0;
00346 return 1;
00347 }
00348
00349
00350
00351
00352
00353
00354 int halt_que(dbref player, dbref object)
00355 {
00356 BQUE *trail, *point, *next;
00357 OBJQE *pque;
00358
00359 int numhalted;
00360
00361 numhalted = 0;
00362
00363
00364
00365
00366 pque = cque_find(player);
00367 if(pque && pque->cque) {
00368 while ((point = cque_deque(player)) != NULL) {
00369 free(point->text);
00370 point->text = NULL;
00371 free_qentry(point);
00372 point = NULL;
00373 numhalted++;
00374 }
00375 }
00376 pque = cque_find(object);
00377 if(pque && pque->cque) {
00378 while ((point = cque_deque(object)) != NULL) {
00379 free(point->text);
00380 point->text = NULL;
00381 free_qentry(point);
00382 point = NULL;
00383 numhalted++;
00384 }
00385 }
00386
00387
00388
00389
00390
00391 for(point = mudstate.qwait, trail = NULL; point; point = next)
00392 if(que_want(point, player, object)) {
00393 numhalted++;
00394 if(trail)
00395 trail->next = next = point->next;
00396 else
00397 mudstate.qwait = next = point->next;
00398 if(evtimer_pending(&point->ev, NULL))
00399 evtimer_del(&point->ev);
00400 free(point->text);
00401 free_qentry(point);
00402 } else
00403 next = (trail = point)->next;
00404
00405
00406
00407
00408
00409 for(point = mudstate.qsemfirst, trail = NULL; point; point = next)
00410 if(que_want(point, player, object)) {
00411 numhalted++;
00412 if(trail)
00413 trail->next = next = point->next;
00414 else
00415 mudstate.qsemfirst = next = point->next;
00416 if(point == mudstate.qsemlast)
00417 mudstate.qsemlast = trail;
00418 add_to(point->sem, -1, point->attr);
00419 free(point->text);
00420 free_qentry(point);
00421 } else
00422 next = (trail = point)->next;
00423
00424 if(player == NOTHING)
00425 player = Owner(object);
00426 giveto(player, (mudconf.waitcost * numhalted));
00427 if(object == NOTHING)
00428 s_Queue(player, 0);
00429 else
00430 a_Queue(player, -numhalted);
00431 return numhalted;
00432 }
00433
00434
00435
00436
00437
00438
00439 void do_halt(dbref player, dbref cause, int key, char *target)
00440 {
00441 dbref player_targ, obj_targ;
00442 int numhalted;
00443
00444 if((key & HALT_ALL) && !(Can_Halt(player))) {
00445 notify(player, "Permission denied.");
00446 return;
00447 }
00448
00449
00450
00451
00452 if(!target || !*target) {
00453 obj_targ = NOTHING;
00454 if(key & HALT_ALL) {
00455 player_targ = NOTHING;
00456 } else {
00457 player_targ = Owner(player);
00458 if(Typeof(player) != TYPE_PLAYER)
00459 obj_targ = player;
00460 }
00461 } else {
00462 if(Can_Halt(player))
00463 obj_targ = match_thing(player, target);
00464 else
00465 obj_targ = match_controlled(player, target);
00466
00467 if(obj_targ == NOTHING)
00468 return;
00469 if(key & HALT_ALL) {
00470 notify(player, "Can't specify a target and /all");
00471 return;
00472 }
00473 if(Typeof(obj_targ) == TYPE_PLAYER) {
00474 player_targ = obj_targ;
00475 obj_targ = NOTHING;
00476 } else {
00477 player_targ = NOTHING;
00478 }
00479 }
00480
00481 numhalted = halt_que(player_targ, obj_targ);
00482 if(Quiet(player))
00483 return;
00484 if(numhalted == 1)
00485 notify(Owner(player), "1 queue entries removed.");
00486 else
00487 notify_printf(Owner(player), "%d queue entries removed.", numhalted);
00488 }
00489
00490
00491
00492
00493
00494
00495 int nfy_que(dbref sem, int attr, int key, int count)
00496 {
00497 BQUE *point, *trail, *next;
00498 int num, aflags;
00499 dbref aowner;
00500 char *str;
00501
00502 if(attr) {
00503 str = atr_get(sem, attr, &aowner, &aflags);
00504 num = atoi(str);
00505 free_lbuf(str);
00506 } else {
00507 num = 1;
00508 }
00509
00510 if(num > 0) {
00511 num = 0;
00512 for(point = mudstate.qsemfirst, trail = NULL; point; point = next) {
00513 if((point->sem == sem) && ((point->attr == attr) || !attr)) {
00514 num++;
00515 if(trail)
00516 trail->next = next = point->next;
00517 else
00518 mudstate.qsemfirst = next = point->next;
00519 if(point == mudstate.qsemlast)
00520 mudstate.qsemlast = trail;
00521
00522
00523
00524
00525
00526 if(key != NFY_DRAIN) {
00527 point->sem = NOTHING;
00528 point->waittime = 0;
00529 cque_enqueue(point->player, point);
00530 } else {
00531 giveto(point->player, mudconf.waitcost);
00532 a_Queue(Owner(point->player), -1);
00533 free(point->text);
00534 free_qentry(point);
00535 }
00536 } else {
00537 next = (trail = point)->next;
00538 }
00539
00540
00541
00542
00543
00544 if((key == NFY_NFY) && (num >= count))
00545 next = NULL;
00546 }
00547 } else {
00548 num = 0;
00549 }
00550
00551
00552
00553
00554
00555 if(key == NFY_NFY)
00556 add_to(sem, -count, attr);
00557 else
00558 atr_clr(sem, attr);
00559
00560 return num;
00561 }
00562
00563
00564
00565
00566
00567
00568 void do_notify(dbref player, dbref cause, int key, char *what, char *count)
00569 {
00570 dbref thing, aowner;
00571 int loccount, attr = -1, aflags;
00572 ATTR *ap;
00573 char *obj;
00574
00575 obj = parse_to(&what, '/', 0);
00576 init_match(player, obj, NOTYPE);
00577 match_everything(0);
00578
00579 if((thing = noisy_match_result()) < 0) {
00580 notify(player, "No match.");
00581 } else if(!controls(player, thing) && !Link_ok(thing)) {
00582 notify(player, "Permission denied.");
00583 } else {
00584 if(!what || !*what) {
00585 ap = NULL;
00586 } else {
00587 ap = atr_str(what);
00588 }
00589
00590 if(!ap) {
00591 attr = A_SEMAPHORE;
00592 } else {
00593
00594 atr_pget_info(thing, ap->number, &aowner, &aflags);
00595 if(Set_attr(player, thing, ap, aflags)) {
00596 attr = ap->number;
00597 } else {
00598 notify_quiet(player, "Permission denied.");
00599 return;
00600 }
00601 }
00602
00603 if(count && *count)
00604 loccount = atoi(count);
00605 else
00606 loccount = 1;
00607 if(loccount > 0) {
00608 nfy_que(thing, attr, key, loccount);
00609 if(!(Quiet(player) || Quiet(thing))) {
00610 if(key == NFY_DRAIN)
00611 notify_quiet(player, "Drained.");
00612 else
00613 notify_quiet(player, "Notified.");
00614 }
00615 }
00616 }
00617 }
00618
00619
00620
00621
00622
00623
00624 static BQUE *setup_que(dbref player, dbref cause, char *command, char *args[],
00625 int nargs, char *sargs[])
00626 {
00627 int a, tlen;
00628 BQUE *tmp;
00629 char *tptr;
00630
00631
00632
00633
00634
00635 if(Halted(player))
00636 return NULL;
00637
00638
00639
00640
00641
00642 a = mudconf.waitcost;
00643 if(mudconf.machinecost && ((random() % mudconf.machinecost) == 0))
00644 a++;
00645 if(!payfor(player, a)) {
00646 notify(Owner(player), "Not enough money to queue command.");
00647 return NULL;
00648 }
00649
00650
00651
00652
00653
00654 a = QueueMax(Owner(player));
00655 if(a_Queue(Owner(player), 1) > a) {
00656 notify(Owner(player),
00657 "Run away objects: too many commands queued. Halted.");
00658 halt_que(Owner(player), NOTHING);
00659
00660
00661
00662
00663 s_Halted(player);
00664 return NULL;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674 tlen = 0;
00675 if(command)
00676 tlen = strlen(command) + 1;
00677 if(nargs > NUM_ENV_VARS)
00678 nargs = NUM_ENV_VARS;
00679 for(a = 0; a < nargs; a++) {
00680 if(args[a])
00681 tlen += (strlen(args[a]) + 1);
00682 }
00683 if(sargs) {
00684 for(a = 0; a < NUM_ENV_VARS; a++) {
00685 if(sargs[a])
00686 tlen += (strlen(sargs[a]) + 1);
00687 }
00688 }
00689
00690
00691
00692
00693 tmp = malloc(sizeof(BQUE));
00694 memset(tmp, 0, sizeof(BQUE));
00695 tmp->comm = NULL;
00696 for(a = 0; a < NUM_ENV_VARS; a++) {
00697 tmp->env[a] = NULL;
00698 }
00699 for(a = 0; a < MAX_GLOBAL_REGS; a++) {
00700 tmp->scr[a] = NULL;
00701 }
00702
00703 tptr = tmp->text = (char *) malloc(tlen);
00704 if(command) {
00705 StringCopy(tptr, command);
00706 tmp->comm = tptr;
00707 tptr += (strlen(command) + 1);
00708 }
00709 for(a = 0; a < nargs; a++) {
00710 if(args[a]) {
00711 StringCopy(tptr, args[a]);
00712 tmp->env[a] = tptr;
00713 tptr += (strlen(args[a]) + 1);
00714 }
00715 }
00716 if(sargs) {
00717 for(a = 0; a < MAX_GLOBAL_REGS; a++) {
00718 if(sargs[a]) {
00719 StringCopy(tptr, sargs[a]);
00720 tmp->scr[a] = tptr;
00721 tptr += (strlen(sargs[a]) + 1);
00722 }
00723 }
00724 }
00725
00726
00727
00728
00729 evtimer_set(&tmp->ev, wakeup_wait_que, tmp);
00730
00731 tmp->player = player;
00732 tmp->waittime = 0;
00733 tmp->next = NULL;
00734 tmp->sem = NOTHING;
00735 tmp->attr = 0;
00736 tmp->cause = cause;
00737 tmp->nargs = nargs;
00738 return tmp;
00739 }
00740
00741
00742
00743
00744
00745
00746 void wait_que(dbref player, dbref cause, int wait, dbref sem, int attr,
00747 char *command, char *args[], int nargs, char *sargs[])
00748 {
00749 BQUE *cmd;
00750 if(mudconf.control_flags & CF_INTERP)
00751 cmd = setup_que(player, cause, command, args, nargs, sargs);
00752 else
00753 cmd = NULL;
00754
00755 if(cmd == NULL) {
00756 return;
00757 }
00758
00759 if(wait > 0) {
00760 cmd->waittime = mudstate.now + wait;
00761 } else {
00762 cmd->waittime = 0;
00763 }
00764
00765 cmd->sem = sem;
00766 cmd->attr = attr;
00767
00768 cque_enqueue(player, cmd);
00769 }
00770
00771
00772
00773
00774
00775
00776
00777 void do_wait(dbref player, dbref cause, int key, char *event, char *cmd,
00778 char *cargs[], int ncargs)
00779 {
00780 dbref thing, aowner;
00781 int howlong, num, attr, aflags;
00782 char *what;
00783 ATTR *ap;
00784
00785
00786
00787
00788
00789 if(is_number(event)) {
00790 howlong = atoi(event);
00791 wait_que(player, cause, howlong, NOTHING, 0, cmd, cargs, ncargs,
00792 mudstate.global_regs);
00793 return;
00794 }
00795
00796
00797
00798
00799 what = parse_to(&event, '/', 0);
00800 init_match(player, what, NOTYPE);
00801 match_everything(0);
00802
00803 thing = noisy_match_result();
00804 if(!Good_obj(thing)) {
00805 notify(player, "No match.");
00806 } else if(!controls(player, thing) && !Link_ok(thing)) {
00807 notify(player, "Permission denied.");
00808 } else {
00809
00810
00811
00812
00813
00814 if(event && *event && is_number(event)) {
00815 attr = A_SEMAPHORE;
00816 howlong = atoi(event);
00817 } else {
00818 attr = A_SEMAPHORE;
00819 howlong = 0;
00820 }
00821
00822 if(event && *event && !is_number(event)) {
00823 ap = atr_str(event);
00824 if(!ap) {
00825 attr = mkattr(event);
00826 if(attr <= 0) {
00827 notify_quiet(player, "Invalid attribute.");
00828 return;
00829 }
00830 ap = atr_num(attr);
00831 }
00832 atr_pget_info(thing, ap->number, &aowner, &aflags);
00833 if(attr && Set_attr(player, thing, ap, aflags)) {
00834 attr = ap->number;
00835 howlong = 0;
00836 } else {
00837 notify_quiet(player, "Permission denied.");
00838 return;
00839 }
00840 }
00841
00842 num = add_to(thing, 1, attr);
00843 if(num <= 0) {
00844
00845
00846
00847
00848
00849 thing = NOTHING;
00850 howlong = 0;
00851 }
00852 wait_que(player, cause, howlong, thing, attr, cmd, cargs, ncargs,
00853 mudstate.global_regs);
00854 }
00855 }
00856
00857
00858
00859
00860
00861
00862 void do_second(void)
00863 {
00864 BQUE *trail, *point, *next;
00865 char *cmdsave;
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 if((mudconf.control_flags & CF_DEQUEUE) == 0)
00876 return;
00877
00878 cmdsave = mudstate.debug_cmd;
00879 mudstate.debug_cmd = (char *) "< do_second >";
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 for(point = mudstate.qsemfirst, trail = NULL; point; point = next) {
00892 if(point->waittime == 0) {
00893 next = (trail = point)->next;
00894 continue;
00895
00896
00897 }
00898 if(point->waittime <= mudstate.now) {
00899 if(trail != NULL)
00900 trail->next = next = point->next;
00901 else
00902 mudstate.qsemfirst = next = point->next;
00903 if(point == mudstate.qsemlast)
00904 mudstate.qsemlast = trail;
00905 add_to(point->sem, -1, point->attr);
00906 point->sem = NOTHING;
00907 point->waittime = 0;
00908 printk("promoting, %d/%s", point->player, point->comm);
00909 cque_enqueue(point->player, point);
00910 } else
00911 next = (trail = point)->next;
00912 }
00913 mudstate.debug_cmd = cmdsave;
00914 return;
00915 }
00916
00917
00918
00919
00920
00921
00922 int do_top(int ncmds)
00923 {
00924 BQUE *tmp, *walk;
00925 OBJQE *current_object;
00926 dbref object, player, last_player;
00927 int count, i;
00928 char *command, *cp, *cmdsave;
00929
00930 if((mudconf.control_flags & CF_DEQUEUE) == 0)
00931 return 0;
00932
00933 cmdsave = mudstate.debug_cmd;
00934 mudstate.debug_cmd = (char *) "< do_top >";
00935
00936 if(!mudstate.qhead)
00937 return 0;
00938
00939 current_object = mudstate.qhead;
00940 count = 0;
00941
00942 while (count < ncmds && mudstate.qhead) {
00943 if(!mudstate.qhead)
00944 break;
00945
00946 object = mudstate.qhead->obj;
00947 tmp = cque_deque(object);
00948
00949 if(!mudstate.qhead->cque) {
00950 mudstate.qhead->queued = 0;
00951 mudstate.qhead = mudstate.qhead->next;
00952 if(mudstate.qhead == NULL)
00953 mudstate.qtail = NULL;
00954 } else {
00955 mudstate.qtail->next = mudstate.qhead;
00956 mudstate.qtail = mudstate.qtail->next;
00957 mudstate.qhead = mudstate.qhead->next;
00958 mudstate.qtail->next = NULL;
00959 }
00960 if(!tmp)
00961 continue;
00962
00963 dassert(tmp);
00964 count++;
00965 if((object >= 0) && !Going(object)) {
00966 giveto(object, mudconf.waitcost);
00967 mudstate.curr_enactor = tmp->cause;
00968 mudstate.curr_player = object;
00969 a_Queue(Owner(object), -1);
00970 if(!Halted(object)) {
00971 for(i = 0; i < MAX_GLOBAL_REGS; i++) {
00972 if(tmp->scr[i]) {
00973 StringCopy(mudstate.global_regs[i], tmp->scr[i]);
00974 } else {
00975 *mudstate.global_regs[i] = '\0';
00976 }
00977 }
00978
00979 command = tmp->comm;
00980
00981 if(command) {
00982 if(isPlayer(object) && Connected(object))
00983 choke_player(object);
00984 while (command) {
00985 cp = parse_to(&command, ';', 0);
00986 if(cp && *cp) {
00987 while (command && (*command == '|')) {
00988 command++;
00989 mudstate.inpipe = 1;
00990 mudstate.poutnew =
00991 alloc_lbuf("process_command.pipe");
00992 mudstate.poutbufc = mudstate.poutnew;
00993 mudstate.poutobj = object;
00994 process_command(object, tmp->cause, 0, cp,
00995 tmp->env, tmp->nargs);
00996 if(mudstate.pout) {
00997 free_lbuf(mudstate.pout);
00998 mudstate.pout = NULL;
00999 }
01000
01001 *mudstate.poutbufc = '\0';
01002 mudstate.pout = mudstate.poutnew;
01003 cp = parse_to(&command, ';', 0);
01004 }
01005 mudstate.inpipe = 0;
01006 process_command(object, tmp->cause, 0,
01007 cp, tmp->env, tmp->nargs);
01008 if(mudstate.pout) {
01009 free_lbuf(mudstate.pout);
01010 mudstate.pout = NULL;
01011 }
01012 }
01013 }
01014 if(isPlayer(object) && Connected(object))
01015 release_player(object);
01016 }
01017 }
01018 }
01019 free(tmp->text);
01020 free_qentry(tmp);
01021 }
01022
01023 for(i = 0; i < MAX_GLOBAL_REGS; i++)
01024 *mudstate.global_regs[i] = '\0';
01025 mudstate.debug_cmd = cmdsave;
01026 return count;
01027 }
01028
01029
01030
01031
01032
01033
01034 static void show_que(dbref player, int key, BQUE * queue, int *qent,
01035 const char *header)
01036 {
01037 BQUE *tmp;
01038 char *bp, *bufp;
01039 int i;
01040
01041 for(tmp = queue; tmp; tmp = tmp->next) {
01042 (*qent)++;
01043 if(key == PS_SUMM)
01044 continue;
01045 if(*qent == 1)
01046 notify_printf(player, "----- %s Queue -----", header);
01047
01048 bufp = unparse_object(player, tmp->player, 0);
01049 if ( !(key & PS_ALL) )
01050 if((player != Owner(tmp->player)))
01051 continue;
01052 if((tmp->waittime > 0) && (Good_obj(tmp->sem)))
01053 notify_printf(player, "[#%d/%d]%s:%s", tmp->sem,
01054 tmp->waittime-mudstate.now, bufp, tmp->comm);
01055 else if(tmp->waittime > 0)
01056 notify_printf(player, "[%d]%s:%s", tmp->waittime-mudstate.now,
01057 bufp, tmp->comm);
01058 else if(Good_obj(tmp->sem))
01059 notify_printf(player, "[#%d]%s:%s", tmp->sem, bufp, tmp->comm);
01060 else
01061 notify_printf(player, "%s:%s", bufp, tmp->comm);
01062
01063 bp = bufp;
01064 if(key == PS_LONG) {
01065 for(i = 0; i < (tmp->nargs); i++) {
01066 if(tmp->env[i] != NULL) {
01067 safe_str((char *) "; Arg", bufp, &bp);
01068 safe_chr(i + '0', bufp, &bp);
01069 safe_str((char *) "='", bufp, &bp);
01070 safe_str(tmp->env[i], bufp, &bp);
01071 safe_chr('\'', bufp, &bp);
01072 }
01073 }
01074 *bp = '\0';
01075 bp = unparse_object(player, tmp->cause, 0);
01076 notify_printf(player, " Enactor: %s%s", bp, bufp);
01077 free_lbuf(bp);
01078 }
01079 free_lbuf(bufp);
01080 }
01081 return;
01082 }
01083
01084 void do_ps(dbref player, dbref cause, int key, char *target)
01085 {
01086 char *bufp;
01087 dbref player_targ, obj_targ;
01088 int pqent, pqtot, pqdel, oqent, oqtot, oqdel, wqent, wqtot, sqent,
01089 sqtot, i;
01090 OBJQE *objq;
01091 int tempkey;
01092
01093
01094
01095
01096
01097 if((key & PS_ALL) && !(See_Queue(player))) {
01098 notify(player, "Permission denied.");
01099 return;
01100 }
01101 if(!target || !*target) {
01102 obj_targ = NOTHING;
01103 if(key & PS_ALL) {
01104 player_targ = NOTHING;
01105 } else {
01106 player_targ = Owner(player);
01107 if(Typeof(player) != TYPE_PLAYER)
01108 obj_targ = player;
01109 }
01110 } else {
01111 player_targ = Owner(player);
01112 obj_targ = match_controlled(player, target);
01113 if(obj_targ == NOTHING)
01114 return;
01115 if(key & PS_ALL) {
01116 notify(player, "Can't specify a target and /all");
01117 return;
01118 }
01119 if(Typeof(obj_targ) == TYPE_PLAYER) {
01120 player_targ = obj_targ;
01121 obj_targ = NOTHING;
01122 }
01123 }
01124 tempkey = key;
01125 key = key & ~PS_ALL;
01126 switch (key) {
01127 case PS_BRIEF:
01128 case PS_SUMM:
01129 case PS_LONG:
01130 break;
01131 default:
01132 notify(player, "Illegal combination of switches.");
01133 return;
01134 }
01135
01136
01137
01138
01139 pqtot = 0;
01140 if(player_targ == NOTHING) {
01141 objq = mudstate.qhead;
01142 while (objq && (objq = objq->next) != NULL) {
01143 pqent = 0;
01144 show_que(player, tempkey, objq->cque, &pqent, "PLAYAH");
01145 pqtot += pqent;
01146 }
01147 } else {
01148 pqent = 0;
01149 objq = cque_find(player_targ);
01150 if(objq) {
01151 show_que(player, tempkey, objq->cque, &pqent, "PLAYAH");
01152 }
01153 }
01154
01155 wqent = 0;
01156 sqent = 0;
01157 wqtot = 0;
01158 sqtot = 0;
01159 show_que(player, tempkey, mudstate.qwait, &wqent, "Wait");
01160 show_que(player, tempkey, mudstate.qsemfirst, &sqent, "Semaphore");
01161
01162
01163
01164
01165
01166 if(See_Queue(player))
01167 notify_printf(player,
01168 "Totals: Player...%d/%d Wait...%d/%d Semaphore...%d/%d",
01169 pqent, pqtot, wqent, wqtot, sqent, sqtot);
01170 else
01171 notify_printf(player,
01172 "Totals: Player...%d/%d Wait...%d/%d Semaphore...%d/%d",
01173 pqent, pqtot, wqent, wqtot, sqent, sqtot);
01174 }
01175
01176
01177
01178
01179
01180
01181 void do_queue(dbref player, dbref cause, int key, char *arg)
01182 {
01183 BQUE *point;
01184 int i, ncmds, was_disabled;
01185
01186 dprintk("WTF?");
01187 was_disabled = 0;
01188 if(key == QUEUE_KICK) {
01189 i = atoi(arg);
01190 if((mudconf.control_flags & CF_DEQUEUE) == 0) {
01191 was_disabled = 1;
01192 mudconf.control_flags |= CF_DEQUEUE;
01193 notify(player, "Warning: automatic dequeueing is disabled.");
01194 }
01195 ncmds = do_top(i);
01196 if(was_disabled)
01197 mudconf.control_flags &= ~CF_DEQUEUE;
01198 if(!Quiet(player))
01199 notify_printf(player, "%d commands processed.", ncmds);
01200 } else if(key == QUEUE_WARP) {
01201 i = atoi(arg);
01202 if((mudconf.control_flags & CF_DEQUEUE) == 0) {
01203 was_disabled = 1;
01204 mudconf.control_flags |= CF_DEQUEUE;
01205 notify(player, "Warning: automatic dequeueing is disabled.");
01206 }
01207
01208
01209
01210
01211
01212 for(point = mudstate.qsemfirst; point; point = point->next) {
01213 if(point->waittime > 0) {
01214 point->waittime -= i;
01215 if(point->waittime <= 0)
01216 point->waittime = -1;
01217 }
01218 }
01219
01220 do_second();
01221 if(was_disabled)
01222 mudconf.control_flags &= ~CF_DEQUEUE;
01223 if(Quiet(player))
01224 return;
01225 if(i > 0)
01226 notify_printf(player, "WaitQ timer advanced %d seconds.", i);
01227 else if(i < 0)
01228 notify_printf(player, "WaitQ timer set back %d seconds.", i);
01229 else
01230 notify(player, "Object queue appended to player queue.");
01231
01232 }
01233 }