JSValueRef js_map_object_find_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { char name[name_str_len]; obj_type *obj; if (!script_check_param_count(cx,func,argc,1,exception)) return(script_null_to_value(cx)); script_value_to_string(cx,argv[0],name,name_str_len); obj=object_find_name(name); if (obj==NULL) return(script_int_to_value(cx,-1)); return(script_int_to_value(cx,obj->idx)); }
JSBool js_event_send_message_func(JSContext *cx,JSObject *j_obj,uintN argc,jsval *argv,jsval *rval) { int msg_to,id; char name[name_str_len]; obj_type *obj; msg_to=JSVAL_TO_INT(argv[0]); id=JSVAL_TO_INT(argv[2]); *rval=JSVAL_TRUE; switch (msg_to) { case sd_message_to_player: obj=object_find_uid(server.player_obj_uid); memmove(obj->attach.get_msg_data,js.attach.set_msg_data,(sizeof(attach_msg_type)*max_msg_data)); scripts_post_event_console(&obj->attach,sd_event_message,sd_event_message_from_script,id); break; case sd_message_to_object: script_value_to_string(argv[1],name,name_str_len); obj=object_find_name(name); if (obj==NULL) { *rval=JSVAL_FALSE; break; } memmove(obj->attach.get_msg_data,js.attach.set_msg_data,(sizeof(attach_msg_type)*max_msg_data)); scripts_post_event_console(&obj->attach,sd_event_message,sd_event_message_from_script,id); break; case sd_message_to_course: memmove(js.course_attach.get_msg_data,js.attach.set_msg_data,(sizeof(attach_msg_type)*max_msg_data)); scripts_post_event_console(&js.course_attach,sd_event_message,sd_event_message_from_script,id); break; case sd_message_to_game: memmove(js.game_attach.get_msg_data,js.attach.set_msg_data,(sizeof(attach_msg_type)*max_msg_data)); scripts_post_event_console(&js.game_attach,sd_event_message,sd_event_message_from_script,id); break; } return(JS_TRUE); }
static void set_object_data(const mxArray *data) { OBJECT *obj; mxArray *pId = mxGetField(data,0,"id"); char id[256]; if (pId==NULL) output_error("set_object_data(const mxArray *data={...}) did not find a required object id field"); else if (mxGetString(pId,id,sizeof(id))) output_error("set_object_data(const mxArray *data={...}) couldn't read the object id field"); else if ((obj=object_find_name(id))==NULL) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't find object id", id); else { int i; for (i=0; i<mxGetNumberOfFields(data); i++) { const char *name; const mxArray *pField = mxGetFieldByNumber(data,0,i); char value[4096]; if ((name=mxGetFieldNameByNumber(data,i))==NULL) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the name of field %d", id, i); else if (strcmp(name,"id")==0 || strcmp(name,"class")==0) { /* these may not be changed */ } else if (pField==NULL) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the object field '%s' for object '%s'", id, name); else if (mxIsChar(pField) && mxGetString(pField,value,sizeof(value))) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the string value '%s' from field '%s'", id, value, name); else if (mxIsDouble(pField) && sprintf(value,"%lg",*(double*)mxGetPr(pField))<1) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the double value '%lg' from field '%s'", id, *(double*)mxGetPr(pField), name); else if (mxIsComplex(pField) && sprintf(value,"%lg%+lgi",*(double*)mxGetPr(pField),*(double*)mxGetPi(pField))<1) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the complex value '%lg%+lgi' from field '%s'", id, *(double*)mxGetPr(pField), *(double*)mxGetPi(pField), name); else if (mxIsUint32(pField) && sprintf(value,"%lu",*(unsigned int*)mxGetPr(pField))<1) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the uint32 value '%lu' from field '%s'", id, *(unsigned int*)mxGetPr(pField), name); else if (strcmp(value,ERROR)==0) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't use error value '%s'", id, value); else if (strcmp(value,NONE)==0 && strcpy(value,"")==NULL) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't clear empty value '%s'", id, value); else if (!object_set_value_by_name(obj,name,value)) output_error("set_object_data(const mxArray *data={id='%s',...}) couldn't read the value '%s' into property '%s'", id, value, name); } } }
JSBool js_event_send_message_to_object_by_name_func(JSContext *cx,JSObject *j_obj,uintN argc,jsval *argv,jsval *rval) { char name[name_str_len]; obj_type *obj; script_value_to_string(argv[0],name,name_str_len); obj=object_find_name(name); if (obj==NULL) { *rval=JSVAL_FALSE; return(JS_TRUE); } memmove(obj->attach.get_msg_data,js.attach.set_msg_data,(sizeof(attach_msg_type)*max_msg_data)); scripts_post_event_console(&obj->attach,sd_event_message,sd_event_message_from_script,JSVAL_TO_INT(argv[1])); *rval=JSVAL_TRUE; return(JS_TRUE); }
/** Convert to an \e object Converts a string to an \e object property. @return 1 on success, 0 on failure, -1 if conversion was incomplete **/ int convert_to_object(const char *buffer, /**< a pointer to the string buffer */ void *data, /**< a pointer to the data */ PROPERTY *prop) /**< a pointer to keywords that are supported */ { CLASSNAME cname; OBJECTNUM id; OBJECT **target = (OBJECT**)data; char oname[256]; if ( strcmp(buffer,"0")==0 ) // NOTE: this is inconsistent with what convert_from_object does for NULL object { *target = NULL; return 1; } else if (sscanf(buffer,"\"%[^\"]\"",oname)==1 || (strchr(buffer,':')==NULL && strncpy(oname,buffer,sizeof(oname)))) { oname[sizeof(oname)-1]='\0'; /* terminate unterminated string */ *target = object_find_name(oname); return (*target)!=NULL; } else if (sscanf(buffer,global_object_scan,cname,&id)==2) { OBJECT *obj = object_find_by_id(id); if(obj == NULL){ /* failure case, make noisy if desired. */ *target = NULL; return 0; } if (obj!=NULL && strcmp(obj->oclass->name,cname)==0) { *target=obj; return 1; } } else *target = NULL; return 0; }
/** Process an incoming XML data request @returns non-zero on success, 0 on failure (errno set) **/ int http_xml_request(HTTP *http,char *uri) { char arg1[1024]="", arg2[1024]=""; int nargs = sscanf(uri,"%1023[^/=\r\n]/%1023[^\r\n=]",arg1,arg2); char *value = strchr(uri,'='); char buffer[1024]=""; OBJECT *obj=NULL; char *id; /* value */ if (value) *value++; /* decode %.. */ http_decode(arg1); http_decode(arg2); if (value) http_decode(value); /* process request */ switch (nargs) { /* get global variable */ case 1: /* find the variable */ if (global_getvar(arg1,buffer,sizeof(buffer))==NULL) { output_error("global variable '%s' not found", arg1); return 0; } /* assignment, if any */ if (value) global_setvar(arg1,value); /* post the response */ http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); http_format(http,"<globalvar>\n\t<name>%s</name>\n\t<value>%s</value>\n</globalvar>\n", arg1, http_unquote(buffer)); http_type(http,"text/xml"); return 1; /* get object property */ case 2: /* find the object */ id = strchr(arg1,':'); if ( id==NULL ) obj = object_find_name(arg1); else obj = object_find_by_id(atoi(id+1)); if ( obj==NULL ) { output_error("object '%s' not found", arg1); return 0; } /* post the current value */ if ( !object_get_value_by_name(obj,arg2,buffer,sizeof(buffer)) ) { output_error("object '%s' property '%s' not found", arg1, arg2); return 0; } /* assignment, if any */ if ( value && !object_set_value_by_name(obj,arg2,value) ) { output_error("cannot set object '%s' property '%s' to '%s'", arg1, arg2, value); return 0; } /* post the response */ http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<property>\n"); http_format(http,"\t<object>%s</object>\n", arg1); http_format(http,"\t<name>%s</name>\n", arg2); http_format(http,"\t<value>%s</value>\n", http_unquote(buffer)); /* TODO add property type info */ http_format(http,"</property>\n"); http_type(http,"text/xml"); return 1; default: return 0; } return 0; }
/** Convert to a \e double_array data type Converts a string to a \e double_array data type property. @return 1 on success, 0 on failure, -1 if conversion was incomplete **/ int convert_to_double_array(const char *buffer, void *data, PROPERTY *prop) { double_array *a=(double_array*)data; a->set_name(prop->name); unsigned row=0, col=0; const char *p = buffer; /* new array */ /* parse input */ for ( p=buffer ; *p!='\0' ; ) { char value[256]; char objectname[64], propertyname[64]; while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */ if ( *p!='\0' && sscanf(p,"%s",value)==1 ) { if ( *p==';' ) /* end row */ { row++; col=0; p++; continue; } else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */ { a->grow_to(row,col); a->clr_at(row,col); col++; } else if ( isdigit(*p) || *p=='.' || *p=='-' || *p=='+' ) /* probably real value */ { a->grow_to(row+1,col+1); a->set_at(row,col,atof(p)); col++; } else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */ { OBJECT *obj = load_get_current_object(); if ( obj!=NULL && strcmp(objectname,"parent")==0 ) obj = obj->parent; else if ( strcmp(objectname,"this")!=0 ) obj = object_find_name(objectname); if ( obj==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object property '%s' not found", buffer,row,col,objectname); return 0; } PROPERTY *prop = object_get_property(obj,propertyname,NULL); if ( prop==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,object_get_double(obj,prop)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* current object/global property */ { OBJECT *obj; PROPERTY *target = NULL; obj = (OBJECT*)((char*)data - (char*)prop->addr)-1; object_name(obj,objectname,sizeof(objectname)); target = object_get_property(obj,propertyname,NULL); if ( target!=NULL ) { if ( target->ptype!=PT_double && target->ptype!=PT_random && target->ptype!=PT_enduse && target->ptype!=PT_loadshape && target->ptype!=PT_enduse ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to property '%s', which is not an underlying double", buffer,row,col,propertyname,objectname,target->name); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,object_get_double(obj,target)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else { GLOBALVAR *var = global_find(propertyname); if ( var==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname); return 0; } if ( var->prop->ptype!=PT_double ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to a global '%s', which is not an underlying double", buffer,row,col,propertyname,objectname,propertyname); return 0; } a->grow_to(row+1,col+1); a->set_at(row,col,(double*)var->prop->addr); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } } else /* not a valid entry */ { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p); return 0; } while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */ } } return 1; }
/** Convert to a \e complex_array data type Converts a string to a \e complex_array data type property. @return 1 on success, 0 on failure, -1 if conversion was incomplete **/ int convert_to_complex_array(const char *buffer, void *data, PROPERTY *prop) { complex_array *a=(complex_array*)data; unsigned row=0, col=0; const char *p = buffer; /* new array */ /* parse input */ for ( p=buffer ; *p!='\0' ; ) { char value[256]; char objectname[64], propertyname[64]; complex c; while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */ if ( *p!='\0' && sscanf(p,"%s",value)==1 ) { if ( *p==';' ) /* end row */ { row++; col=0; p++; continue; } else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */ { a->grow_to(row,col); a->clr_at(row,col); col++; } else if ( convert_to_complex(value,(void*)&c,prop) ) /* probably real value */ { a->grow_to(row,col); a->set_at(row,col,c); col++; } else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */ { OBJECT *obj = object_find_name(objectname); PROPERTY *prop; if ( obj==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object '%s' not found", buffer,row,col,objectname); return 0; } prop = object_get_property(obj,propertyname,NULL); if ( prop==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname); return 0; } a->grow_to(row,col); a->set_at(row,col,object_get_complex(obj,prop)); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* object property */ { GLOBALVAR *var = global_find(propertyname); if ( var==NULL ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname); return 0; } a->grow_to(row,col); a->set_at(row,col,(complex*)var->prop->addr); if ( a->is_nan(row,col) ) { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname); return 0; } col++; } else /* not a valid entry */ { output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p); return 0; } while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */ } } return 1; }
/* initialize modules */ int link_initall(void) { output_debug("link_initall(): link startup in progress..."); glxlink *mod; for ( mod=glxlink::get_first() ; mod!=NULL ; mod=mod->get_next() ) { LINKLIST *item; output_debug("link_initall(): setting up %s link", mod->get_target()); // set default global list (if needed) if ( mod->get_globals()==NULL ) { GLOBALVAR *var = NULL; while ( (var=global_getnext(var))!=NULL ) { if ( var->prop!=NULL && var->prop->name!=NULL ) { LINKLIST *item = mod->add_global(var->prop->name); if ( item!=NULL ) item->data = (void*)var; else output_error("link_initall(): unable to link %s", var->prop->name); } else output_warning("link_initall(): a variable property definition is null"); } } else { // link global variables for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) ) { if ( strcmp(item->name,"")==0 ) continue; item->data = (void*)global_find(item->name); if ( item->data==NULL ) output_error("link_initall(target='%s'): global '%s' is not found", mod->get_target(), item->name); } } // link objects if ( mod->get_objects()==NULL ) { // set default object list OBJECT *obj = NULL; for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) ) { // add named objects LINKLIST *item = NULL; if ( obj->name!=NULL ) item = mod->add_object(obj->name); else { char id[256]; sprintf(id,"%s:%d",obj->oclass->name,obj->id); item = mod->add_object(id); } item->data = (void*)obj; } } else { LINKLIST *item; // link global variables for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { if ( strcmp(item->name,"")==0 ) continue; OBJECT *obj = NULL; item->data = (void*)object_find_name(item->name); if ( item->data==NULL) output_error("link_initall(target='%s'): object '%s' is not found", mod->get_target(), item->name); } } // link exports for ( item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) ) { char objname[64], propname[64], varname[64]; if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 ) { OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY)); objprop->obj = object_find_name(objname); if ( objprop->obj ) { objprop->prop = class_find_property(objprop->obj->oclass,propname); if ( objprop->prop==NULL ) output_error("link_initall(target='%s'): export '%s' property not found", mod->get_target(), item->name); else { item->data = objprop; strcpy(item->name,varname); } } else output_error("link_initall(target='%s'): export '%s' object not found", mod->get_target(), item->name); } else output_error("link_initall(target='%s'): '%s' is not a valid export specification", mod->get_target(), item->name); } // link imports for ( item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) ) { char objname[64], propname[64], varname[64]; if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 ) { OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY)); objprop->obj = object_find_name(objname); if ( objprop->obj ) { objprop->prop = class_find_property(objprop->obj->oclass,propname); if ( objprop->prop==NULL ) output_error("link_initall(target='%s'): import '%s' property not found", mod->get_target(), item->name); else { item->data = objprop; strcpy(item->name,varname); } } else output_error("link_initall(target='%s'): import '%s' object not found", mod->get_target(), item->name); } else output_error("link_initall(target='%s'): '%s' is not a valid import specification", mod->get_target(), item->name); } // initialize link module if ( !mod->do_init() ) { output_error("link_initall(): link startup failed"); link_termall(); return 0; } } output_debug("link_initall(): link startup done ok"); atexit((void(*)(void))link_termall); return 1; }