sendmap with map config files, script contexts (~sandbox)

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1471 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
driAn
2007-12-22 23:39:30 +00:00
parent c3a95a3879
commit 7fa0a75765
12 changed files with 202 additions and 93 deletions
+111 -66
View File
@@ -6,6 +6,8 @@
void itoa(char *s, int i) { s_sprintf(s)("%d", i); }
char *exchangestr(char *o, char *n) { delete[] o; return newstring(n); }
int execcontext = IEXC_CORE;
hashtable<char *, ident> *idents = NULL; // contains ALL vars/commands/aliases
bool persistidents = true;
@@ -16,7 +18,7 @@ void alias(char *name, char *action)
if(!b)
{
name = newstring(name);
ident b = { ID_ALIAS, name, 0, 0, 0, 0, 0, newstring(action), 0, persistidents };
ident b = { ID_ALIAS, name, 0, 0, 0, 0, 0, newstring(action), 0, persistidents, execcontext };
idents->access(name, &b);
}
else if(b->type==ID_ALIAS)
@@ -35,7 +37,7 @@ COMMAND(alias, ARG_2STR);
int variable(char *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist)
{
if(!idents) idents = new hashtable<char *, ident>;
ident v = { ID_VAR, name, min, max, storage, fun, 0, 0, 0, persist };
ident v = { ID_VAR, name, min, max, storage, fun, 0, 0, 0, persist, IEXC_CORE };
idents->access(name, &v);
return cur;
}
@@ -53,7 +55,7 @@ char *getalias(char *name)
bool addcommand(char *name, void (*fun)(), int narg)
{
if(!idents) idents = new hashtable<char *, ident>;
ident c = { ID_COMMAND, name, 0, 0, 0, fun, narg, 0, 0, false };
ident c = { ID_COMMAND, name, 0, 0, 0, fun, narg, 0, 0, false, IEXC_CORE };
idents->access(name, &c);
return false;
}
@@ -142,75 +144,84 @@ int execute(char *p) // all evaluation happens here,
val = ATOI(c);
if(!val && *c!='0') conoutf("unknown command: %s", c);
}
else switch(id->type)
else
{
case ID_COMMAND: // game defined commands
switch(id->narg) // use very ad-hoc function signature, and just call it
{
case ARG_1INT: ((void (__cdecl *)(int))id->fun)(ATOI(w[1])); break;
case ARG_2INT: ((void (__cdecl *)(int, int))id->fun)(ATOI(w[1]), ATOI(w[2])); break;
case ARG_3INT: ((void (__cdecl *)(int, int, int))id->fun)(ATOI(w[1]), ATOI(w[2]), ATOI(w[3])); break;
case ARG_4INT: ((void (__cdecl *)(int, int, int, int))id->fun)(ATOI(w[1]), ATOI(w[2]), ATOI(w[3]), ATOI(w[4])); break;
case ARG_NONE: ((void (__cdecl *)())id->fun)(); break;
case ARG_1STR: ((void (__cdecl *)(char *))id->fun)(w[1]); break;
case ARG_2STR: ((void (__cdecl *)(char *, char *))id->fun)(w[1], w[2]); break;
case ARG_3STR: ((void (__cdecl *)(char *, char *, char*))id->fun)(w[1], w[2], w[3]); break;
case ARG_4STR: ((void (__cdecl *)(char *, char *, char*, char*))id->fun)(w[1], w[2], w[3], w[4]); break;
case ARG_5STR: ((void (__cdecl *)(char *, char *, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5]); break;
case ARG_6STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6]); break;
case ARG_7STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6], w[7]); break;
case ARG_8STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6], w[7], w[8]); break;
case ARG_DOWN: ((void (__cdecl *)(bool))id->fun)(addreleaseaction(id->name)!=NULL); break;
case ARG_1EXP: val = ((int (__cdecl *)(int))id->fun)(execute(w[1])); break;
case ARG_2EXP: val = ((int (__cdecl *)(int, int))id->fun)(execute(w[1]), execute(w[2])); break;
case ARG_1EST: val = ((int (__cdecl *)(char *))id->fun)(w[1]); break;
case ARG_2EST: val = ((int (__cdecl *)(char *, char *))id->fun)(w[1], w[2]); break;
case ARG_VARI:
{
int len = max(numargs-2, 0);
for(int i = 1; i<numargs; i++) len += (int)strlen(w[i]);
char *r = newstring("", len);
for(int i = 1; i<numargs; i++)
if(execcontext > id->context)
{
conoutf("not allowed in this execution context: %s", id->name);
continue;
}
switch(id->type)
{
case ID_COMMAND: // game defined commands
switch(id->narg) // use very ad-hoc function signature, and just call it
{
case ARG_1INT: ((void (__cdecl *)(int))id->fun)(ATOI(w[1])); break;
case ARG_2INT: ((void (__cdecl *)(int, int))id->fun)(ATOI(w[1]), ATOI(w[2])); break;
case ARG_3INT: ((void (__cdecl *)(int, int, int))id->fun)(ATOI(w[1]), ATOI(w[2]), ATOI(w[3])); break;
case ARG_4INT: ((void (__cdecl *)(int, int, int, int))id->fun)(ATOI(w[1]), ATOI(w[2]), ATOI(w[3]), ATOI(w[4])); break;
case ARG_NONE: ((void (__cdecl *)())id->fun)(); break;
case ARG_1STR: ((void (__cdecl *)(char *))id->fun)(w[1]); break;
case ARG_2STR: ((void (__cdecl *)(char *, char *))id->fun)(w[1], w[2]); break;
case ARG_3STR: ((void (__cdecl *)(char *, char *, char*))id->fun)(w[1], w[2], w[3]); break;
case ARG_4STR: ((void (__cdecl *)(char *, char *, char*, char*))id->fun)(w[1], w[2], w[3], w[4]); break;
case ARG_5STR: ((void (__cdecl *)(char *, char *, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5]); break;
case ARG_6STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6]); break;
case ARG_7STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6], w[7]); break;
case ARG_8STR: ((void (__cdecl *)(char *, char *, char*, char*, char*, char*, char*, char*))id->fun)(w[1], w[2], w[3], w[4], w[5], w[6], w[7], w[8]); break;
case ARG_DOWN: ((void (__cdecl *)(bool))id->fun)(addreleaseaction(id->name)!=NULL); break;
case ARG_1EXP: val = ((int (__cdecl *)(int))id->fun)(execute(w[1])); break;
case ARG_2EXP: val = ((int (__cdecl *)(int, int))id->fun)(execute(w[1]), execute(w[2])); break;
case ARG_1EST: val = ((int (__cdecl *)(char *))id->fun)(w[1]); break;
case ARG_2EST: val = ((int (__cdecl *)(char *, char *))id->fun)(w[1], w[2]); break;
case ARG_VARI:
{
strcat(r, w[i]); // make string-list out of all arguments
if(i==numargs-1) break;
strcat(r, " ");
int len = max(numargs-2, 0);
for(int i = 1; i<numargs; i++) len += (int)strlen(w[i]);
char *r = newstring("", len);
for(int i = 1; i<numargs; i++)
{
strcat(r, w[i]); // make string-list out of all arguments
if(i==numargs-1) break;
strcat(r, " ");
}
((void (__cdecl *)(char *))id->fun)(r);
delete[] r;
break;
}
((void (__cdecl *)(char *))id->fun)(r);
delete[] r;
break;
}
}
break;
case ID_VAR: // game defined variables
if(!w[1][0]) conoutf("%s = %d", c, *id->storage); // var with no value just prints its current value
else if(id->min>id->max) conoutf("variable %s is read-only", id->name);
else
{
int i1 = ATOI(w[1]);
if(i1<id->min || i1>id->max)
break;
case ID_VAR: // game defined variables
if(!w[1][0]) conoutf("%s = %d", c, *id->storage); // var with no value just prints its current value
else if(id->min>id->max) conoutf("variable %s is read-only", id->name);
else
{
i1 = i1<id->min ? id->min : id->max; // clamp to valid range
conoutf("valid range for %s is %d..%d", id->name, id->min, id->max);
int i1 = ATOI(w[1]);
if(i1<id->min || i1>id->max)
{
i1 = i1<id->min ? id->min : id->max; // clamp to valid range
conoutf("valid range for %s is %d..%d", id->name, id->min, id->max);
}
*id->storage = i1;
if(id->fun) ((void (__cdecl *)())id->fun)(); // call trigger function if available
}
*id->storage = i1;
if(id->fun) ((void (__cdecl *)())id->fun)(); // call trigger function if available
}
break;
case ID_ALIAS: // alias, also used as functions and (global) variables
for(int i = 1; i<numargs; i++)
{
s_sprintfd(t)("arg%d", i); // set any arguments as (global) arg values so functions can access them
alias(t, w[i]);
}
char *wasexecuting = id->executing;
id->executing = id->action;
val = execute(id->action);
if(id->executing!=id->action && id->executing!=wasexecuting) delete[] id->executing;
id->executing = wasexecuting;
break;
break;
case ID_ALIAS: // alias, also used as functions and (global) variables
for(int i = 1; i<numargs; i++)
{
s_sprintfd(t)("arg%d", i); // set any arguments as (global) arg values so functions can access them
alias(t, w[i]);
}
char *wasexecuting = id->executing;
id->executing = id->action;
val = execute(id->action);
if(id->executing!=id->action && id->executing!=wasexecuting) delete[] id->executing;
id->executing = wasexecuting;
break;
}
}
loopj(numargs) delete[] w[j];
}
@@ -358,3 +369,37 @@ void identnames(vector<char *> &names, bool builtinonly)
{
enumerateht(*idents) if(!builtinonly || idents->enumc->data.type != ID_ALIAS) names.add(idents->enumc->key);
}
void changescriptcontext(int newcontext)
{
if(newcontext < execcontext) // clean up aliases created in the old context
{
enumerateht(*idents)
{
ident *id = &idents->enumc->data;
if(id->type == ID_ALIAS && id->context > newcontext)
{
idents->remove(idents->enumc->key);
i--;
}
}
}
execcontext = newcontext;
}
bool contextsealed = false;
void scriptcontext(char *context, char *idname)
{
if(contextsealed) return;
ident *id = idents->access(idname);
if(!id) return;
int c = atoi(context);
if(c >= 0 && c < IEXC_NUM) id->context = c;
}
void sealcontexts() { contextsealed = true; }
COMMAND(scriptcontext, ARG_2STR);
COMMAND(sealcontexts, ARG_NONE);