/* look at ../docs/COPYING for copyright */ #include "strings.h" #include "db.h" #include "config.h" #include "externs.h" #include "interface.h" #include "params.h" const char *trash_braces(const char *what) { char buff[BUFFER_LEN]; if(*what == '{' && what[strlen(what) -1] == '}') { strcpy(buff, what+1); buff[strlen(buff) -1] = '\0'; } else return what; return buff; } char *awptr[10]; struct das { dbref who; dbref owner; /* the owner of who... don't execut * * the command if this isn't the same, * * because we might have been recycled. */ char *command; /* command.. free this when we're done. */ dbref trigger; /* who made us go? */ char *awptr[10]; /* the %[0-9]'s */ struct das *next; /* the next thing in our LinkedList */ }; struct das *que=NULL; int gotio; /* flag that game.c sets when we get * * some io in one our sockets... signals * * us to stop. */ #define MINEX 5 /* how many we have to execute minimum */ int que_check() { return (que!=NULL); } /* for interface.c. we check the queue to see if there's anything in there. if there isn't, we wait a whole second for more input. Otherwise, there's stuff in tue queue, so we just quick check input, and then come right back and process some more queued commands. */ int sofar; static void freer(struct das *what) { register int i; if(what->command) free(what->command); for(i=0;i<10;i++) if(what->awptr[i]) free(what->awptr[i]); free(what); } static void check_a_wait() { struct das *cur; if(que == NULL) /* no junk in the queue, quit */ return; cur = que; que = que->next; if(!is_ok(cur->who)) { /* preblie been recycled */ if(is_ok(cur->owner)) { /* we HOPE the owner's ok */ sprintf(buf,"Object #%d no longer exists."); notify(cur->owner,buf); } else { sprintf(buf,"CWAITS: weird object #%d owned by #%d.", cur->who,cur->owner); log_status(buf); } freer(cur); return; } if(OWNER(cur->who) != cur->owner) { /* aack, ownership change! */ sprintf(buf,"Object %s halted... %s now owns it.", unparse_object(OWNER(cur->who),cur->who), /* old owner should know * what we're talkin bout * even if can't see it.. */ unparse_object(cur->owner,OWNER(cur->who))); notify(cur->owner,buf); freer(cur); return; } if(Halted((cur->who))) { sprintf(buf,"Attempt to execute command by halted object %s.", unparse_object(cur->owner,cur->who)); notify(cur->owner,buf); freer(cur); return; } if(!payfor(cur->who, TRIGGER_COST)) { sprintf(buf, "%s went bankrupt.", unparse_object(cur->owner, cur->who)); notify(cur->owner, buf); freer(cur); return; } if(!cur->command) { /* hmm.. we can't really do anything. */ freer(cur); return; } strcpy(buf, cur->command); { int x; for(x = 0; x < 10; x++) { awptr[x] = cur->awptr[x]; } printf("Executing queue:%d, trig %d: %s\n", cur->who, cur->trigger, buf); process_command(cur->who, trash_braces(pronoun_substitute(cur->trigger, buf, cur->who)), cur->trigger,1); for(x = 0; x < 10; x++) { awptr[x] = NULL; } } /* Okay, okay, finally we get to execute a command. yay. */ freer(cur); } void check_waits() { sofar = 0; wc_every_sec(); /* for @waits.. do this first, so we can do * those this time too. */ while(que && (sofar++ < MINEX)) check_a_wait(); } void queue_command(dbref who, const char *what, dbref trigger) { struct das *x; struct das *y; int z; x = malloc(sizeof(*x)); x->who = who; x->owner = OWNER(who); x->command = alloc_string(what); x->trigger = trigger; for(z = 0; z < 10; z++) x->awptr[z] = alloc_string(wptr[z]); x->next = NULL; /* this goes at the end.. ends don't have * * a next. */ if(!que) que = x; /* well.. this is the only one in the que! */ else { for(y = que; y->next; y = y->next); y->next = x; /* stick it in at the end. */ } } void trigobj(dbref who, const char *what, dbref trig) { char buffer1[BUFFER_LEN+1]; char *x; char *buffer = buffer1 + 1; int depth = 0; if(!what) return; if(!*what) return; if(!is_ok(who)) return; if(Typeof(who) != TYPE_THING && Typeof(who) != TYPE_PLAYER) return; if(trig == NOTHING) trig = global_trigger; strcpy(buffer, what); for(x = buffer; *x; x++) { if(*x == '{') depth++; if(*x == '}') depth--; if(depth < 0) depth = 0; if(*x == ';' && depth == 0) { *x = '\0'; queue_command(who, buffer, trig); what += strlen(buffer) + 1; strcpy(buffer, what); x = buffer - 1; } } if(*buffer != '\0') queue_command(who, buffer, trig); } void do_trigger(dbref player, const char *thing, const char *args) { dbref who; int d; int depth; char *arg; char *p; char *x; arg = alloc_string(args); for(d = 0; d < 10; d++) wptr[d] = NULL; if(!index(thing,'/')) { notify(player, "No match."); return; } { strcpy(buf, thing); *index(buf,'/') = NULL; who = match_controlled(player, buf); if(who == NOTHING) return; x = 1 + index(buf, '\0'); if(!get_property_class(who, x)) { notify(player,"No match."); return; } } if(!is_ok(who)) return; d = 0; depth = 0; p = arg; while(arg && *arg) { if(*arg == ',' && depth == 0 && d <= 8) { *arg = '\0'; wptr[d++] = alloc_string(trash_braces(p)); p = arg+1; } if(*arg == '{') depth++; if(*arg == '}') depth--; arg++; } wptr[d] = alloc_string(p); trigobj(who, get_property_class(who,x), player); for(d = 0; d < 10; d++) if(wptr[d]) { free(wptr[d]); wptr[d]=NULL; } }