mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 06:15:37 +03:00
New version
This commit is contained in:
parent
7801cde7f0
commit
286a0d0d02
@ -126,12 +126,12 @@ const uint32_t CRCTable[256] = {
|
|||||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
|
||||||
|
|
||||||
uint32_t CLangMngr::CLang::MakeHash(const char *src)
|
uint32_t CLangMngr::CLang::MakeHash(const char *src, bool makeLower)
|
||||||
{
|
{
|
||||||
uint32_t crc = 0xFFFFFFFF;
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
|
|
||||||
while (*src)
|
while (*src)
|
||||||
crc = ((crc>>8)&0xFFFFFFFF)^CRCTable[(crc^*src++)&0xFF];
|
crc = ((crc>>8)&0xFFFFFFFF)^CRCTable[(crc^ (makeLower ? tolower(*src++) : *src++) )&0xFF];
|
||||||
|
|
||||||
return ~crc;
|
return ~crc;
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ void CLangMngr::CLang::LangEntry::SetKey(const char *pKey)
|
|||||||
delete [] m_pKey;
|
delete [] m_pKey;
|
||||||
m_pKey = new char[strlen(pKey)+1];
|
m_pKey = new char[strlen(pKey)+1];
|
||||||
strcpy(m_pKey, pKey);
|
strcpy(m_pKey, pKey);
|
||||||
m_KeyHash = MakeHash(pKey);
|
m_KeyHash = MakeHash(pKey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLangMngr::CLang::LangEntry::SetDef(const char *pDef)
|
void CLangMngr::CLang::LangEntry::SetDef(const char *pDef)
|
||||||
@ -286,7 +286,7 @@ void CLangMngr::CLang::Clear()
|
|||||||
CLangMngr::CLang::LangEntry & CLangMngr::CLang::GetEntry(const char *key)
|
CLangMngr::CLang::LangEntry & CLangMngr::CLang::GetEntry(const char *key)
|
||||||
{
|
{
|
||||||
LookUpVecIter iter;
|
LookUpVecIter iter;
|
||||||
uint32_t hash = MakeHash(key);
|
uint32_t hash = MakeHash(key, true);
|
||||||
for (iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
|
for (iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
|
||||||
if (*iter == hash)
|
if (*iter == hash)
|
||||||
break;
|
break;
|
||||||
@ -317,7 +317,7 @@ void CLangMngr::CLang::Dump()
|
|||||||
|
|
||||||
const char * CLangMngr::CLang::GetDef(const char *key)
|
const char * CLangMngr::CLang::GetDef(const char *key)
|
||||||
{
|
{
|
||||||
uint32_t hash = MakeHash(key);
|
uint32_t hash = MakeHash(key, true);
|
||||||
for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
|
for (LookUpVecIter iter = m_LookUpTable.begin(); iter != m_LookUpTable.end(); ++iter)
|
||||||
if (*iter == hash)
|
if (*iter == hash)
|
||||||
return iter->GetDef();
|
return iter->GetDef();
|
||||||
@ -438,7 +438,7 @@ bool CLangMngr::CLang::Load(FILE *fp)
|
|||||||
char keyBuf[257];
|
char keyBuf[257];
|
||||||
char defBuf[4096];
|
char defBuf[4096];
|
||||||
|
|
||||||
for (int i = 0; i < numOfEntries; ++i)
|
for (unsigned int i = 0; i < numOfEntries; ++i)
|
||||||
{
|
{
|
||||||
uint32_t keyHash, defHash;
|
uint32_t keyHash, defHash;
|
||||||
uint32_t tmp1, tmp2, tmp3;
|
uint32_t tmp1, tmp2, tmp3;
|
||||||
@ -471,10 +471,10 @@ bool CLangMngr::CLang::Load(FILE *fp)
|
|||||||
|
|
||||||
/******** CLangMngr *********/
|
/******** CLangMngr *********/
|
||||||
|
|
||||||
const char *CLangMngr::Format(const char *pKey, ...)
|
const char *CLangMngr::Format(const char *src, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, pKey);
|
va_start(argptr, src);
|
||||||
static char outbuf[4096];
|
static char outbuf[4096];
|
||||||
char *outptr = outbuf;
|
char *outptr = outbuf;
|
||||||
enum State
|
enum State
|
||||||
@ -485,13 +485,13 @@ const char *CLangMngr::Format(const char *pKey, ...)
|
|||||||
|
|
||||||
State curState = S_Normal;
|
State curState = S_Normal;
|
||||||
|
|
||||||
while (*pKey)
|
while (*src)
|
||||||
{
|
{
|
||||||
if (*pKey == '%' && curState == S_Normal)
|
if (*src == '%' && curState == S_Normal)
|
||||||
curState = S_PercentSign;
|
curState = S_PercentSign;
|
||||||
else if (curState == S_PercentSign)
|
else if (curState == S_PercentSign)
|
||||||
{
|
{
|
||||||
switch (*pKey)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
@ -517,6 +517,10 @@ const char *CLangMngr::Format(const char *pKey, ...)
|
|||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
char *langName = va_arg(argptr, char*);
|
char *langName = va_arg(argptr, char*);
|
||||||
|
// Handle player ids (1-32)
|
||||||
|
if ((int)langName >= 1 && (int)langName <= 32)
|
||||||
|
langName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I((int)langName)->pEdict, "_language");
|
||||||
|
|
||||||
char *key = va_arg(argptr, char*);
|
char *key = va_arg(argptr, char*);
|
||||||
const char *def = GetDef(langName, key);
|
const char *def = GetDef(langName, key);
|
||||||
while (*def)
|
while (*def)
|
||||||
@ -556,17 +560,136 @@ const char *CLangMngr::Format(const char *pKey, ...)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
*outptr++= '%';
|
*outptr++= '%';
|
||||||
*outptr++ = *pKey;
|
*outptr++ = *src;
|
||||||
}
|
}
|
||||||
curState = S_Normal;
|
curState = S_Normal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*outptr++ = *pKey;
|
*outptr++ = *src;
|
||||||
++pKey;
|
++src;
|
||||||
}
|
}
|
||||||
|
*outptr++ = 0;
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||||
|
{
|
||||||
|
cell *src = get_amxaddr(amx, params[parm++]);
|
||||||
|
static char outbuf[4096];
|
||||||
|
char *outptr = outbuf;
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
S_Normal,
|
||||||
|
S_PercentSign,
|
||||||
|
};
|
||||||
|
|
||||||
|
State curState = S_Normal;
|
||||||
|
while (*src)
|
||||||
|
{
|
||||||
|
if (*src == '%' && curState == S_Normal)
|
||||||
|
curState = S_PercentSign;
|
||||||
|
else if (curState == S_PercentSign)
|
||||||
|
{
|
||||||
|
switch (*src)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
cell *tmpArg = get_amxaddr(amx, params[parm++]);;
|
||||||
|
while (*tmpArg)
|
||||||
|
*outptr++ = *tmpArg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f':
|
||||||
|
case 'g':
|
||||||
|
{
|
||||||
|
char format[16];
|
||||||
|
format[0] = '%';
|
||||||
|
char *ptr = format+1;
|
||||||
|
while (!isalpha(*ptr++ = *src++))
|
||||||
|
/*nothing*/;
|
||||||
|
--src;
|
||||||
|
*ptr = 0;
|
||||||
|
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'L':
|
||||||
|
{
|
||||||
|
cell langName = params[parm];
|
||||||
|
cell *pLangName = get_amxaddr(amx, params[parm++]);
|
||||||
|
const char *cpLangName=NULL;
|
||||||
|
// Handle player ids (1-32) and server language
|
||||||
|
if (*pLangName == 0)
|
||||||
|
*pLangName = m_CurGlobId;
|
||||||
|
if (*pLangName == -1)
|
||||||
|
cpLangName = g_vault.get("server_language");
|
||||||
|
else if (*pLangName > 1 && *pLangName < 32)
|
||||||
|
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pLangName)->pEdict, "_language");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
cpLangName = get_amxstring(amx, langName, 2, len);
|
||||||
|
}
|
||||||
|
int len;
|
||||||
|
char *key = get_amxstring(amx, params[parm++], 1, len);
|
||||||
|
const char *def = GetDef(cpLangName, key);
|
||||||
|
while (*def)
|
||||||
|
{
|
||||||
|
switch (*def)
|
||||||
|
{
|
||||||
|
case INSERT_NUMBER:
|
||||||
|
{
|
||||||
|
itoa((float)*(REAL*)get_amxaddr(amx, params[parm++]), outptr, 10);
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_STRING:
|
||||||
|
{
|
||||||
|
cell *tmpArg = get_amxaddr(amx, params[parm++]);;
|
||||||
|
while (*tmpArg)
|
||||||
|
*outptr++ = *tmpArg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_FLOAT:
|
||||||
|
{
|
||||||
|
sprintf(outptr, "%f", *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_NEWLINE:
|
||||||
|
*outptr++ = '\n';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*outptr++ = *def;
|
||||||
|
}
|
||||||
|
++def;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
char format[16];
|
||||||
|
format[0] = '%';
|
||||||
|
char *ptr = format+1;
|
||||||
|
while (!isalpha(*ptr++ = *src++))
|
||||||
|
/*nothing*/;
|
||||||
|
--src;
|
||||||
|
*ptr = 0;
|
||||||
|
sprintf(outptr, format, *get_amxaddr(amx, params[parm++]));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curState = S_Normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*outptr++ = *src;
|
||||||
|
++src;
|
||||||
|
}
|
||||||
|
len = outptr - outbuf;
|
||||||
|
*outptr++ = 0;
|
||||||
|
return outbuf;
|
||||||
|
}
|
||||||
|
|
||||||
void CLangMngr::MergeDefinitions(const char *lang, CVector<sKeyDef> &tmpVec)
|
void CLangMngr::MergeDefinitions(const char *lang, CVector<sKeyDef> &tmpVec)
|
||||||
{
|
{
|
||||||
@ -842,4 +965,35 @@ bool CLangMngr::Load(const char *filename)
|
|||||||
void CLangMngr::Clear()
|
void CLangMngr::Clear()
|
||||||
{
|
{
|
||||||
m_Languages.clear();
|
m_Languages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CLangMngr::GetLangsNum()
|
||||||
|
{
|
||||||
|
return m_Languages.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CLangMngr::GetLangName(int langId)
|
||||||
|
{
|
||||||
|
return m_Languages.at(langId).GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CLangMngr::LangExists(const char *langName)
|
||||||
|
{
|
||||||
|
char buf[3] = { 0 };
|
||||||
|
int i = 0;
|
||||||
|
while (buf[i] = tolower(*langName++))
|
||||||
|
{
|
||||||
|
if (++i == 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LangVecIter iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||||
|
if (*iter == buf)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLangMngr::SetDefLang(int id)
|
||||||
|
{
|
||||||
|
m_CurGlobId = id;
|
||||||
}
|
}
|
@ -32,6 +32,8 @@
|
|||||||
#ifndef _INCLUDE_CLANG_H
|
#ifndef _INCLUDE_CLANG_H
|
||||||
#define _INCLUDE_CLANG_H
|
#define _INCLUDE_CLANG_H
|
||||||
|
|
||||||
|
#define LANG_SERVER -1
|
||||||
|
|
||||||
class CLangMngr
|
class CLangMngr
|
||||||
{
|
{
|
||||||
struct sKeyDef
|
struct sKeyDef
|
||||||
@ -61,7 +63,7 @@ class CLangMngr
|
|||||||
bool Load(FILE *fp);
|
bool Load(FILE *fp);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static uint32_t MakeHash(const char *src);
|
static uint32_t MakeHash(const char *src, bool makeLower = false);
|
||||||
|
|
||||||
class LangEntry
|
class LangEntry
|
||||||
{
|
{
|
||||||
@ -107,14 +109,23 @@ class CLangMngr
|
|||||||
|
|
||||||
CLang & GetLang(const char *name);
|
CLang & GetLang(const char *name);
|
||||||
|
|
||||||
void Clear();
|
int m_CurGlobId;
|
||||||
public:
|
public:
|
||||||
int MergeDefinitionFile(const char *file);
|
int MergeDefinitionFile(const char *file);
|
||||||
void Dump();
|
void Dump();
|
||||||
const char *GetDef(const char *langName, const char *key);
|
const char *GetDef(const char *langName, const char *key);
|
||||||
const char *Format(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 Save(const char *filename);
|
||||||
bool Load(const char *filename);
|
bool Load(const char *filename);
|
||||||
|
|
||||||
|
int GetLangsNum();
|
||||||
|
const char *GetLangName(int langId);
|
||||||
|
bool LangExists(const char *langName);
|
||||||
|
|
||||||
|
// 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();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_CLANG_H
|
#endif //_INCLUDE_CLANG_H
|
||||||
|
Loading…
Reference in New Issue
Block a user