/* v1.1 * * scm.c: Shield Class Module interface routines. * * This program is free software and may be freely redistributed as * specified in the GNU General Public License. Please see the file * 'COPYING' for details. */ #include #include "spaceconf.h" #ifdef ENABLE_SHIELD_CLASSES #include "pseint.h" #include "dbint.h" #include "space.h" #include "output.h" /* Include the core shield class definitions for the plugin interface */ #include "scm/scm.h" /* Include the interface structure definitions * * extern SCM_INTERFACE scm_module1name; * extern SCM_INTERFACE scm_module2name; etc * * This file is automatically generated during the build process. */ #include "scmlib.h" /* Include the index of plugins. * * static scm_plugins[] = { * &scm_module1name, * &scm_module2name, etc * NULL }; * * This file is automatically generated during the build process. */ #include "scm.def" /* Contains the names of all the registered modules */ static char szRegisteredModuleList[MAX_ATTRIBUTE_LEN]; /* scmInitModules * * This function iterates through the list of compiled in modules, and calls * the registration function for each. Modules which claim to initialise * correctly are added to the list of registered modules. */ void scmInitModules() { int i, l; szRegisteredModuleList[0] = '\0'; for (i = l = 0; scm_plugins[i] != NULL; i++) { if ((scm_plugins[i]->scmInitModule != NULL) && (scm_plugins[i]->scmInitModule() != 0)) { if (l + strlen(scm_plugins[i]->scmName) < MAX_ATTRIBUTE_LEN-1) { strcpy(&szRegisteredModuleList[l], scm_plugins[i]->scmName); scm_plugins[i]->scmNameLen = strlen(scm_plugins[i]->scmName); l = l + strlen(scm_plugins[i]->scmName); szRegisteredModuleList[l++] = ' '; } } } /* Remove the trailing space from correctly registered modules */ if (l != 0) szRegisteredModuleList[--l] = '\0'; } /* scmListRegisteredModules * * This function returns the list of modules which were registered correctly * when the server was started. These are the only modules which will be * correctly recognized when objects define their shields. */ const char *scmListRegisteredModules() { return szRegisteredModuleList; } /* scmLoadData * * This function is called to initialise each layer of shielding for new * ship objects. It is passed the dbref to the object which defines the * ship, and the contents of it's SHIELDARRAY_LAYER attribute. * * The SHIELDARRAY_LAYER contents are checked against the list of * registered shield modules, and if a match is found, the appropriate * loading routine is called. */ int scmLoadData(dbref db, SCDATA *data, const char *szModule) { int i, len; const char *szData; /* Strip leading spaces - not that there should be any... */ for (; *szModule == ' '; szModule++) ; /* Calculate the length of the string */ for (len = 0, szData=szModule; *szData && *szData != ' '; szData++, len++) ; /* Skip any spaces before the data parameter */ for (; *szData == ' '; szData++) ; /* Look for a match. Should probably make this a hash table at some * point - but it may not be worth it as the number of plugins is never * likely to be very high. */ for (i = 0; scm_plugins[i] != NULL; i++) { if ((len == scm_plugins[i]->scmNameLen) && (strncasecmp(scm_plugins[i]->scmName, szModule, len) == 0)) { data->plugin = scm_plugins[i]; return data->plugin->scmLoadLayer(db, data, szData); } } return 0; } /* scmSaveData * * This function is called to save out each layer of shielding for * ship objects. It is passed the dbref to the object which defines the * ship, and the SCDATA for that layer. */ int scmSaveData(dbref db, SCDATA *data) { SSTR *ps; SSTR *qs; ps = sstr_new(MAX_ATTRIBUTE_LEN); qs = sstr_new(MAX_ATTRIBUTE_LEN); if (data == NULL) { log_space("Stuffed 0 #%d", db); return 0; } /* Put the plugin identifier first */ sstr_sprintf(ps, "%s ", data->plugin->scmName); /* Append the layer data */ data->plugin->scmSaveLayer(ps, data); sstr_sprintf(qs, "%s%d", SHIELDARRAY_LAYER, data->attrib); setAttrByName(db, sstr_str(qs), sstr_str(ps)); log_space("SCM: Save: #%d: %s/%s", db, sstr_str(qs), sstr_str(ps)); sstr_free(ps); sstr_free(qs); return 1; } /* scmParseData * * This function is called from the LoadLayer functions of the scm * modules. It parses up the standard format for the data strings * into: * * * * Module release is an integer * Area name is a single word/name (only alphanumerics allowed. No spaces) * Other parameters are in whatever form the plugin was wanting them. * They can also be blank, in which case this routine returns a pointer * to the end-of-string marker. */ const char *scmParseData(const char *data, int *rel, SCAREAS **area) { const char *p; const char *q; /* Skip any leading white space */ for (p = data; *p == ' ';p++) ; q = p; /* Jump over digits */ for (; isdigit(*p) || *p; p++) ; /* If p isn't a space, then the string isn't in standard format, * so set release to zero, area definition to null, and return * a pointer to the start of the data buffer we were given. */ if (*p != ' ') { *rel = 0; *area = NULL; return data; } /* Convert the release number */ *rel = atoi(q); /* Skip any white space */ for (; *p || *p == ' '; p++) ; /* If we got to the end of the string, it's not standard form. * Take the same action as before. */ if (*p == '\0') { *rel = 0; *area = NULL; return data; } q = p; /* Jump over alpha-numerics */ for (; isalpha(*p) || *p; p++) ; /* FIX ME - lookup string starting at q in the areas list */ *area = NULL; /* Skip any white space */ for (; *p || *p == ' '; p++) ; /* Return the pointer */ return p; } #endif