Merge pull request #320 from Arkshine/fix/l-translation-specifier

Fix incorrect translation language for %l format identifier
This commit is contained in:
Vincent Herbet 2015-12-24 15:54:28 +01:00
commit ac37f8053b
3 changed files with 71 additions and 43 deletions

View File

@ -4456,7 +4456,7 @@ static cell AMX_NATIVE_CALL LookupLangKey(AMX *amx, cell *params)
{ {
int len; int len;
char *key=get_amxstring(amx,params[3],0,len); char *key=get_amxstring(amx,params[3],0,len);
const char *def=translate(amx,params[4],key); const char *def=translate(amx, playerlang(params[4]),key);
if (def==NULL) if (def==NULL)
{ {

View File

@ -44,60 +44,78 @@ template size_t atcprintf<char, char>(char *, size_t, const char *, AMX *, cell
THash<ke::AString, lang_err> BadLang_Table; THash<ke::AString, lang_err> BadLang_Table;
static cvar_t *amx_mldebug = NULL; static cvar_t *amx_mldebug = nullptr;
static cvar_t *amx_cl_langs = NULL; static cvar_t *amx_cl_langs = nullptr;
const char *translate(AMX *amx, cell amxaddr, const char *key) const char *playerlang(const cell index)
{ {
const char *pLangName = NULL; const char *pLangName = nullptr;
const char *def = NULL;
int status; if (index == LANG_PLAYER)
cell *addr = get_amxaddr(amx, amxaddr);
char name[4];
if (addr[0] == LANG_PLAYER)
{ {
if (!amx_cl_langs) if (!amx_cl_langs)
{
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages"); amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 ) }
if (static_cast<int>(amx_cl_langs->value) == 0)
{ {
pLangName = amxmodx_language->string; pLangName = amxmodx_language->string;
} else { }
else
{
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang"); pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang");
} }
} else if (addr[0] == LANG_SERVER) { }
pLangName = amxmodx_language->string; else if (index == LANG_SERVER)
} else if (addr[0] >= 1 && addr[0] <= gpGlobals->maxClients) {
if (!amx_cl_langs)
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 )
{ {
pLangName = amxmodx_language->string; pLangName = amxmodx_language->string;
} else {
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(addr[0])->pEdict, "lang");
} }
} else { else if (index >= 1 && index <= gpGlobals->maxClients)
get_amxstring_r(amx, amxaddr, name, 3); {
pLangName = name; if (!amx_cl_langs)
{
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
} }
if (static_cast<int>(amx_cl_langs->value) == 0)
{
pLangName = amxmodx_language->string;
}
else
{
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(index)->pEdict, "lang");
}
}
return pLangName;
}
const char *translate(AMX *amx, const char *lang, const char *key)
{
auto pLangName = lang;
int status;
if (!pLangName || !isalpha(pLangName[0])) if (!pLangName || !isalpha(pLangName[0]))
{ {
pLangName = amxmodx_language->string; pLangName = amxmodx_language->string;
} }
//next parameter! auto def = g_langMngr.GetDef(pLangName, key, status);
def = g_langMngr.GetDef(pLangName, key, status);
if (!amx_mldebug) if (!amx_mldebug)
{
amx_mldebug = CVAR_GET_POINTER("amx_mldebug"); amx_mldebug = CVAR_GET_POINTER("amx_mldebug");
}
bool debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0')); auto debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0'));
if (debug) if (debug)
{ {
int debug_status; int debug_status;
bool validlang = true; auto validlang = true;
const char *testlang = amx_mldebug->string; auto testlang = amx_mldebug->string;
if (!g_langMngr.LangExists(testlang)) if (!g_langMngr.LangExists(testlang))
{ {
AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang); AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang);
@ -107,16 +125,18 @@ const char *translate(AMX *amx, cell amxaddr, const char *key)
g_langMngr.GetDef(testlang, key, debug_status); g_langMngr.GetDef(testlang, key, debug_status);
if (validlang && debug_status == ERR_BADKEY) if (validlang && debug_status == ERR_BADKEY)
{
AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx)); AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx));
} }
}
if (def == NULL) if (!def)
{ {
if (debug && status == ERR_BADLANG) if (debug && status == ERR_BADLANG)
{ {
ke::AString lang(pLangName); ke::AString langName(pLangName);
lang_err &err = BadLang_Table.AltFindOrInsert(ke::Move(lang)); auto &err = BadLang_Table.AltFindOrInsert(ke::Move(langName));
if (err.last + 120.0f < gpGlobals->time) if (err.last + 120.0f < gpGlobals->time)
{ {
@ -125,12 +145,16 @@ const char *translate(AMX *amx, cell amxaddr, const char *key)
} }
} }
if (addr[0] != LANG_SERVER) if (strcmp(pLangName, amxmodx_language->string) != 0)
{
def = g_langMngr.GetDef(amxmodx_language->string, key, status); def = g_langMngr.GetDef(amxmodx_language->string, key, status);
}
if (!def && (strcmp(pLangName, "en") != 0 && strcmp(amxmodx_language->string, "en") != 0)) if (!def && (strcmp(pLangName, "en") != 0 && strcmp(amxmodx_language->string, "en") != 0))
{
def = g_langMngr.GetDef("en", key, status); def = g_langMngr.GetDef("en", key, status);
} }
}
return def; return def;
} }
@ -656,20 +680,23 @@ reswitch:
case 'L': case 'L':
case 'l': case 'l':
{ {
cell target; const char *lang;
int len;
if (ch == 'L') if (ch == 'L')
{ {
CHECK_ARGS(1); CHECK_ARGS(1);
target = params[arg++]; auto currParam = params[arg++];
lang = playerlang(*get_amxaddr(amx, currParam));
if (!lang)
lang = get_amxstring(amx, currParam, 4, len);
} }
else else
{ {
CHECK_ARGS(0); CHECK_ARGS(0);
target = g_langMngr.GetDefLang(); lang = playerlang(g_langMngr.GetDefLang());
} }
int len;
const char *key = get_amxstring(amx, params[arg++], 3, len); const char *key = get_amxstring(amx, params[arg++], 3, len);
const char *def = translate(amx, target, key); const char *def = translate(amx, lang, key);
if (!def) if (!def)
{ {
static char buf[255]; static char buf[255];

View File

@ -14,6 +14,7 @@
template <typename D, typename S> template <typename D, typename S>
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param); size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
const char *translate(AMX *amx, cell amxaddr, const char *key); const char *playerlang(const cell index);
const char *translate(AMX *amx, const char *lang, const char *key);
#endif //_INCLUDE_FORMATTING_H #endif //_INCLUDE_FORMATTING_H