diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index ee502f23..7da9e022 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -36,6 +36,7 @@ #include "amx.h" #include "natives.h" #include "debugger.h" +#include "libraries.h" extern const char *no_function; @@ -472,3 +473,133 @@ void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf) } } +void CPluginMngr::CacheAndLoadModules(const char *plugin) +{ + size_t progsize; + char *prog = ReadIntoOrFromCache(plugin, progsize); + + if (!prog) + return; + + AMX_HEADER hdr; + memcpy(&hdr, prog, sizeof(AMX_HEADER)); + + uint16_t magic = hdr.magic; + amx_Align16(&magic); + + if (magic != AMX_MAGIC) + { + return; + } + + if (hdr.file_version < MIN_FILE_VERSION || + hdr.file_version > CUR_FILE_VERSION) + { + return; + } + if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) && + (hdr.defsize != sizeof(AMX_FUNCSTUBNT))) + { + return; + } + + amx_Align32((uint32_t*)&hdr.nametable); + uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable); + amx_Align16(namelength); + if (*namelength>sNAMEMAX) + { + return; + } + + if (hdr.stp <= 0) + { + return; + } + + AMX amx; + memset(&amx, 0, sizeof(AMX)); + amx.base = (unsigned char *)prog; + + int num; + char name[sNAMEMAX+1]; + cell tag_id; + amx_NumTags(&amx, &num); + + CVector expects; + CVector defaults; + for (int i=0; icmd == LibCmd_ForceLib) + { + RunLibCommand(dc); + delete dc; + } else if ( (dc->cmd == LibCmd_ExpectClass) || + (dc->cmd == LibCmd_ExpectLib) ) + { + expects.push_back(dc); + } else if (dc->cmd == LibCmd_DefaultLib) { + defaults.push_back(dc); + } + } else { + delete dc; + } + } + } + + for (size_t i=0; i m_plcache; }; diff --git a/amxmodx/amx.cpp b/amxmodx/amx.cpp index 743cafd7..4e431212 100755 --- a/amxmodx/amx.cpp +++ b/amxmodx/amx.cpp @@ -844,19 +844,6 @@ int AMXAPI amx_Init(AMX *amx, void *program) { AMX_HEADER *hdr; BROWSEHOOK hook = NULL; - #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD - char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */ - #if defined _Windows - typedef int (FAR WINAPI *AMX_ENTRY)(AMX _FAR *amx); - HINSTANCE hlib; - #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ - typedef int (*AMX_ENTRY)(AMX *amx); - void *hlib; - #endif - int numlibraries,i; - AMX_FUNCSTUB *lib; - AMX_ENTRY libinit; - #endif if ((amx->flags & AMX_FLAG_RELOC)!=0) return AMX_ERR_INIT; /* already initialized (may not do so twice) */ @@ -866,22 +853,6 @@ int AMXAPI amx_Init(AMX *amx, void *program) * multi-byte words */ assert(check_endian()); - #if BYTE_ORDER==BIG_ENDIAN - amx_Align32((uint32_t*)&hdr->size); - amx_Align16(&hdr->magic); - amx_Align16((uint16_t*)&hdr->flags); - amx_Align16((uint16_t*)&hdr->defsize); - amx_Align32((uint32_t*)&hdr->cod); - amx_Align32((uint32_t*)&hdr->dat); - amx_Align32((uint32_t*)&hdr->hea); - amx_Align32((uint32_t*)&hdr->stp); - amx_Align32((uint32_t*)&hdr->cip); - amx_Align32((uint32_t*)&hdr->publics); - amx_Align32((uint32_t*)&hdr->natives); - amx_Align32((uint32_t*)&hdr->libraries); - amx_Align32((uint32_t*)&hdr->pubvars); - amx_Align32((uint32_t*)&hdr->tags); - #endif if (hdr->magic!=AMX_MAGIC) return AMX_ERR_FORMAT; @@ -902,13 +873,7 @@ int AMXAPI amx_Init(AMX *amx, void *program) } /* if */ if (hdr->stp<=0) return AMX_ERR_FORMAT; - #if BYTE_ORDER==BIG_ENDIAN - if ((hdr->flags & AMX_FLAG_COMPACT)==0) { - ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod); - while (code<(ucell *)((unsigned char *)program+(int)hdr->hea)) - swapcell(code++); - } /* if */ - #endif + assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size); if ((hdr->flags & AMX_FLAG_COMPACT)!=0) { #if AMX_COMPACTMARGIN > 2 @@ -935,108 +900,12 @@ int AMXAPI amx_Init(AMX *amx, void *program) amx->callback=amx_Callback; amx->data=NULL; - /* also align all addresses in the public function, public variable, - * public tag and native function tables --offsets into the name table - * (if present) must also be swapped. - */ - #if BYTE_ORDER==BIG_ENDIAN - { /* local */ - AMX_FUNCSTUB *fs; - int i,num; - - fs=GETENTRY(hdr,natives,0); - num=NUMENTRIES(hdr,natives,libraries); - for (i=0; iaddress); /* redundant, because it should be zero */ - if (USENAMETABLE(hdr)) - amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs); - fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); - } /* for */ - - fs=GETENTRY(hdr,publics,0); - assert(hdr->publics<=hdr->natives); - num=NUMENTRIES(hdr,publics,natives); - for (i=0; iaddress); - if (USENAMETABLE(hdr)) - amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs); - fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); - } /* for */ - - fs=GETENTRY(hdr,pubvars,0); - assert(hdr->pubvars<=hdr->tags); - num=NUMENTRIES(hdr,pubvars,tags); - for (i=0; iaddress); - if (USENAMETABLE(hdr)) - amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs); - fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); - } /* for */ - - fs=GETENTRY(hdr,tags,0); - if (hdr->file_version<7) { - assert(hdr->tags<=hdr->cod); - num=NUMENTRIES(hdr,tags,cod); - } else { - assert(hdr->tags<=hdr->nametable); - num=NUMENTRIES(hdr,tags,nametable); - } /* if */ - for (i=0; iaddress); - if (USENAMETABLE(hdr)) - amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs); - fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); - } /* for */ - } /* local */ - #endif - /* relocate call and jump instructions */ hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK]; if (hook) hook(amx, NULL, NULL); amx_BrowseRelocate(amx); - /* load any extension modules that the AMX refers to */ - #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD - hdr=(AMX_HEADER *)amx->base; - numlibraries=NUMENTRIES(hdr,libraries,pubvars); - for (i=0; iaddress=(ucell)hlib; - } /* for */ - #endif - return AMX_ERR_NONE; } diff --git a/amxmodx/amxxfile.cpp b/amxmodx/amxxfile.cpp index f3dbd41c..fe0a4a6e 100755 --- a/amxmodx/amxxfile.cpp +++ b/amxmodx/amxxfile.cpp @@ -109,7 +109,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize) { DATAREAD(&m_Bh.version, sizeof(int16_t), 1); - if (m_Bh.version != MAGIC_VERSION) + if (m_Bh.version > MAGIC_VERSION) { m_Status = Err_OldFile; fclose(m_pFile); diff --git a/amxmodx/libraries.cpp b/amxmodx/libraries.cpp index 214d19cd..fc6047b2 100644 --- a/amxmodx/libraries.cpp +++ b/amxmodx/libraries.cpp @@ -20,62 +20,62 @@ bool AddLibrary(const char *name, LibType type, LibSource src, void *parent) return true; } -bool DecodeLibCmdString(const char *str, LibDecoder &dec) +bool DecodeLibCmdString(const char *str, LibDecoder *dec) { - if (str[0] != '_') + if (dec->buffer) { - dec.cmd = LibCmd_ReqLib; - dec.buffer = strdup(str); - if (strcmp(str, "dbi") == 0) - dec.cmd = LibCmd_ReqClass; - dec.param1 = dec.buffer; - dec.param2 = NULL; + free(dec->buffer); + dec->buffer = NULL; + } + if (str[0] != '?') + { + return false; } else { str++; if (*str == 'r') { str++; if (*str == 'c') - dec.cmd = LibCmd_ReqClass; + dec->cmd = LibCmd_ReqClass; else if (*str == 'l') - dec.cmd = LibCmd_ReqLib; + dec->cmd = LibCmd_ReqLib; else return false; str++; } else if (*str == 'f') { str++; - dec.cmd = LibCmd_ForceLib; + dec->cmd = LibCmd_ForceLib; } else if (*str == 'e') { str++; if (*str == 'c') - dec.cmd = LibCmd_ExpectClass; + dec->cmd = LibCmd_ExpectClass; else if (*str == 'l') - dec.cmd = LibCmd_ExpectLib; + dec->cmd = LibCmd_ExpectLib; else return false; str++; } else if (*str == 'd') { str++; - dec.cmd = LibCmd_DefaultLib; + dec->cmd = LibCmd_DefaultLib; } if (*str != '_') return false; str++; - if (dec.cmd < LibCmd_ExpectLib) + if (dec->cmd < LibCmd_ExpectLib) { - dec.buffer = strdup(str); - dec.param1 = dec.buffer; - dec.param2 = NULL; + dec->buffer = strdup(str); + dec->param1 = dec->buffer; + dec->param2 = NULL; } else { - dec.buffer = strdup(str); - char *p = const_cast(strchr(str, '_')); + dec->buffer = strdup(str); + char *p = strchr(str, '_'); while (p && (*(p+1) != '_')) - p = const_cast(strchr(str, '_')); + p = strchr(str, '_'); if (!p || !*(p+1)) return false; *p = '\0'; - dec.param1 = dec.buffer; - dec.param2 = p+1; + dec->param1 = dec->buffer; + dec->param2 = p+1; } } diff --git a/amxmodx/libraries.h b/amxmodx/libraries.h index 3a696550..df89ad4b 100644 --- a/amxmodx/libraries.h +++ b/amxmodx/libraries.h @@ -58,7 +58,7 @@ struct LibDecoder }; bool AddLibrary(const char *name, LibType type, LibSource src, void *parent=NULL); -bool DecodeLibCmdString(const char *str, LibDecoder &cmd); +bool DecodeLibCmdString(const char *str, LibDecoder *cmd); size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent=NULL); size_t ClearLibraries(LibSource src); LibError RunLibCommand(const LibDecoder *enc); diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index 96f440a1..1d468d41 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -262,6 +262,7 @@ int C_Spawn(edict_t *pent) // ###### Load modules loadModules(get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini"), PT_ANYTIME); + g_plugins.CALMFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini")); int loaded = countModules(CountModules_Running); // Call after attachModules so all modules don't have pending stat // Set some info about amx version and modules diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index e1a90f87..c367dd11 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -430,9 +430,12 @@ int CheckModules(AMX *amx, char error[128]) { int numLibraries = amx_GetLibraries(amx); char buffer[64]; + LibType expect; + bool found; Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER]; + /** decode old style plugins */ for (int i = 0; i < numLibraries; i++) { amx_GetLibrary(amx, i, buffer, sizeof(buffer) - 1); @@ -440,41 +443,18 @@ int CheckModules(AMX *amx, char error[128]) if (stricmp(buffer, "float") == 0) continue; - LibDecoder dcd; - LibType expect; - bool found = false; - const char *search = NULL; - - DecodeLibCmdString(buffer, dcd); - - switch (dcd.cmd) + if (stricmp(buffer, "dbi") == 0) { - case LibCmd_ReqLib: - search = dcd.param1; - expect = LibType_Library; - break; - case LibCmd_ExpectLib: - search = dcd.param2; - expect = LibType_Library; - break; - case LibCmd_ReqClass: - search = dcd.param1; expect = LibType_Class; - break; - case LibCmd_ExpectClass: - search = dcd.param2; - expect = LibType_Class; - break; + } else { + expect = LibType_Library; } - if (!search) - continue; - - found = FindLibrary(search, expect); + found = FindLibrary(buffer, expect); if (!found) { - if (pHandler->HandleModule(search)) + if (pHandler->HandleModule(buffer)) found = true; } @@ -483,11 +463,41 @@ int CheckModules(AMX *amx, char error[128]) const char *type = "Module/Library"; if (expect == LibType_Class) type = "Module/Library Class"; - sprintf(error, "%s \"%s\" required for plugin. Check modules.ini.", type, search); + sprintf(error, "%s \"%s\" required for plugin. Check modules.ini.", type, buffer); return 0; } } + /** decode new style plugins */ + amx_NumTags(amx, &numLibraries); + cell notused; + LibDecoder dec; + LibError err; + for (int i=0; iHandleModule(buffer)) + { + const char *type = "Module/Library"; + if (err == LibErr_NoClass) + type = "Module/Library Class"; + sprintf(error, "%s \"%s\" required for plugin. Check modules.ini.", type, buffer); + return 0; + } + } + } + } + } + + return 1; } diff --git a/amxmodx/srvcmd.cpp b/amxmodx/srvcmd.cpp index 1265fa82..3c3f06c9 100755 --- a/amxmodx/srvcmd.cpp +++ b/amxmodx/srvcmd.cpp @@ -39,7 +39,7 @@ void amx_command() { print_srvconsole("Currently loaded plugins:\n"); - print_srvconsole(" %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status"); + print_srvconsole(" %-23.22s %-8.7s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status"); int plugins = 0; int running = 0; @@ -52,7 +52,7 @@ void amx_command() if ((*a).isValid() && !(*a).isPaused()) ++running; - print_srvconsole(" [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus()); + print_srvconsole(" [%3d] %-23.22s %-8.7s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus()); ++a; }