diff --git a/amxmodx/CLang.cpp b/amxmodx/CLang.cpp index 6da0cb54..3c31176f 100755 --- a/amxmodx/CLang.cpp +++ b/amxmodx/CLang.cpp @@ -47,6 +47,15 @@ #define FFHL_VERSION 4 #define FFHL_MIN_VERSION 4 +#define NEXT_PARAM() \ + if (parm > paramCount) \ + { \ + strcpy(outbuf, ""); \ + len = 0; \ + AMXXLOG_Log("[AMXX] Plugin did not format a string correctly (parameter %d (total %d), line %d, \"%s\")", parm, paramCount, amx->curline, g_plugins.findPluginFast(amx)); \ + return outbuf; \ + } + /*version history: * 1 (BAILOPAN) - Simplest form possible, no reverse * 2 (BAILOPAN) - One language per file with full reverse @@ -627,8 +636,9 @@ const char *CLangMngr::Format(const char *src, ...) char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) { - cell *src = get_amxaddr(amx, params[parm++]); + int paramCount = *params / sizeof(cell); static char outbuf[4096]; + cell *src = get_amxaddr(amx, params[parm++]); char *outptr = outbuf; enum State { @@ -646,6 +656,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) if (*src=='L') { cell langName = params[parm]; // "en" case (langName contains the address to the string) + NEXT_PARAM(); cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases const char *cpLangName=NULL; // Handle player ids (1-32) and server language @@ -673,6 +684,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) if (!cpLangName || strlen(cpLangName) < 1) cpLangName = "en"; int len = 0; + NEXT_PARAM(); char *key = get_amxstring(amx, params[parm++], 1, len); const char *def = GetDef(cpLangName, key); if (def == NULL) @@ -709,6 +721,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) { char tmpString[256]; char *tmpPtr = tmpString; + NEXT_PARAM(); cell *tmpCell = get_amxaddr(amx, params[parm++]); while (*tmpCell) *tmpPtr++ = *tmpCell++; @@ -719,15 +732,23 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) case 'g': case 'f': { + NEXT_PARAM(); sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++])); break; } case 'i': case 'd': { + NEXT_PARAM(); sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++])); break; } + default: + { + *outptr++ = '%'; + *outptr++ = *(ptr-1); + break; + } } outptr += strlen(outptr); } @@ -764,33 +785,49 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) char format[16]; format[0] = '%'; char *ptr = format+1; - while (!isalpha(*ptr++ = *src++)) - /*nothing*/; - --src; - *ptr = 0; - switch ( *(ptr-1) ) + if (*src != '%') { - case 's': + while (!isalpha(*ptr++ = *src++)) + /*nothing*/; + --src; + *ptr = 0; + switch ( *(ptr-1) ) { - cell *tmpCell = get_amxaddr(amx, params[parm++]); - while (*tmpCell) - *tmpPtr++ = *tmpCell++; - *tmpPtr = 0; - sprintf(outptr, format, tmpString); - break; - } - case 'g': - case 'f': - { - sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++])); - break; - } - case 'i': - case 'd': - { - sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++])); - break; + case 's': + { + NEXT_PARAM(); + cell *tmpCell = get_amxaddr(amx, params[parm++]); + while (*tmpCell) + *tmpPtr++ = *tmpCell++; + *tmpPtr = 0; + sprintf(outptr, format, tmpString); + break; + } + case 'g': + case 'f': + { + NEXT_PARAM(); + sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++])); + break; + } + case 'i': + case 'd': + { + NEXT_PARAM(); + sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++])); + break; + } + default: + { + *outptr++ = '%'; + *outptr++ = *(ptr-1); + break; + } } + } else { + *outptr++ = '%'; + *outptr++ = '%'; + src++; } outptr += strlen(outptr); } diff --git a/amxmodx/amxxfile.cpp b/amxmodx/amxxfile.cpp index 8053fb12..5db57cfa 100755 --- a/amxmodx/amxxfile.cpp +++ b/amxmodx/amxxfile.cpp @@ -124,45 +124,52 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize) m_pFile = NULL; return; } - } - - // try to find the section - mint8_t numOfPlugins; - DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1); - - TableEntry entry; - - m_SectionHdrOffset = 0; - int i = 0; - for (i = 0; i < static_cast(numOfPlugins); ++i) - { - DATAREAD(&entry, sizeof(entry), 1); - if (entry.cellSize == m_CellSize) - { - m_SectionHdrOffset = ftell(m_pFile) - sizeof(entry); - break; - } - } - if (!m_SectionHdrOffset) - { - m_Status = Err_SectionNotFound; + } else if ( magic == 0x524C4542 ) { + //we have an invalid, old, RLEB file + m_Status = Err_OldFile; fclose(m_pFile); m_pFile = NULL; return; - } + } else { - // compute section length - if ((i+1) < static_cast(numOfPlugins)) - { - // there is a next section - TableEntry nextEntry; - DATAREAD(&nextEntry, sizeof(nextEntry), 1); - m_SectionLength = nextEntry.offset - entry.offset; - } - else - { - fseek(m_pFile, 0, SEEK_END); - m_SectionLength = ftell(m_pFile) - (long)entry.offset; + // try to find the section + mint8_t numOfPlugins; + DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1); + + TableEntry entry; + + m_SectionHdrOffset = 0; + int i = 0; + for (i = 0; i < static_cast(numOfPlugins); ++i) + { + DATAREAD(&entry, sizeof(entry), 1); + if (entry.cellSize == m_CellSize) + { + m_SectionHdrOffset = ftell(m_pFile) - sizeof(entry); + break; + } + } + if (!m_SectionHdrOffset) + { + m_Status = Err_SectionNotFound; + fclose(m_pFile); + m_pFile = NULL; + return; + } + + // compute section length + if ((i+1) < static_cast(numOfPlugins)) + { + // there is a next section + TableEntry nextEntry; + DATAREAD(&nextEntry, sizeof(nextEntry), 1); + m_SectionLength = nextEntry.offset - entry.offset; + } + else + { + fseek(m_pFile, 0, SEEK_END); + m_SectionLength = ftell(m_pFile) - (long)entry.offset; + } } } diff --git a/amxmodx/amxxfile.h b/amxmodx/amxxfile.h index b454f1c7..442fc22c 100755 --- a/amxmodx/amxxfile.h +++ b/amxmodx/amxxfile.h @@ -44,7 +44,8 @@ public: Err_FileInvalid, Err_SectionNotFound, Err_DecompressorInit, - Err_Decompress + Err_Decompress, + Err_OldFile, }; private: diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index e7ed7d52..20103ae5 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -132,6 +132,8 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 case CAmxxReader::Err_Decompress: strcpy(error, "Internal error: Decompress"); return (amx->error = AMX_ERR_NOTFOUND); + case CAmxxReader::Err_OldFile: + strcpy(error, "Plugin uses deprecated format. Update compiler"); default: strcpy(error, "Unknown error"); return (amx->error = AMX_ERR_NOTFOUND); @@ -894,6 +896,7 @@ void *Module_ReqFnptr(const char *funcName) REGISTER_FUNC("amx_Execv", amx_Execv) REGISTER_FUNC("amx_Allot", amx_Allot) REGISTER_FUNC("amx_FindPublic", amx_FindPublic) + REGISTER_FUNC("amx_FindNative", amx_FindNative) // Natives / Forwards REGISTER_FUNC("AddNatives", MNF_AddNatives) diff --git a/amxmodx/msvc/amxmodx.vcproj b/amxmodx/msvc/amxmodx.vcproj index 30e69af3..c159557a 100755 --- a/amxmodx/msvc/amxmodx.vcproj +++ b/amxmodx/msvc/amxmodx.vcproj @@ -42,7 +42,7 @@