/* 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; }
}