diff --git a/amxmodx/CCmd.h b/amxmodx/CCmd.h index 11002e69..5dbe3e7f 100755 --- a/amxmodx/CCmd.h +++ b/amxmodx/CCmd.h @@ -52,10 +52,10 @@ public: friend class CmdMngr; CPluginMngr::CPlugin* plugin; CmdMngr* parent; - CString command; - CString argument; - CString commandline; - CString info; + String command; + String argument; + String commandline; + String info; bool listable; int function; int flags; @@ -100,7 +100,7 @@ private: CmdLink* clcmdlist; struct CmdPrefix { - CString name; + String name; CmdMngr* parent; CmdLink* list; CmdPrefix* next; diff --git a/amxmodx/CEvent.h b/amxmodx/CEvent.h index 44469536..0a3f8ba0 100755 --- a/amxmodx/CEvent.h +++ b/amxmodx/CEvent.h @@ -88,7 +88,7 @@ public: { int paramId; // the message parameter id - CString sValue; // value (string) + String sValue; // value (string) float fValue; // value (float) int iValue; // value (int) int type; // type (can be int, float, string) diff --git a/amxmodx/CFile.cpp b/amxmodx/CFile.cpp index ffd969c7..43312775 100755 --- a/amxmodx/CFile.cpp +++ b/amxmodx/CFile.cpp @@ -52,7 +52,7 @@ File::operator bool ( ) const return fp && !feof(fp); } -File& operator<<( File& f, const CString& n ) +File& operator<<( File& f, const String& n ) { if ( f ) fputs( n.c_str() , f.fp ) ; return f; @@ -77,7 +77,7 @@ File& operator<<( File& f, const char& c ) return f; } -File& operator>>( File& f, CString& n ) +File& operator>>( File& f, String& n ) { if ( !f ) return f; char temp[1024]; diff --git a/amxmodx/CFile.h b/amxmodx/CFile.h index b7a83cb6..5a0f1123 100755 --- a/amxmodx/CFile.h +++ b/amxmodx/CFile.h @@ -30,7 +30,7 @@ */ #include -#include "CString.h" +#include "String.h" // ***************************************************** // class File @@ -44,11 +44,11 @@ public: File( const char* n, const char* m ); ~File( ); operator bool ( ) const; - friend File& operator<<( File& f, const CString& n ); + friend File& operator<<( File& f, const String& n ); friend File& operator<<( File& f, const char* n ); friend File& operator<<( File& f, const char& c ); friend File& operator<<( File& f, int n ); - friend File& operator>>( File& f, CString& n ); + friend File& operator>>( File& f, String& n ); friend File& operator>>( File& f, char* n ); int getline( char* buf, int sz ); File& skipWs( ); diff --git a/amxmodx/CLang.cpp b/amxmodx/CLang.cpp index 89d061b5..6dab96b0 100755 --- a/amxmodx/CLang.cpp +++ b/amxmodx/CLang.cpp @@ -29,10 +29,10 @@ * version. */ +#include #include "amxmodx.h" #include "CLang.h" - #define LITIDX_NONE 0 #define LITIDX_BRACKET 1 #define LITIDX_DEFINITION 2 @@ -42,43 +42,45 @@ #define INSERT_STRING 3 #define INSERT_NEWLINE 4 -// dictionary format is Fast-Format-Hash-Lookup, v3 +void qdbg(const char *s, ...) +{ + va_list argptr; + FILE *dbg = fopen("c:\\beta.txt", "at"); + va_start(argptr, s); + char buf[2048]; + vsprintf(buf, s, argptr); + va_end(argptr); + fprintf(dbg, "%s", buf); + fclose(dbg); +} + +// dictionary format is Fast-Format-Hash-Lookup, v4 #define MAGIC_HDR 0x4646484C +#define FFHL_VERSION 4 /* - FORMAT: - Magic (4 bytes) - Number of languages (4 bytes) - LANGUAGE INFO TABLE - For every language: - Language Name (2 bytes) - Absolut offset (4 bytes) - LANGUAGES - For every language: - Number of entries (4 bytes) - - Offset to Definition Table (4 bytes) - Length of Definition Table (4 bytes) - - Offset to Reverse Lookup Table (4 bytes) - Size of Reverse Lookup Table (4 bytes) - - - LOOK UP TABLE - For every entry: - Key hash (4 bytes) - Definition hash (4 bytes) - Definition offset (4 bytes) (into the Def table) - Key offset (4 bytes) (into the Rev table) - DEFINITION TABLE - For every entry: - Definition length (2 bytes) - Definition (variable size) - REVERSE LOOKUP TABLE - For every entry: - Key length (1 byte) - Key (variable size) -*/ +FORMAT: +Magic 4bytes +Version 1byte +Number of Languages 4bytes +LANG INFO TABLE[] + Language Name 2bytes + Offset 4bytes +KEY TABLE[] + Key Hash 4bytes + Key Lookup Offset 4bytes +LANGUAGES TABLE[] + Language[] + Key Hash # 4bytes (virtual # in hash table, 0 indexed) + Def Hash 4bytes + Def Offset 4bytes +KEY LOOKUP TABLE[] + Key length 1byte + Key string variable +DEF LOOKUP TABLE[] + Def length 2bytes + Def string variable + */ /******** CRC & Strip *********/ const uint32_t CRCTable[256] = { @@ -136,6 +138,15 @@ uint32_t CLangMngr::CLang::MakeHash(const char *src, bool makeLower) return ~crc; } +uint32_t CLangMngr::MakeHash(const char *src, bool makeLower) +{ + uint32_t crc = 0xFFFFFFFF; + + while (*src) + crc = ((crc>>8)&0xFFFFFFFF)^CRCTable[(crc^ (makeLower ? tolower(*src++) : *src++) )&0xFF]; + + return ~crc; +} // strip the whitespaces at the beginning and the end of a string // also convert to lowercase if needed @@ -183,34 +194,28 @@ uint32_t CLangMngr::CLang::LangEntry::GetDefHash() return m_DefHash; } -uint32_t CLangMngr::CLang::LangEntry::GetKeyHash() -{ - return m_KeyHash; -} - -const char *CLangMngr::CLang::LangEntry::GetKey() -{ - return m_pKey; -} - const char *CLangMngr::CLang::LangEntry::GetDef() { - return m_pDef; + return m_pDef.c_str(); } +int CLangMngr::CLang::LangEntry::GetKey() +{ + return 0; +} CLangMngr::CLang::LangEntry::LangEntry() { Clear(); } -CLangMngr::CLang::LangEntry::LangEntry(const char *pKey) +CLangMngr::CLang::LangEntry::LangEntry(int pKey) { Clear(); SetKey(pKey); } -CLangMngr::CLang::LangEntry::LangEntry(const char *pKey, const char *pDef) +CLangMngr::CLang::LangEntry::LangEntry(int pKey, const char *pDef) { Clear(); SetKey(pKey); @@ -220,42 +225,24 @@ CLangMngr::CLang::LangEntry::LangEntry(const char *pKey, const char *pDef) CLangMngr::CLang::LangEntry::LangEntry(const LangEntry &other) { Clear(); - SetKey(other.m_pKey); - SetDef(other.m_pDef); -} - - -void CLangMngr::CLang::LangEntry::operator= (const char *pNewDef) -{ - SetDef(pNewDef); -} - -bool CLangMngr::CLang::LangEntry::operator== (uint32_t hash) -{ - return m_KeyHash == hash; + SetKey(other.key); + SetDef(other.m_pDef.c_str()); } void CLangMngr::CLang::LangEntry::Clear() { - m_pKey = NULL; - m_pDef = NULL; - m_KeyHash = 0; - m_DefHash = 0; + m_pDef.clear(); + key = -1; } -void CLangMngr::CLang::LangEntry::SetKey(const char *pKey) +void CLangMngr::CLang::LangEntry::SetKey(int pkey) { - delete [] m_pKey; - m_pKey = new char[strlen(pKey)+1]; - strcpy(m_pKey, pKey); - m_KeyHash = MakeHash(pKey, true); + key = pkey; } void CLangMngr::CLang::LangEntry::SetDef(const char *pDef) { - delete [] m_pDef; - m_pDef = new char[strlen(pDef)+1]; - strcpy(m_pDef, pDef); + m_pDef.assign(pDef); m_DefHash = MakeHash(pDef); } @@ -280,51 +267,65 @@ CLangMngr::CLang::~CLang() void CLangMngr::CLang::Clear() { + /*for (int i=0; iGetKeyHash(key); + for (i=0; iGetKeyHash(e->GetKey()) == hash) break; - if (iter != m_LookUpTable.end()) - return *iter; + } + if (i < m_LookUpTable.size()) + return m_LookUpTable.at(i); - m_LookUpTable.push_back(LangEntry(key)); + e = new LangEntry(key); + m_LookUpTable.push_back(e); return m_LookUpTable.back(); } -void CLangMngr::CLang::MergeDefinitions(CVector &vec) +void CLangMngr::CLang::MergeDefinitions(CQueue &vec) { - for (CVector::iterator iter = vec.begin(); iter != vec.end(); ++iter) + const char *def = 0; + int key = -1; + while (!vec.empty()) { - LangEntry & entry = GetEntry(iter->key); - if (entry.GetDefHash() != MakeHash(iter->def)) - entry = iter->def; + key = vec.front()->key; + def = vec.front()->def->c_str(); + LangEntry *entry = GetEntry(key); + if (entry->GetDefHash() != MakeHash(def)) + { + entry->SetDef(def); + } + delete vec.front(); + vec.pop(); } } -void CLangMngr::CLang::Dump() -{ - LookUpVecIter iter; - for (iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) - printf(" %s(%d)=%s(%d)\n", iter->GetKey(), iter->GetKeyHash(), iter->GetDef(), iter->GetDefHash()); -} - - const char * CLangMngr::CLang::GetDef(const char *key) { - static char nfind[1024]; - uint32_t hash = MakeHash(key, true); - for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) + static char nfind[1024] = "ML_NOTFOUND"; + int ikey = lman->GetKeyEntry(key); + if (ikey == -1) + return nfind; + for (unsigned int i = 0; iGetDef(); + qdbg("Key: %d\tLookup: %d\tString: %s\n", + ikey, m_LookUpTable[i]->GetKey(), m_LookUpTable[i]->GetDef()); + if (m_LookUpTable[i]->GetKey() == ikey) + return m_LookUpTable[i]->GetDef(); } - return nfind; + return "ML_LNOTFOUND"; } @@ -336,144 +337,85 @@ struct OffsetPair // Assumes fp is set to the right position bool CLangMngr::CLang::Save(FILE *fp) { - uint32_t tmpu32; - - long startOffset = ftell(fp); - - tmpu32 = m_LookUpTable.size(); - fflush(fp); - // number of entries - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - - // write fields that will be filled later - tmpu32 = 0; - // offset to definition table - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - // size of definition table - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - // offset to rev lookup table - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - // size of rev lookup table - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - uint32_t dtb, rtb; - - fflush(fp); - // Write the lookup table - for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) - { - uint32_t ltbE[4] = { - iter->GetKeyHash(), - iter->GetDefHash(), - 0, // def offset - 0 // key offset - }; - fwrite((void*)ltbE, sizeof(uint32_t), 4, fp); - } - - // Write the definition table - dtb = ftell(fp); - CVector offsetVec; - offsetVec.reserve(m_LookUpTable.size()); - OffsetPair tmp; - tmp.keyOffset = 0; - for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) - { - tmp.defOffset = ftell(fp); - offsetVec.push_back(tmp); - uint16_t defLength = strlen(iter->GetDef()); - fwrite((void*)&defLength, sizeof(defLength), 1, fp); - fwrite((void*)iter->GetDef(), 1, defLength, fp); - } - - // Write the reverse lookup table - rtb = ftell(fp); - CVector::iterator offsetVecIter = offsetVec.begin(); - for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter) - { - offsetVecIter->keyOffset = ftell(fp); - ++offsetVecIter; - - char keyLength = strlen(iter->GetKey()); - fwrite((void*)&keyLength, 1, 1, fp); - fwrite((void*)iter->GetKey(), 1, keyLength, fp); - } - - // Write the offsets - fflush(fp); - int i = 0; - for (CVector::iterator iter = offsetVec.begin(); iter != offsetVec.end(); ++iter) - { - fseek(fp, startOffset + 20 + i*16 + 8, SEEK_SET); - - tmpu32 = iter->defOffset; - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - tmpu32 = iter->keyOffset; - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - fflush(fp); - ++i; - } - - fseek(fp, 0, SEEK_END); - uint32_t dtbSize = rtb - dtb; - uint32_t rtbSize = ftell(fp) - rtb; - fseek(fp, startOffset + 4, SEEK_SET); - fwrite((void*)&dtb, sizeof(uint32_t), 1,fp); - fwrite((void*)&dtbSize, sizeof(uint32_t), 1,fp); - fwrite((void*)&rtb, sizeof(uint32_t), 1,fp); - fwrite((void*)&rtbSize, sizeof(uint32_t), 1,fp); - return true; + return false; } // assumes fp is set to the right position bool CLangMngr::CLang::Load(FILE *fp) { - uint32_t numOfEntries; - uint32_t dtb, rtb, dtbSize, rtbSize; - Clear(); - - fread((void*)&numOfEntries, sizeof(uint32_t), 1, fp); - fread((void*)&dtb, sizeof(uint32_t), 1, fp); - fread((void*)&dtbSize, sizeof(uint32_t), 1, fp); - fread((void*)&rtb, sizeof(uint32_t), 1, fp); - fread((void*)&rtbSize, sizeof(uint32_t), 1, fp); - - char keyBuf[257]; - char defBuf[4096]; - - for (unsigned int i = 0; i < numOfEntries; ++i) - { - uint32_t keyHash, defHash; - uint32_t tmp1, tmp2, tmp3; - fread((void*)&keyHash, sizeof(uint32_t), 1, fp); - fread((void*)&defHash, sizeof(uint32_t), 1, fp); - fread((void*)&tmp1, sizeof(uint32_t), 1, fp); - fread((void*)&tmp2, sizeof(uint32_t), 1, fp); - tmp3 = ftell(fp); - unsigned char tmpu8; - uint16_t tmpu16; - // definition - fseek(fp, tmp2, SEEK_SET); - fread((void*)&tmpu8, 1, 1, fp); - fread((void*)keyBuf, 1, tmpu8, fp); - keyBuf[tmpu8] = 0; - //key - fseek(fp, tmp1, SEEK_SET); - fread((void*)&tmpu16, 2, 1, fp); - fread((void*)defBuf, 1, tmpu16, fp); - defBuf[tmpu16] = 0; - - // add to the entries - m_LookUpTable.push_back(LangEntry(keyBuf, defBuf)); - - // seek back - fseek(fp, tmp3, SEEK_SET); - } return true; } /******** CLangMngr *********/ +CLangMngr::CLangMngr() +{ + Clear(); +} + +const char * CLangMngr::GetKey(int key) +{ + if (key < 0 || key >= (int)KeyList.size()) + return 0; + + return KeyList[key]->key.c_str(); +} + +int CLangMngr::GetKeyHash(int key) +{ + if (key < 0 || key >= (int)KeyList.size()) + return 0; + + return KeyList[key]->hash; +} + +int CLangMngr::GetKeyEntry(const char *key) +{ + uint32_t hKey = MakeHash(key, true); + uint32_t cmpKey = 0; + unsigned int i = 0; + + for (i = 0; ihash; + if (hKey == cmpKey) + { + return i; + } + } + + return -1; +} + +int CLangMngr::AddKeyEntry(String &key) +{ + uint32_t hKey = MakeHash(key.c_str(), true); + + keyEntry *e = new keyEntry; + e->key.assign(key); + e->hash = hKey; + KeyList.push_back(e); + + return (KeyList.size() - 1); +} + +int CLangMngr::GetKeyEntry(String &key) +{ + uint32_t hKey = MakeHash(key.c_str(), true); + unsigned int i = 0; + + for (i = 0; ihash) + { + return i; + } + } + + return -1; +} + const char *CLangMngr::Format(const char *src, ...) { va_list argptr; @@ -745,10 +687,11 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len) return outbuf; } -void CLangMngr::MergeDefinitions(const char *lang, CVector &tmpVec) +void CLangMngr::MergeDefinitions(const char *lang, CQueue &tmpVec) { - CLang & language = GetLang(lang); - language.MergeDefinitions(tmpVec); + CLang * language = GetLang(lang); + if (language) + language->MergeDefinitions(tmpVec); } //this is the file parser for dictionary text files @@ -757,220 +700,253 @@ int CLangMngr::MergeDefinitionFile(const char *file) { FILE *fp = fopen(file, "rt"); if (!fp) - return 0; - char buf[4096]; - char language[3]; - char bufstk[4096]; - - // Allocate enough memory to store everything - fseek(fp, 0, SEEK_END); - long fileSize = ftell(fp); - char *tempStorage = new char[fileSize]; - fseek(fp, 0, SEEK_SET); - char *ptrStorage = tempStorage; - - unsigned int i = 0, j = 0; - int litidx = LITIDX_NONE; - int stk = 0; - int max = 0; - int multiline = 0; - CLang lang; - CVector tmpVec; - sKeyDef tmpEntry; - while (fgets(buf, 4095, fp) != NULL) { - j++; - size_t len=strlen(buf); - for (i=0; i::iterator iter; + for (iter=FileList.begin(); iter!=FileList.end(); iter++) { - // be very careful not to mess up litidx assignments. - // also stk assignments. - switch (litidx) + if ( (*iter)->file.compare(file) == 0 ) { - case LITIDX_NONE: - { - if (buf[i] == '[') - { - // Merge last language - if (!tmpVec.empty()) - { - MergeDefinitions(language, tmpVec); - tmpVec.clear(); - } - litidx = LITIDX_BRACKET; - stk = 0; - } else if (buf[i] == '=') { - bufstk[stk] = 0; - tmpEntry.key = ptrStorage; - ptrStorage += strip(bufstk, ptrStorage, true); - stk = 0; - bufstk[stk] = 0; - litidx = LITIDX_DEFINITION; - } else if (buf[i] == ':') { - bufstk[stk] = 0; - tmpEntry.key = ptrStorage; - ptrStorage += strip(bufstk, ptrStorage, true); - stk = 0; - bufstk[stk] = 0; - multiline = 1; - litidx = LITIDX_DEFINITION; - } else { - bufstk[stk++] = buf[i]; - } - break; - } - case LITIDX_DEFINITION: - { - if (buf[i] == '\n' && !multiline) - { - bufstk[stk] = 0; - tmpEntry.def = ptrStorage; - tmpVec.push_back(tmpEntry); - ptrStorage += strip(bufstk, ptrStorage); - stk = 0; - bufstk[stk] = 0; - multiline = 0; - litidx = LITIDX_NONE; - } else if (buf[i] == '%') { - i++; - if (buf[i] == 's') - { - bufstk[stk++] = INSERT_STRING; - } else if (buf[i] == 'f') { - bufstk[stk++] = INSERT_FLOAT; - } else if (buf[i] == 'd') { - bufstk[stk++] = INSERT_NUMBER; - } else if (buf[i] == 'n') { - bufstk[stk++] = INSERT_NEWLINE; - } else { - bufstk[stk++] = '%'; - bufstk[stk++] = buf[i]; - } - } else if (buf[i] == ':' && multiline && i == 0) { - bufstk[stk] = 0; - tmpEntry.def = ptrStorage; - tmpVec.push_back(tmpEntry); - ptrStorage += strip(bufstk, ptrStorage); - stk = 0; - bufstk[stk] = 0; - //lang.MergeDefinition(key, def); - litidx = LITIDX_NONE; - multiline = 0; - } else { - if (stk < (sizeof(bufstk)-1)) - bufstk[stk++] = buf[i]; - } - break; - } - case LITIDX_BRACKET: - { - if (buf[i] == ']') - { - language[stk] = 0; - ptrStorage = tempStorage; // reset storage pointer - stk = 0; - litidx = LITIDX_NONE; - } else { - if (stk < (sizeof(language)-1) && isalpha(buf[i])) - language[stk++] = tolower(buf[i]); - } - break; - } + char buf[33] = {0}; + (*iter)->val.assign(buf); + break; + } + } + return 0; + } + MD5 md5; + md5.update(fp); + md5.finalize(); + char md5buffer[33]; + md5.hex_digest(md5buffer); + bool foundFlag = false; + +/* CVector::iterator iter; + for (iter=FileList.begin(); iter!=FileList.end(); iter++) + { + if ( (*iter)->file.compare(file) == 0 ) + { + if ( (*iter)->val.compare(md5buffer) == 0 ) + { + return 2; + } else { + (*iter)->val.assign(md5buffer); + break; } + foundFlag = true; } } - // finish last definition if no newline is at the end of file - if (litidx==LITIDX_DEFINITION) + + if (!foundFlag) { - bufstk[stk] = 0; - tmpEntry.def = ptrStorage; - tmpVec.push_back(tmpEntry); - ptrStorage += strip(bufstk, ptrStorage); + md5Pair *p = new md5Pair; + p->file.assign(file); + p->val.assign(md5buffer); + FileList.push_back(p); + }*/ + + fp = fopen(file, "rt"); + if (!fp) + { + return 0; } - // merge last language - if (!tmpVec.empty()) - MergeDefinitions(language, tmpVec); - delete [] tempStorage; + + // Allocate enough memory to store everything + bool multiline = 0; + int pos = 0, line = 0; + CQueue Defq; + String buf; + char language[3]; + sKeyDef *tmpEntry = NULL; + + while (!feof(fp)) + { + line++; + buf._fread(fp); + buf.trim(); + if (buf[0] == 0) + continue; + if (buf[0] == '[' && buf.size() >= 3) + { + if (multiline) + { + AMXXLOG_Log("New section, multiline unterminated (file \"%s\" line %d)", file, line); + if (tmpEntry) + delete tmpEntry; + tmpEntry = 0; + } + if (!Defq.empty()) + { + MergeDefinitions(language, Defq); + } + language[0] = buf[1]; + language[1] = buf[2]; + language[2] = 0; + } else if (buf.size() > 4) { + if (!multiline) + { + pos = buf.find('='); + if (pos > String::npos) + { + tmpEntry = new sKeyDef; + String key = buf.substr(0, pos); + String def = buf.substr(pos+1, def.size()-pos); + key.trim(); + key.toLower(); + int iKey = GetKeyEntry(key); + if (iKey == -1) + iKey = AddKeyEntry(key); + qdbg("key=%d\n", iKey); + tmpEntry->key = iKey; + tmpEntry->def = new String; + tmpEntry->def->assign(def.c_str()); + tmpEntry->def->trim(); + Defq.push(tmpEntry); + tmpEntry = 0; + } else { + pos = buf.find(':'); + if (pos > String::npos) + { + tmpEntry = new sKeyDef; + String key = buf.substr(0, pos); + key.trim(); + key.toLower(); + int iKey = GetKeyEntry(key); + if (iKey == -1) + iKey = AddKeyEntry(key); + tmpEntry->key = iKey; + tmpEntry->def = new String; + multiline = true; + } else { + //user typed a line with no directives + AMXXLOG_Log("Invalid multi-lingual line (file \"%s\" line %d)", file, line); + } + } + } else { + if (buf[0] == ':') + { + Defq.push(tmpEntry); + tmpEntry = 0; + multiline = false; + } else { + tmpEntry->def->append(buf); + } + } // if !multiline + } //if - main + } + return 1; } // Find a CLang by name, if not found, add it -CLangMngr::CLang & CLangMngr::GetLang(const char *name) +CLangMngr::CLang * CLangMngr::GetLang(const char *name) { LangVecIter iter; - for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter) - if (*iter == name) - break; - if (iter != m_Languages.end()) - return *iter; - - m_Languages.push_back(CLang(name)); - return m_Languages.back(); -} - -void CLangMngr::Dump() -{ - LangVecIter iter; - for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter) + for (iter=m_Languages.begin(); iter!=m_Languages.end(); iter++) { - printf("LANGUAGE: %s\n", iter->GetName()); - iter->Dump(); + if ( strcmp((*iter)->GetName(), name)==0 ) + return (*iter); } + + CLang *p = new CLang(name); + p->SetMngr(this); + + m_Languages.push_back(p); + return p; } const char *CLangMngr::GetDef(const char *langName, const char *key) { - CLang & lang = GetLang(langName); - return lang.GetDef(key); + CLang *lang = GetLang(langName); + if (lang) + return lang->GetDef(key); + return ""; } bool CLangMngr::Save(const char *filename) { - FILE *fp = fopen(filename, "wb"); + /*FILE *fp = fopen(filename, "wb"); + if (!fp) return false; - uint32_t tmpu32; - // Magic - tmpu32 = MAGIC_HDR; - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - tmpu32 = m_Languages.size(); - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - // Write language info table - tmpu32 = 0; - for (LangVecIter iter = m_Languages.begin(); iter != m_Languages.end(); ++iter) - { - // name - fwrite((void*)iter->GetName(), 2, 1, fp); - // offset ( to be set later ) - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - } - fflush(fp); - CVector langOffsets; - langOffsets.reserve(m_Languages.size()); - // write the languages - for (LangVecIter iter1 = m_Languages.begin(); iter1 != m_Languages.end(); ++iter1) + uint32_t magic = MAGIC_HDR; + unsigned char version = FFHL_VERSION; + uint32_t langNum = m_Languages.size(); + const char *langName = 0; + + fwrite((void *)&magic, sizeof(uint32_t), 1, fp); + fwrite((void *)&version, sizeof(unsigned char), 1, fp); + fwrite((void *)&langNum, sizeof(uint32_t), 1, fp); + + LangVecIter iter; + for (iter = m_Languages.begin(); iter!=m_Languages.end(); iter++) { - langOffsets.push_back((uint32_t)ftell(fp)); - if (!iter1->Save(fp)) - { - fclose(fp); - return false; - } - // Make sure we are at the end of the file again - fseek(fp, 0, SEEK_END); + langName = (*iter)->GetName(); + fwrite(langName, sizeof(char), 2, fp); + + }*/ + return false; +} + +bool CLangMngr::SaveCache(const char *filename) +{ + FILE *fp = fopen(filename, "wb"); + if (!fp) + { + return false; } - // write the offsets - int i = 0; - for (CVector::iterator iter2 = langOffsets.begin(); iter2 != langOffsets.end(); ++iter2) + CVector::iterator i; + short dictCount = FileList.size(); + char len = 0; + + fwrite((void *)&dictCount, sizeof(short), 1, fp); + + for (i=FileList.begin(); i!=FileList.end(); i++) { - fseek(fp, 8 + i*6 + 2, SEEK_SET); - tmpu32 = *iter2; - fwrite((void*)&tmpu32, sizeof(tmpu32), 1, fp); - ++i; + len = (*i)->file.size(); + fwrite((void *)&len, sizeof(char), 1, fp); + fwrite((*i)->file.c_str(), sizeof(char), len, fp); + fwrite((*i)->val.c_str(), sizeof(char), 32, fp); } + fclose(fp); + + return true; +} + +bool CLangMngr::LoadCache(const char *filename) +{ + FILE *fp = fopen(filename, "rb"); + if (!fp) + { + return false; + } + + short dictCount = 0; + char len = 0; + char buf[255]; + char md5[34]; + fread((void*)&dictCount, sizeof(short), 1, fp); + md5Pair *p = 0; + + + for (int i=1; i<=dictCount; i++) + { + fread((void*)&len, sizeof(char), 1, fp); + fread(buf, sizeof(char), len, fp); + buf[len] = 0; + fread(md5, sizeof(char), 32, fp); + md5[32] = 0; + p = new md5Pair; + p->file.assign(buf); + p->val.assign(md5); + FileList.push_back(p); + p = 0; + } + + fclose(fp); + return true; } @@ -978,47 +954,38 @@ bool CLangMngr::Load(const char *filename) { Clear(); - // open the file - FILE *fp = fopen(filename, "rb"); - if (!fp) - return false; - - uint32_t tmpu32; - // Check magic - fread((void*)&tmpu32, sizeof(uint32_t), 1, fp); - if (tmpu32 != MAGIC_HDR) - return false; - - uint32_t numOfLangs; - fread((void*)&numOfLangs, sizeof(uint32_t), 1, fp); - - // Read language info table - CVector langOffsets; - langOffsets.reserve(numOfLangs); - for (uint32_t i = 0; i < numOfLangs; ++i) - { - char langName[3]; - fread((void*)langName, 2, 1, fp); - langName[2] = 0; - GetLang(langName); - fread((void*)&tmpu32, sizeof(uint32_t), 1, fp); - langOffsets.push_back(tmpu32); - } - - // read languages - for (uint32_t i = 0; i < numOfLangs; ++i) - { - fseek(fp, langOffsets[i], SEEK_SET); - if (!m_Languages[i].Load(fp)) - return false; - } - fclose(fp); return true; } +CLangMngr::~CLangMngr() +{ + Clear(); +} + void CLangMngr::Clear() { + /*int i = 0; + for (i=0; iGetName(); + } + i++; + } + return ""; } bool CLangMngr::LangExists(const char *langName) @@ -1041,9 +1018,13 @@ bool CLangMngr::LangExists(const char *langName) break; } - for (LangVecIter iter = m_Languages.begin(); iter != m_Languages.end(); ++iter) - if (*iter == buf) + LangVecIter iter; + for (iter=m_Languages.begin(); iter!=m_Languages.end(); iter++) + { + if ( strcmp((*iter)->GetName(), langName)==0 ) return true; + iter++; + } return false; } diff --git a/amxmodx/CLang.h b/amxmodx/CLang.h index 3fad0fb1..177c83f7 100755 --- a/amxmodx/CLang.h +++ b/amxmodx/CLang.h @@ -35,14 +35,28 @@ #define LANG_SERVER 0 #define LANG_PLAYER -1 +struct md5Pair +{ + String file; + String val; +}; + +struct keyEntry +{ + String key; + uint32_t hash; +}; + +struct sKeyDef +{ + sKeyDef() { key = -1; def = 0; } + ~sKeyDef() { if (def) delete def; } + int key; + String *def; +}; + class CLangMngr { - struct sKeyDef - { - const char *key; - const char *def; - }; - class CLang { public: @@ -51,7 +65,7 @@ class CLangMngr ~CLang(); const char *GetDef(const char *key); - void MergeDefinitions(CVector & vec); + void MergeDefinitions(CQueue & vec); void Clear(); friend bool operator == (const CLang &left, const char *right) @@ -59,9 +73,9 @@ class CLangMngr return strcmp(left.m_LanguageName, right)==0 ? true : false; } const char *GetName() { return m_LanguageName; } - void Dump(); bool Save(FILE *fp); bool Load(FILE *fp); + void SetMngr(CLangMngr *l) { lman = l; } private: static uint32_t MakeHash(const char *src, bool makeLower = false); @@ -69,56 +83,62 @@ class CLangMngr class LangEntry { uint32_t m_DefHash; - uint32_t m_KeyHash; - char *m_pKey; - char *m_pDef; - void SetKey(const char *pKey); - void SetDef(const char *pDef); + int key; + String m_pDef; public: + void SetKey(int key); + void SetDef(const char *pDef); uint32_t GetDefHash(); - uint32_t GetKeyHash(); - const char *GetKey(); + + int GetKey(); const char *GetDef(); LangEntry(); - LangEntry(const char *pKey); - LangEntry(const char *pKey, const char *pDef); + LangEntry(int key); + LangEntry(int key, const char *pDef); LangEntry(const LangEntry &other); - void operator= (const char *pNewDef); - bool operator== (uint32_t hash); - void Clear(); }; - LangEntry & GetEntry(const char *key); - typedef CVector LookUpVec; + LangEntry * GetEntry(int key); + typedef CVector LookUpVec; typedef LookUpVec::iterator LookUpVecIter; char m_LanguageName[3]; LookUpVec m_LookUpTable; + CLangMngr *lman; }; - void MergeDefinitions(const char *lang, CVector &tmpVec); + void MergeDefinitions(const char *lang, CQueue &tmpVec); static size_t strip(char *str, char *newstr, bool makelower=false); - typedef CVector LangVec; - typedef LangVec::iterator LangVecIter; + typedef CVector LangVec; + typedef CVector::iterator LangVecIter; LangVec m_Languages; + CVector FileList; + CVector KeyList; - CLang & GetLang(const char *name); + CLang * GetLang(const char *name); int m_CurGlobId; public: int MergeDefinitionFile(const char *file); - void Dump(); const char *GetDef(const char *langName, const char *key); const char *Format(const char *src, ...); char *FormatAmxString(AMX *amx, cell *params, int parm, int &len); bool Save(const char *filename); bool Load(const char *filename); + bool LoadCache(const char *filename); + bool SaveCache(const char *filename); + int GetKeyEntry(String &key); + int GetKeyEntry(const char *key); + int GetKeyHash(int key); + const char *GetKey(int key); + int AddKeyEntry(String &key); + uint32_t MakeHash(const char *src, bool makeLower); int GetLangsNum(); const char *GetLangName(int langId); @@ -127,6 +147,9 @@ public: // When a language id in a format string in FormatAmxString is 0, the glob id decides which language to take. void SetDefLang(int id); void Clear(); + + CLangMngr(); + ~CLangMngr(); }; #endif //_INCLUDE_CLANG_H diff --git a/amxmodx/CLogEvent.h b/amxmodx/CLogEvent.h index 7c5c87c4..5512b74b 100755 --- a/amxmodx/CLogEvent.h +++ b/amxmodx/CLogEvent.h @@ -63,7 +63,7 @@ public: friend class LogEventsMngr; friend class CLogEvent; LogEventsMngr* parent; - CString text; + String text; int logid; int pos; int result; diff --git a/amxmodx/CMenu.h b/amxmodx/CMenu.h index 152363c6..66e89b2c 100755 --- a/amxmodx/CMenu.h +++ b/amxmodx/CMenu.h @@ -40,7 +40,7 @@ class MenuMngr { struct MenuIdEle { - CString name; + String name; AMX* amx; MenuIdEle* next; int id; diff --git a/amxmodx/CMisc.h b/amxmodx/CMisc.h index b4b28ccc..45e88b4d 100755 --- a/amxmodx/CMisc.h +++ b/amxmodx/CMisc.h @@ -40,8 +40,8 @@ class CCVar { cvar_t cvar; - CString name; - CString plugin; + String name; + String plugin; public: CCVar( const char* pname, const char* pplugin, int pflags, float pvalue ) : name(pname) , plugin(pplugin ) { @@ -68,9 +68,9 @@ class CPlayer public: edict_t* pEdict; - CString name; - CString ip; - CString team; + String name; + String ip; + String team; bool initialized; bool ingame; @@ -98,7 +98,7 @@ public: int death_killer; int death_victim; bool death_tk; - CString death_weapon; + String death_weapon; Vector lastTrace; Vector thisTrace; @@ -149,7 +149,7 @@ public: // class ForceObject // ***************************************************** class ForceObject { - CString filename; + String filename; FORCE_TYPE type; Vector mins; Vector maxs; @@ -203,7 +203,7 @@ public: // ***************************************************** class CScript { - CString filename; + String filename; AMX* amx; void* code; public: @@ -220,7 +220,7 @@ public: class TeamIds { struct TeamEle { - CString name; + String name; int id; char tid; static char uid; diff --git a/amxmodx/CModule.h b/amxmodx/CModule.h index 68aca045..2bad7908 100755 --- a/amxmodx/CModule.h +++ b/amxmodx/CModule.h @@ -69,7 +69,7 @@ struct amxx_module_info_s class CModule { - CString m_Filename; // Filename + String m_Filename; // Filename bool m_Metamod; // Using metamod? bool m_Amxx; // Using new module interface? module_info_s* m_InfoOld; // module info (old module interface) diff --git a/amxmodx/CPlugin.h b/amxmodx/CPlugin.h index 2e29945e..2c234d0f 100755 --- a/amxmodx/CPlugin.h +++ b/amxmodx/CPlugin.h @@ -59,10 +59,10 @@ public: AMX amx; void* code; - CString name; - CString version; - CString title; - CString author; + String name; + String version; + String title; + String author; int paused_fun; int status; CPlugin* next; diff --git a/amxmodx/CQueue.h b/amxmodx/CQueue.h new file mode 100755 index 00000000..22fa69f6 --- /dev/null +++ b/amxmodx/CQueue.h @@ -0,0 +1,125 @@ +/* AMX Mod X +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +//by David "BAILOPAN" Anderson +#ifndef _INCLUDE_CQUEUE_H +#define _INCLUDE_CQUEUE_H + +template +class CQueue +{ +public: + class CQueueItem + { + public: + CQueueItem(const T &i, CQueueItem *n) + { + item = i; + next = n; + } + CQueueItem *GetNext() + { + return next; + } + T & GetItem() + { + return item; + } + void SetNext(CQueueItem *n) + { + next = n; + } + private: + T item; + CQueueItem *next; + }; +public: + CQueue() + { + mSize = 0; + mFirst = NULL; + mLast = NULL; + } + + bool empty() + { + return ((mSize==0)?true:false); + } + + void push(const T &v) + { + CQueueItem *p = new CQueueItem(v, NULL); + if (empty()) + { + mFirst = p; + } else { + mLast->SetNext(p); + } + mLast = p; + mSize++; + } + + void pop() + { + if (mFirst == mLast) + { + delete mFirst; + mFirst = NULL; + mLast = NULL; + } else { + CQueueItem *p = mFirst->GetNext(); + delete mFirst; + mFirst = p; + } + mSize--; + } + + T & front() + { + return mFirst->GetItem(); + } + + T & back() + { + return mLast->GetItem(); + } + + unsigned int size() + { + return mSize; + } +private: + CQueueItem *mFirst; + CQueueItem *mLast; + unsigned int mSize; +}; + +#endif //_INCLUDE_CQUEUE_H \ No newline at end of file diff --git a/amxmodx/CString.h b/amxmodx/CString.h index b6e95f1e..3a52b284 100755 --- a/amxmodx/CString.h +++ b/amxmodx/CString.h @@ -33,30 +33,67 @@ #define _INCLUDE_CSTRING_H //by David "BAILOPAN" Anderson -class CString +class String { public: - CString() { v = NULL; mSize = 0; } - ~CString() { if (v) delete [] v; } + String() + { + v = NULL; + mSize = 0; + cSize = 0; + Grow(2); + assign(""); + } - //added these for amxx - CString(const char *src) { v = NULL; mSize = 0; assign(src); } - CString(CString &src) { v = NULL; mSize = 0; assign(src.c_str()); } + ~String() + { + if (v) + delete [] v; + } + + String(const char *src) + { + v = NULL; + mSize = 0; + cSize = 0; assign(src); + } + + String(String &src) + { + v = NULL; + mSize = 0; + cSize = 0; + assign(src.c_str()); + } const char *c_str() { return v?v:""; } const char *c_str() const { return v?v:""; } void append(const char *t) { - Grow(strlen(v) + strlen(t)); + Grow(cSize + strlen(t)); strcat(v, t); + cSize = strlen(v); } - void append(CString &d) + void append(const char c) + { + Grow(cSize + 2); + v[cSize] = c; + v[++cSize] = 0; + } + + void append(String &d) { const char *t = d.c_str(); - Grow(strlen(v) + strlen(t)); + Grow(cSize + strlen(t)); strcat(v, t); + cSize = strlen(v); + } + + void assign(const String &src) + { + assign(src.c_str()); } void assign(const char *d) @@ -64,20 +101,27 @@ public: if (!d) { Grow(1); + cSize = 0; strcpy(v, ""); return; } Grow(strlen(d)); if (v) + { strcpy(v, d); + cSize = strlen(v); + } else { + cSize = 0; + } } void clear() { if (v) - delete [] v; - v = NULL; - mSize = 0; + { + v[0] = 0; + cSize = 0; + } } int compare (const char *d) @@ -100,7 +144,7 @@ public: //Added this for amxx inclusion bool empty() { - if (!v || !mSize) + if (!v || !cSize) return true; return false; @@ -110,20 +154,218 @@ public: { if (!v) return 0; - return strlen(v); + return cSize; + } + + const char * _fread(FILE *fp) + { + Grow(512); + char * ret = fgets(v, 511, fp); + cSize = strlen(v); + return ret; + } + + int find(const char c, int index = 0) + { + if (!v) + return npos; + unsigned int i = 0; + for (i=index; i=0; i--) + { + if (!is_space(v[i]) + || (is_space(v[i]) && i==0)) + { + erase(i+1, j); + break; + } + j++; + } + } + + if (cSize == 1) + { + if (is_space(v[0])) + { + clear(); + return; + } + } + } + + String & erase(unsigned int start, int num = npos) + { + if (!v) + return (*this); + unsigned int i = 0; + //check for bounds + if (num == npos || start+num > cSize-num+1) + num = cSize - start; + //do the erasing + bool copyflag = false; + for (i=0; i=start && i= cSize || !v) + return ns; + + if (index+rnum >= cSize) + { + rnum = cSize - index+1; + } + + unsigned int i = 0, j=0; + char *s = new char[cSize+1]; + + for (i=index; i= 65 && v[i] <= 90) + v[i] |= 32; + } + } + + String & operator = (const String &src) + { + assign(src); + return *this; + } + + String & operator = (const char *src) + { + assign(src); + return *this; + + } + + char operator [] (unsigned int index) + { + if (index > cSize) + { + return -1; + } else { + return v[index]; + } } private: - void Grow(int d) + void Grow(unsigned int d) { if (d<1) return; if (d > mSize) { + mSize = d + 16; // allocate a buffer char *t = new char[d+1]; if (v) { strcpy(t, v); - t[strlen(v)] = 0; + t[cSize] = 0; delete [] v; } v = t; @@ -132,7 +374,10 @@ private: } char *v; - int mSize; + unsigned int mSize; + unsigned int cSize; +public: + static const int npos = -1; }; -#endif //_INCLUDE_CSTRING_H \ No newline at end of file +#endif //_INCLUDE_CSTRING_H diff --git a/amxmodx/CVault.h b/amxmodx/CVault.h index 57a4276e..66cef054 100755 --- a/amxmodx/CVault.h +++ b/amxmodx/CVault.h @@ -32,7 +32,7 @@ #ifndef VAULT_CUSTOM_H #define VAULT_CUSTOM_H -#include "CString.h" +#include "String.h" #include "CList.h" // ***************************************************** @@ -43,14 +43,14 @@ class Vault { struct Obj { - CString key; - CString value; + String key; + String value; int number; Obj *next; Obj( const char* k, const char* v); } *head; - CString path; + String path; Obj** find( const char* n ); @@ -79,8 +79,8 @@ public: iterator& operator++() { if ( a ) a = a->next; return *this; } bool operator==(const iterator& b) const { return a == b.a; } bool operator!=(const iterator& b) const { return !operator==(b); } - CString& key() const { return a->key; } - CString& value() const { return a->value; } + String& key() const { return a->key; } + String& value() const { return a->value; } }; inline iterator begin() const { return iterator(head); } diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 27189a1b..5a4751cf 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -796,6 +796,41 @@ static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */ return -1; } +static cell AMX_NATIVE_CALL amx_md5(AMX *amx, cell *params) +{ + int len = 0; + char *str = get_amxstring(amx, params[1], 0, len); + char buffer[33]; + + MD5 md5; + md5.update((unsigned char *)str, len); + md5.finalize(); + md5.hex_digest(buffer); + + return set_amxstring(amx, params[2], buffer, 32); +} + +static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params) +{ + int len = 0; + char *str = get_amxstring(amx, params[1], 0, len); + char buffer[33]; + + FILE *fp = fopen(str, "rb"); + if (!fp) + { + amx_RaiseError(amx, AMX_ERR_NATIVE); + return 0; + } + + MD5 md5; + md5.update(fp); //closes for you + md5.finalize(); + md5.hex_digest(buffer); + + return set_amxstring(amx, params[2], buffer, 32); +} + static cell AMX_NATIVE_CALL get_pluginsnum(AMX *amx, cell *params) { return g_plugins.getPluginsNum(); @@ -2749,5 +2784,7 @@ AMX_NATIVE_INFO amxmod_Natives[] = { { "get_lang", get_lang }, { "register_dictionary", register_dictionary }, { "lang_exists", lang_exists }, + { "md5", amx_md5 }, + { "md5_file", amx_md5_file }, { NULL, NULL } }; diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 9304270d..55efd9cc 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -41,8 +41,10 @@ #include "mmgr/mmgr.h" #endif +#include "md5.h" #include "CVector.h" #include "CList.h" +#include "CQueue.h" #include "modules.h" #include "CString.h" #include "CPlugin.h" @@ -115,7 +117,7 @@ void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen #define GET_PLAYER_POINTER_I(i) (&g_players[i]) struct WeaponsVault { - CString fullName; + String fullName; short int iId; short int ammoSlot; }; @@ -145,8 +147,8 @@ extern Grenades g_grenades; extern LogEventsMngr g_logevents; extern MenuMngr g_menucmds; extern CLangMngr g_langMngr; -extern CString g_log_dir; -extern CString g_mod_name; +extern String g_log_dir; +extern String g_mod_name; extern TeamIds g_teamsIds; extern Vault g_vault; extern CForwardMngr g_forwards; diff --git a/amxmodx/amxxlog.cpp b/amxmodx/amxxlog.cpp index 1d35f230..eaa03b4b 100755 --- a/amxmodx/amxxlog.cpp +++ b/amxmodx/amxxlog.cpp @@ -106,7 +106,7 @@ void CLog::CreateNewFile() fclose(fp); } -void CLog::UseFile(const CString &fileName) +void CLog::UseFile(const String &fileName) { m_LogFile.assign(build_pathname("%s/%s", g_log_dir.c_str(), fileName.c_str())); } diff --git a/amxmodx/amxxlog.h b/amxmodx/amxxlog.h index ac2a88e8..53a037cf 100755 --- a/amxmodx/amxxlog.h +++ b/amxmodx/amxxlog.h @@ -34,11 +34,11 @@ class CLog { private: - CString m_LogFile; + String m_LogFile; int m_LogType; - void GetLastFile(int &outMonth, int &outDay, CString &outFilename); - void UseFile(const CString &fileName); + void GetLastFile(int &outMonth, int &outDay, String &outFilename); + void UseFile(const String &fileName); public: CLog(); ~CLog(); diff --git a/amxmodx/fakemeta.h b/amxmodx/fakemeta.h index 29544735..ee7a2680 100755 --- a/amxmodx/fakemeta.h +++ b/amxmodx/fakemeta.h @@ -74,7 +74,7 @@ public: { private: // plugin info - CString m_Path; + String m_Path; PLUG_STATUS m_Status; plugin_info_t *m_Info; // Function tables diff --git a/amxmodx/md5.cpp b/amxmodx/md5.cpp new file mode 100755 index 00000000..0eb37288 --- /dev/null +++ b/amxmodx/md5.cpp @@ -0,0 +1,474 @@ +// MD5.CC - source code for the C++/object oriented translation and +// modification of MD5. + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + + */ + +#include "md5.h" + +#include +#include + +// MD5 simple initialization method + +MD5::MD5(){ + + init(); + +} + + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. + +void MD5::update (uint1 *input, uint4 input_length) { + + uint4 input_index, buffer_index; + uint4 buffer_space; // how much space is left in buffer + + if (finalized){ // so we can't update! + /*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/ + return; + } + + // Compute number of bytes mod 64 + buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); + + // Update number of bits + if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) + count[1]++; + + count[1] += ((uint4)input_length >> 29); + + + buffer_space = 64 - buffer_index; // how much space is left in buffer + + // Transform as many times as possible. + if (input_length >= buffer_space) { // ie. we have enough to fill the buffer + // fill the rest of the buffer and transform + memcpy (buffer + buffer_index, input, buffer_space); + transform (buffer); + + // now, transform each 64-byte piece of the input, bypassing the buffer + for (input_index = buffer_space; input_index + 63 < input_length; + input_index += 64) + transform (input+input_index); + + buffer_index = 0; // so we can buffer remaining + } + else + input_index=0; // so we can buffer the whole input + + + // and here we do the buffering: + memcpy(buffer+buffer_index, input+input_index, input_length-input_index); +} + + + +// MD5 update for files. +// Like above, except that it works on files (and uses above as a primitive.) + +void MD5::update(FILE *file){ + + unsigned char buffer[1024]; + int len; + + while (len=fread(buffer, 1, 1024, file)) + update(buffer, len); + + fclose (file); + +} + + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. + + +void MD5::finalize (){ + + unsigned char bits[8]; + unsigned int index, padLen; + static uint1 PADDING[64]={ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (finalized){ + /* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/ + return; + } + + // Save number of bits + encode (bits, count, 8); + + // Pad out to 56 mod 64. + index = (uint4) ((count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update (PADDING, padLen); + + // Append length (before padding) + update (bits, 8); + + // Store state in digest + encode (digest, state, 16); + + // Zeroize sensitive information + memset (buffer, 0, sizeof(*buffer)); + + finalized=1; + +} + + + + +MD5::MD5(FILE *file){ + + init(); // must be called be all constructors + update(file); + finalize (); +} + +unsigned char *MD5::raw_digest(){ + + uint1 *s = new uint1[16]; + + if (!finalized){ +/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<< + "finalized the digest!" <> 8) & 0xff); + output[j+2] = (uint1) ((input[i] >> 16) & 0xff); + output[j+3] = (uint1) ((input[i] >> 24) & 0xff); + } +} + + + + +// Decodes input (unsigned char) into output (UINT4). Assumes len is +// a multiple of 4. +void MD5::decode (uint4 *output, uint1 *input, uint4 len){ + + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + + + + + +// Note: Replace "for loop" with standard memcpy if possible. +void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){ + + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + + + +// Note: Replace "for loop" with standard memset if possible. +void MD5::memset (uint1 *output, uint1 value, uint4 len){ + + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = value; +} + + + +// ROTATE_LEFT rotates x left n bits. + +inline unsigned int MD5::rotate_left (uint4 x, uint4 n){ + return (x << n) | (x >> (32-n)) ; +} + + + + +// F, G, H and I are basic MD5 functions. + +inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){ + return (x & y) | (~x & z); +} + +inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){ + return (x & z) | (y & ~z); +} + +inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){ + return x ^ y ^ z; +} + +inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){ + return y ^ (x | ~z); +} + + + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. + + +inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += F(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += G(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += H(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += I(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} diff --git a/amxmodx/md5.h b/amxmodx/md5.h new file mode 100755 index 00000000..045a4a90 --- /dev/null +++ b/amxmodx/md5.h @@ -0,0 +1,105 @@ +// MD5.CC - source code for the C++/object oriented translation and +// modification of MD5. + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MD5.H - header file for MD5C.C + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + +#include +//#include +//#include + +class MD5 { + +public: +// methods for controlled operation: + MD5 (); // simple initializer + void update (unsigned char *input, unsigned int input_length); + void update (FILE *file); + void finalize (); + +// constructors for special circumstances. All these constructors finalize +// the MD5 context. + MD5 (unsigned char *string); // digest string, finalize + MD5 (FILE *file); // digest file, close, finalize + +// methods to acquire finalized result + unsigned char *raw_digest (); // digest as a 16-byte binary array + char * hex_digest (); // digest as a 33-byte ascii-hex string + char * hex_digest (char buffer[33]); //same as above, passing buffer + + + +private: + +// first, some types: + typedef unsigned int uint4; // assumes integer is 4 words long + typedef unsigned short int uint2; // assumes short integer is 2 words long + typedef unsigned char uint1; // assumes char is 1 word long + +// next, the private data: + uint4 state[4]; + uint4 count[2]; // number of *bits*, mod 2^64 + uint1 buffer[64]; // input buffer + uint1 digest[16]; + uint1 finalized; + +// last, the private methods, mostly static: + void init (); // called by all constructors + void transform (uint1 *buffer); // does the real update work. Note + // that length is implied to be 64. + + static void encode (uint1 *dest, uint4 *src, uint4 length); + static void decode (uint4 *dest, uint1 *src, uint4 length); + static void memcpy (uint1 *dest, uint1 *src, uint4 length); + static void memset (uint1 *start, uint1 val, uint4 length); + + static inline uint4 rotate_left (uint4 x, uint4 n); + static inline uint4 F (uint4 x, uint4 y, uint4 z); + static inline uint4 G (uint4 x, uint4 y, uint4 z); + static inline uint4 H (uint4 x, uint4 y, uint4 z); + static inline uint4 I (uint4 x, uint4 y, uint4 z); + static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac); + static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac); + static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac); + static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac); + +}; diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index 0f647e6a..fea40fb0 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -73,8 +73,8 @@ Grenades g_grenades; LogEventsMngr g_logevents; MenuMngr g_menucmds; CLangMngr g_langMngr; -CString g_log_dir; -CString g_mod_name; +String g_log_dir; +String g_mod_name; XVars g_xvars; bool g_bmod_cstrike; bool g_bmod_dod; @@ -91,7 +91,7 @@ float g_auth_time; #ifdef MEMORY_TEST float g_next_memreport_time; unsigned int g_memreport_count; -CString g_memreport_dir; +String g_memreport_dir; bool g_memreport_enabled; #define MEMREPORT_INTERVAL 300.0f /* 5 mins */ #endif // MEMORY_TEST @@ -218,8 +218,8 @@ int C_Spawn( edict_t *pent ) { g_tasksMngr.registerTimers( &gpGlobals->time, &mp_timelimit->value, &g_game_timeleft ); // ###### Load lang - g_langMngr.Load(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxx/data"))); - g_langMngr.MergeDefinitionFile(build_pathname("%s/langnames.lng", get_localinfo("amxx_datadir", "addons/amxx/data"))); + g_langMngr.LoadCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxx/data"))); +// g_langMngr.Load(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxx/data"))); // ###### Initialize commands prefixes g_commands.registerPrefix( "amx" ); g_commands.registerPrefix( "amxx" ); @@ -402,6 +402,7 @@ void C_ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ) executeForwards(FF_PluginCfg); // ###### Save lang + g_langMngr.SaveCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxx/data"))); g_langMngr.Save(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxx/data"))); // Correct time in Counter-Strike and other mods (except DOD) @@ -461,6 +462,7 @@ void C_ServerDeactivate_Post() { g_vault.clear(); g_xvars.clear(); g_plugins.clear(); + g_langMngr.SaveCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxx/data"))); g_langMngr.Save(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxx/data"))); g_langMngr.Clear(); // last memreport diff --git a/amxmodx/msvc/amxmodx_mm 7.1.vcproj b/amxmodx/msvc/amxmodx_mm 7.1.vcproj index e32f7d72..4d37ccf8 100755 --- a/amxmodx/msvc/amxmodx_mm 7.1.vcproj +++ b/amxmodx/msvc/amxmodx_mm 7.1.vcproj @@ -25,7 +25,7 @@ AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_mm_EXPORTS" BasicRuntimeChecks="3" - RuntimeLibrary="1" + RuntimeLibrary="5" StructMemberAlignment="3" UsePrecompiledHeader="2" PrecompiledHeaderThrough="amxmodx.h" @@ -661,6 +661,9 @@ + + @@ -774,6 +777,12 @@ + + + + @@ -789,6 +798,9 @@ + +