added amb1666 - rehaul over the ml api so extensions can easily use translations

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402132
This commit is contained in:
David Anderson
2008-05-10 09:23:55 +00:00
parent 1e70b04f48
commit c7418e70ba
27 changed files with 1060 additions and 227 deletions
+6 -7
View File
@@ -216,15 +216,14 @@ void ChatTriggers::OnSayCommand_Pre()
{
char buffer[128];
/* :TODO: log an error? */
if (g_Translator.CoreTransEx(g_pFloodPhrases,
client,
buffer,
if (!CoreTranslate(
buffer,
sizeof(buffer),
"Flooding the server",
"%T",
2,
NULL,
NULL)
!= Trans_Okay)
"Flooding the server",
&client))
{
UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!");
}
+1 -2
View File
@@ -494,8 +494,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
/* If we got here, the command failed... */
char buffer[128];
if (g_Translator.CoreTrans(client, buffer, sizeof(buffer), "No Access", NULL, NULL)
!= Trans_Okay)
if (!CoreTranslate(buffer, sizeof(buffer), "%T", 1, NULL, "No Access", &client))
{
UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command");
}
+17 -4
View File
@@ -41,6 +41,7 @@
#include "ShareSys.h"
#include "HandleSys.h"
#include "sourcemm_api.h"
#include "Translator.h"
MenuManager g_Menus;
VoteMenuHandler s_VoteHandler;
@@ -585,14 +586,20 @@ skip_search:
{
if (exitBackButton)
{
CorePlayerTranslate(client, text, sizeof(text), "Back", NULL);
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client))
{
UTIL_Format(text, sizeof(text), "Back");
}
dr.style = ITEMDRAW_CONTROL;
position = panel->DrawItem(dr);
slots[position].type = ItemSel_ExitBack;
}
else
{
CorePlayerTranslate(client, text, sizeof(text), "Previous", NULL);
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client))
{
UTIL_Format(text, sizeof(text), "Previous");
}
dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
position = panel->DrawItem(dr);
slots[position].type = ItemSel_Back;
@@ -610,7 +617,10 @@ skip_search:
/* NEXT */
if (displayNext || canDrawDisabled)
{
CorePlayerTranslate(client, text, sizeof(text), "Next", NULL);
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client))
{
UTIL_Format(text, sizeof(text), "Next");
}
dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
position = panel->DrawItem(dr);
slots[position].type = ItemSel_Next;
@@ -638,7 +648,10 @@ skip_search:
/* EXIT */
if (exitButton)
{
CorePlayerTranslate(client, text, sizeof(text), "Exit", NULL);
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client))
{
UTIL_Format(text, sizeof(text), "Exit");
}
dr.style = ITEMDRAW_CONTROL;
position = panel->DrawItem(dr);
slots[position].type = ItemSel_Exit;
+131
View File
@@ -0,0 +1,131 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* 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, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "PhraseCollection.h"
#include "Translator.h"
#include "sm_stringutil.h"
CPhraseCollection::CPhraseCollection()
{
}
CPhraseCollection::~CPhraseCollection()
{
}
void CPhraseCollection::Destroy()
{
delete this;
}
IPhraseFile *CPhraseCollection::AddPhraseFile(const char *filename)
{
size_t i;
unsigned int fid;
IPhraseFile *pFile;
char full_name[PLATFORM_MAX_PATH];
/* No compat shim here. The user should have read the doc. */
UTIL_Format(full_name, sizeof(full_name), "%s.txt", filename);
fid = g_Translator.FindOrAddPhraseFile(full_name);
pFile = g_Translator.GetFileByIndex(fid);
for (i = 0; i < m_Files.size(); i++)
{
if (m_Files[i] == pFile)
{
return pFile;
}
}
m_Files.push_back(pFile);
return pFile;
}
unsigned int CPhraseCollection::GetFileCount()
{
return (unsigned int)m_Files.size();
}
IPhraseFile *CPhraseCollection::GetFile(unsigned int file)
{
if (file >= m_Files.size())
{
return NULL;
}
return m_Files[file];
}
TransError CPhraseCollection::FindTranslation(const char *key, unsigned int langid, Translation *pTrans)
{
size_t i;
for (i = 0; i < m_Files.size(); i++)
{
if (m_Files[i]->GetTranslation(key, langid, pTrans) == Trans_Okay)
{
return Trans_Okay;
}
}
return Trans_BadPhrase;
}
bool CPhraseCollection::FormatString(char *buffer,
size_t maxlength,
const char *format,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase)
{
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
if (arg != numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
return true;
}
+65
View File
@@ -0,0 +1,65 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* 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, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_PHRASECOLLECTION_H_
#define _INCLUDE_SOURCEMOD_PHRASECOLLECTION_H_
#include <string.h>
#include <sh_vector.h>
#include <ITranslator.h>
using namespace SourceHook;
using namespace SourceMod;
class CPhraseCollection : public IPhraseCollection
{
public:
CPhraseCollection();
~CPhraseCollection();
public:
IPhraseFile *AddPhraseFile(const char *filename);
unsigned int GetFileCount();
IPhraseFile *GetFile(unsigned int file);
void Destroy();
TransError FindTranslation(const char *key, unsigned int langid, Translation *pTrans);
bool FormatString(
char *buffer,
size_t maxlength,
const char *format,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase);
private:
CVector<IPhraseFile *> m_Files;
};
#endif //_INCLUDE_SOURCEMOD_PHRASECOLLECTION_H_
+1 -1
View File
@@ -1203,7 +1203,7 @@ CPlayer::CPlayer()
m_bAdminCheckSignalled = false;
m_bIsInKickQueue = false;
m_LastPassword.clear();
m_LangId = LANGUAGE_ENGLISH;
m_LangId = SOURCEMOD_LANGUAGE_ENGLISH;
}
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
+115 -62
View File
@@ -38,9 +38,11 @@
#include "sm_stringutil.h"
#include "sourcemod.h"
#include "PlayerManager.h"
#include "PhraseCollection.h"
#include "ShareSys.h"
Translator g_Translator;
CPhraseFile *g_pCorePhrases = NULL;
IPhraseCollection *g_pCorePhrases = NULL;
unsigned int g_pCorePhraseID = 0;
struct trans_t
@@ -663,7 +665,7 @@ const char *CPhraseFile::GetFilename()
** MAIN TRANSLATOR CODE **
**************************/
Translator::Translator() : m_ServerLang(LANGUAGE_ENGLISH)
Translator::Translator() : m_ServerLang(SOURCEMOD_LANGUAGE_ENGLISH)
{
m_pStringTab = new BaseStringTable(2048);
m_pLCodeLookup = sm_trie_create();
@@ -727,11 +729,15 @@ void Translator::OnSourceModAllInitialized()
{
AddLanguage("en", "English");
unsigned int id;
g_pCorePhrases = CreatePhraseCollection();
g_pCorePhrases->AddPhraseFile("core.phrases");
id = FindOrAddPhraseFile("core.phrases.txt");
g_pCorePhraseID = id;
g_pCorePhrases = GetFileByIndex(id);
g_ShareSys.AddInterface(NULL, this);
}
void Translator::OnSourceModShutdown()
{
g_pCorePhrases->Destroy();
}
bool Translator::GetLanguageByCode(const char *code, unsigned int *index)
@@ -842,7 +848,7 @@ void Translator::RebuildLanguageDatabase(const char *lang_header_file)
g_Logger.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
m_ServerLang = LANGUAGE_ENGLISH;
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
}
m_ServerLang = reinterpret_cast<unsigned int>(serverLang);
@@ -936,61 +942,6 @@ CPhraseFile *Translator::GetFileByIndex(unsigned int index)
return m_Files[index];
}
size_t Translator::Translate(char *buffer, size_t maxlength, void **params, const Translation *pTrans)
{
void *new_params[MAX_TRANSLATE_PARAMS];
/* Rewrite the parameter order */
for (unsigned int i=0; i<pTrans->fmt_count; i++)
{
new_params[i] = params[pTrans->fmt_order[i]];
}
return gnprintf(buffer, maxlength, pTrans->szPhrase, new_params);
}
TransError Translator::CoreTransEx(CPhraseFile *pFile,
int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen)
{
Translation trans;
TransError err;
/* Using server lang temporarily until client lang stuff is implemented */
if ((err = pFile->GetTranslation(phrase, m_ServerLang, &trans)) != Trans_Okay)
{
return err;
}
size_t len = Translate(buffer, maxlength, params, &trans);
if (outlen)
{
*outlen = len;
}
return Trans_Okay;
}
TransError Translator::CoreTrans(int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen)
{
if (!g_pCorePhrases)
{
return Trans_BadPhraseFile;
}
return CoreTransEx(g_pCorePhrases, client, buffer, maxlength, phrase, params, outlen);
}
unsigned int Translator::GetServerLanguage()
{
return m_ServerLang;
@@ -1021,3 +972,105 @@ bool Translator::GetLanguageInfo(unsigned int number, const char **code, const c
return true;
}
const char *Translator::GetInterfaceName()
{
return SMINTERFACE_TRANSLATOR_NAME;
}
unsigned int Translator::GetInterfaceVersion()
{
return SMINTERFACE_TRANSLATOR_VERSION;
}
IPhraseCollection *Translator::CreatePhraseCollection()
{
return new CPhraseCollection();
}
int Translator::SetGlobalTarget(int index)
{
return g_SourceMod.SetGlobalTarget(index);
}
int Translator::GetGlobalTarget() const
{
return g_SourceMod.GetGlobalTarget();
}
bool CoreTranslate(char *buffer,
size_t maxlength,
const char *format,
unsigned int numparams,
size_t *pOutLength,
...)
{
va_list ap;
unsigned int i;
const char *fail_phrase;
void *params[MAX_TRANSLATE_PARAMS];
if (numparams > MAX_TRANSLATE_PARAMS)
{
assert(false);
return false;
}
va_start(ap, pOutLength);
for (i = 0; i < numparams; i++)
{
params[i] = va_arg(ap, void *);
}
va_end(ap);
if (!g_pCorePhrases->FormatString(buffer,
maxlength,
format,
params,
numparams,
pOutLength,
&fail_phrase))
{
if (fail_phrase != NULL)
{
g_Logger.LogError("[SM] Could not find core phrase: %s", fail_phrase);
}
else
{
g_Logger.LogError("[SM] Unknown fatal error while translating a core phrase.");
}
return false;
}
return true;
}
bool Translator::FormatString(char *buffer,
size_t maxlength,
const char *format,
IPhraseCollection *pPhrases,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase)
{
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
if (arg != numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
return true;
}
+37 -35
View File
@@ -38,6 +38,7 @@
#include "sm_globals.h"
#include "sm_memtable.h"
#include "ITextParsers.h"
#include <ITranslator.h>
#define MAX_TRANSLATE_PARAMS 32
#define CORELANG_ENGLISH 0
@@ -60,25 +61,9 @@ struct Language
int m_FullName;
};
struct Translation
{
const char *szPhrase; /**< Translated phrase. */
unsigned int fmt_count; /**< Number of format parameters. */
int *fmt_order; /**< Format phrase order. */
};
#define LANGUAGE_ENGLISH 0
enum TransError
{
Trans_Okay = 0,
Trans_BadLanguage = 1,
Trans_BadPhrase = 2,
Trans_BadPhraseLanguage = 3,
Trans_BadPhraseFile = 4,
};
class CPhraseFile : public ITextListener_SMC
class CPhraseFile :
public ITextListener_SMC,
public IPhraseFile
{
public:
CPhraseFile(Translator *pTranslator, const char *file);
@@ -112,7 +97,8 @@ private:
class Translator :
public ITextListener_SMC,
public SMGlobalClass
public SMGlobalClass,
public ITranslator
{
public:
Translator();
@@ -125,6 +111,7 @@ public: // SMGlobalClass
size_t maxlength);
void OnSourceModAllInitialized();
void OnSourceModLevelChange(const char *mapName);
void OnSourceModShutdown();
public: // ITextListener_SMC
void ReadSMC_ParseStart();
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
@@ -138,23 +125,30 @@ public:
bool GetLanguageInfo(unsigned int number, const char **code, const char **name);
bool GetLanguageByCode(const char *code, unsigned int *index);
bool GetLanguageByName(const char *name, unsigned int *index);
size_t Translate(char *buffer, size_t maxlength, void **params, const Translation *pTrans);
CPhraseFile *GetFileByIndex(unsigned int index);
TransError CoreTransEx(CPhraseFile *pFile,
int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen=NULL);
TransError CoreTrans(int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen=NULL);
public: //ITranslator
unsigned int GetServerLanguage();
unsigned int GetClientLanguage(int client);
const char *GetInterfaceName();
unsigned int GetInterfaceVersion();
IPhraseCollection *CreatePhraseCollection();
int SetGlobalTarget(int index);
int GetGlobalTarget() const;
size_t FormatString(
char *buffer,
size_t maxlength,
SourcePawn::IPluginContext *pContext,
const cell_t *params,
unsigned int param);
bool FormatString(
char *buffer,
size_t maxlength,
const char *format,
IPhraseCollection *pPhrases,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase);
private:
bool AddLanguage(const char *langcode, const char *description);
private:
@@ -168,7 +162,15 @@ private:
char m_InitialLang[3];
};
extern CPhraseFile *g_pCorePhrases;
/* Nice little wrapper to handle error logging and whatnot */
bool CoreTranslate(char *buffer,
size_t maxlength,
const char *format,
unsigned int numparams,
size_t *pOutLength,
...);
extern IPhraseCollection *g_pCorePhrases;
extern unsigned int g_pCorePhraseID;
extern Translator g_Translator;
+12
View File
@@ -901,6 +901,10 @@
RelativePath="..\MenuVoting.cpp"
>
</File>
<File
RelativePath="..\PhraseCollection.cpp"
>
</File>
<File
RelativePath="..\PlayerManager.cpp"
>
@@ -1063,6 +1067,10 @@
RelativePath="..\MenuVoting.h"
>
</File>
<File
RelativePath="..\PhraseCollection.h"
>
</File>
<File
RelativePath="..\PlayerManager.h"
>
@@ -1232,6 +1240,10 @@
RelativePath="..\..\public\ITimerSystem.h"
>
</File>
<File
RelativePath="..\..\public\ITranslator.h"
>
</File>
<File
RelativePath="..\..\public\IUserMessages.h"
>
+262 -55
View File
@@ -50,43 +50,6 @@
return 0; \
}
size_t CorePlayerTranslate(int client, char *buffer, size_t maxlength, const char *phrase, void **params)
{
Translation pTrans;
TransError err;
err = g_pCorePhrases->GetTranslation(phrase, g_Translator.GetClientLanguage(client), &pTrans);
if (err != Trans_Okay)
{
err = g_pCorePhrases->GetTranslation(phrase, g_Translator.GetServerLanguage(), &pTrans);
if (err != Trans_Okay && g_Translator.GetServerLanguage() != CORELANG_ENGLISH)
{
err = g_pCorePhrases->GetTranslation(phrase, CORELANG_ENGLISH, &pTrans);
}
}
if (err != Trans_Okay)
{
return UTIL_Format(buffer, maxlength, "%s", phrase);
}
return g_Translator.Translate(buffer, maxlength, params, &pTrans);
}
inline bool TryTranslation(CPlugin *pl, const char *key, unsigned int langid, unsigned int langcount, Translation *pTrans)
{
TransError err = Trans_BadLanguage;
CPhraseFile *phrfl;
for (size_t i=0; i<langcount && err!=Trans_Okay; i++)
{
phrfl = g_Translator.GetFileByIndex(pl->GetLangFileByIndex(i));
err = phrfl->GetTranslation(key, langid, pTrans);
}
return (err == Trans_Okay) ? true : false;
}
inline void ReorderTranslationParams(const Translation *pTrans, cell_t *params)
{
cell_t new_params[MAX_TRANSLATE_PARAMS];
@@ -110,11 +73,13 @@ size_t Translate(char *buffer,
*error = false;
Translation pTrans;
CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext());
size_t langcount = pl->GetLangFileCount();
unsigned int max_params = 0;
IPhraseCollection *pPhrases;
pPhrases = pl->GetPhrases();
try_serverlang:
if (target == LANG_SERVER)
if (target == SOURCEMOD_SERVER_LANGUAGE)
{
langid = g_Translator.GetServerLanguage();
}
@@ -128,16 +93,16 @@ try_serverlang:
goto error_out;
}
if (!TryTranslation(pl, key, langid, langcount, &pTrans))
if (pPhrases->FindTranslation(key, langid, &pTrans) != Trans_Okay)
{
if (target != LANG_SERVER && langid != g_Translator.GetServerLanguage())
if (target != SOURCEMOD_SERVER_LANGUAGE && langid != g_Translator.GetServerLanguage())
{
target = LANG_SERVER;
target = SOURCEMOD_SERVER_LANGUAGE;
goto try_serverlang;
}
else if (langid != LANGUAGE_ENGLISH)
else if (langid != SOURCEMOD_LANGUAGE_ENGLISH)
{
if (!TryTranslation(pl, key, LANGUAGE_ENGLISH, langcount, &pTrans))
if (!pPhrases->FindTranslation(key, SOURCEMOD_LANGUAGE_ENGLISH, &pTrans))
{
pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Language phrase \"%s\" not found", key);
goto error_out;
@@ -575,11 +540,32 @@ void AddHex(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags
*buf_p = buf;
}
size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args)
bool gnprintf(char *buffer,
size_t maxlen,
const char *format,
IPhraseCollection *pPhrases,
void **params,
unsigned int numparams,
unsigned int &curparam,
size_t *pOutLength,
const char **pFailPhrase)
{
if (!buffer || !maxlen)
{
return 0;
if (pOutLength != NULL)
{
*pOutLength = 0;
}
return true;
}
if (numparams > MAX_TRANSLATE_PARAMS)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
int arg = 0;
@@ -668,7 +654,16 @@ reswitch:
{
goto done;
}
char *c = (char *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
char *c = (char *)params[curparam];
curparam++;
*buf_p++ = *c;
llen--;
arg++;
@@ -676,7 +671,16 @@ reswitch:
}
case 'b':
{
int *value = (int *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
int *value = (int *)params[curparam];
curparam++;
AddBinary(&buf_p, llen, *value, width, flags);
arg++;
break;
@@ -684,35 +688,224 @@ reswitch:
case 'd':
case 'i':
{
int *value = (int *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
int *value = (int *)params[curparam];
curparam++;
AddInt(&buf_p, llen, *value, width, flags);
arg++;
break;
}
case 'u':
{
unsigned int *value = (unsigned int *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
unsigned int *value = (unsigned int *)params[curparam];
curparam++;
AddUInt(&buf_p, llen, *value, width, flags);
arg++;
break;
}
case 'f':
{
float *value = (float *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
float *value = (float *)params[curparam];
curparam++;
AddFloat(&buf_p, llen, *value, width, prec, flags);
arg++;
break;
}
case 's':
{
const char *str = (const char *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
const char *str = (const char *)params[curparam];
curparam++;
AddString(&buf_p, llen, str, width, prec);
arg++;
break;
}
case 'T':
case 't':
{
int target;
const char *key;
size_t out_length;
Translation trans;
unsigned int lang_id;
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
key = (const char *)(params[curparam]);
curparam++;
if (ch == 'T')
{
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
target = *((int *)(params[curparam]));
curparam++;
}
else
{
target = g_Translator.GetGlobalTarget();
}
try_again:
if (target == SOURCEMOD_SERVER_LANGUAGE)
{
lang_id = g_Translator.GetServerLanguage();
}
else if (target >= 1 && target <= g_Players.GetMaxClients())
{
lang_id = g_Translator.GetClientLanguage(target);
}
else
{
lang_id = g_Translator.GetServerLanguage();
}
if (pPhrases == NULL)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = key;
}
return false;
}
if (pPhrases->FindTranslation(key, lang_id, &trans) != Trans_Okay)
{
if (target != SOURCEMOD_SERVER_LANGUAGE && lang_id != g_Translator.GetServerLanguage())
{
target = SOURCEMOD_SERVER_LANGUAGE;
goto try_again;
}
else if (lang_id != SOURCEMOD_LANGUAGE_ENGLISH)
{
if (pPhrases->FindTranslation(key, SOURCEMOD_LANGUAGE_ENGLISH, &trans) != Trans_Okay)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = key;
}
return false;
}
}
else
{
if (pFailPhrase != NULL)
{
*pFailPhrase = key;
}
return false;
}
}
if (trans.fmt_count)
{
unsigned int i;
void *new_params[MAX_TRANSLATE_PARAMS];
if (curparam + trans.fmt_count > numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
/* Copy the array and re-order the stack */
memcpy(new_params, params, sizeof(void *) * numparams);
for (i = 0; i < trans.fmt_count; i++)
{
new_params[i] = const_cast<void *>(params[curparam + trans.fmt_order[i]]);
}
if (!gnprintf(buf_p,
llen,
trans.szPhrase,
pPhrases,
new_params,
numparams,
curparam,
&out_length,
pFailPhrase))
{
return false;
}
}
else
{
if (!gnprintf(buf_p,
llen,
trans.szPhrase,
pPhrases,
params,
numparams,
curparam,
&out_length,
pFailPhrase))
{
return false;
}
}
buf_p += out_length;
llen -= out_length;
break;
}
case 'X':
{
unsigned int *value = (unsigned int *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
unsigned int *value = (unsigned int *)params[curparam];
curparam++;
flags |= UPPERDIGITS;
AddHex(&buf_p, llen, *value, width, flags);
arg++;
@@ -720,7 +913,16 @@ reswitch:
}
case 'x':
{
unsigned int *value = (unsigned int *)args[arg];
if (curparam >= numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
unsigned int *value = (unsigned int *)params[curparam];
curparam++;
AddHex(&buf_p, llen, *value, width, flags);
arg++;
break;
@@ -761,7 +963,12 @@ reswitch:
done:
*buf_p = '\0';
return (maxlen - llen - 1);
if (pOutLength != NULL)
{
*pOutLength = (maxlen - llen - 1);
}
return true;
}
size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param)
+13 -6
View File
@@ -33,23 +33,30 @@
#define _INCLUDE_SOURCEMOD_STRINGUTIL_H_
#include <math.h>
#include "sp_vm_api.h"
#include "sp_typeutil.h"
#include <sp_vm_api.h>
#include <sp_typeutil.h>
#include <ITranslator.h>
using namespace SourcePawn;
#define LANG_SERVER 0
using namespace SourceMod;
#define IS_STR_FILLED(var) (var[0] != '\0')
size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param);
const char *stristr(const char *str, const char *substr);
unsigned int strncopy(char *dest, const char *src, size_t count);
size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args);
bool gnprintf(char *buffer,
size_t maxlen,
const char *format,
IPhraseCollection *pPhrases,
void **params,
unsigned int numparams,
unsigned int &curparam,
size_t *pOutLength,
const char **pFailPhrase);
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap);
char *sm_strdup(const char *str);
size_t CorePlayerTranslate(int client, char *buffer, size_t maxlength, const char *phrase, void **params);
unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace);
char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen);
char *UTIL_TrimWhitespace(char *str, size_t &len);
+2 -2
View File
@@ -828,7 +828,7 @@ static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
@@ -849,7 +849,7 @@ static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer)-2, pContext, params, 1);
+4 -4
View File
@@ -126,7 +126,7 @@ static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
{
char buffer[512];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
@@ -502,7 +502,7 @@ static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params)
static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params)
{
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
@@ -532,7 +532,7 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
@@ -565,7 +565,7 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
+1 -1
View File
@@ -136,7 +136,7 @@ static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Not called from inside a native function");
}
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[512];
+5 -5
View File
@@ -568,7 +568,7 @@ static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
@@ -594,7 +594,7 @@ static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
@@ -612,7 +612,7 @@ static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
@@ -667,7 +667,7 @@ static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
@@ -698,7 +698,7 @@ static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
+12 -11
View File
@@ -37,24 +37,25 @@
static cell_t sm_LoadTranslations(IPluginContext *pCtx, const cell_t *params)
{
char *filename;
unsigned int index;
char *filename, *ext;
char buffer[PLATFORM_MAX_PATH];
CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext());
pCtx->LocalToString(params[1], &filename);
UTIL_Format(buffer, sizeof(buffer), "%s", filename);
/* Check if there is no extension */
const char *ext = g_LibSys.GetFileExtension(filename);
if (!ext || (strcmp(ext, "cfg") && strcmp(ext, "txt")))
/* Make sure there is no extension */
if ((ext = strstr(buffer, ".txt")) != NULL
|| (ext = strstr(buffer, ".cfg")) != NULL)
{
/* Append one */
static char new_file[PLATFORM_MAX_PATH];
UTIL_Format(new_file, sizeof(new_file), "%s.txt", filename);
filename = new_file;
/* Simple heuristic -- just see if it's at the end and terminate if so */
if (ext - buffer == strlen(buffer) - 4)
{
*ext = '\0';
}
}
index = g_Translator.FindOrAddPhraseFile(filename);
pl->AddLangFile(index);
pl->GetPhrases()->AddPhraseFile(buffer);
return 1;
}
+1 -1
View File
@@ -838,7 +838,7 @@ static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
+2 -2
View File
@@ -928,7 +928,7 @@ static cell_t _ShowActivity(IPluginContext *pContext,
}
else
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
@@ -1065,7 +1065,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext,
}
else
{
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
+10 -15
View File
@@ -67,6 +67,7 @@ CPlugin::CPlugin(const char *file)
m_FakeNativesMissing = false;
m_LibraryMissing = false;
m_bGotAllLoaded = false;
m_pPhrases = g_Translator.CreatePhraseCollection();
}
CPlugin::~CPlugin()
@@ -111,6 +112,11 @@ CPlugin::~CPlugin()
delete m_configs[i];
}
m_configs.clear();
if (m_pPhrases != NULL)
{
m_pPhrases->Destroy();
m_pPhrases = NULL;
}
}
void CPlugin::InitIdentity()
@@ -128,7 +134,6 @@ unsigned int CPlugin::CalcMemUsage()
unsigned int base_size =
sizeof(CPlugin)
+ sizeof(IdentityToken_t)
+ (m_PhraseFiles.size() * sizeof(unsigned int))
+ (m_dependents.size() * sizeof(CPlugin *))
+ (m_dependsOn.size() * sizeof(CPlugin *))
+ (m_fakeNatives.size() * (sizeof(FakeNative *) + sizeof(FakeNative)))
@@ -710,19 +715,9 @@ void CPlugin::SetTimeStamp(time_t t)
m_LastAccess = t;
}
void CPlugin::AddLangFile(unsigned int index)
IPhraseCollection *CPlugin::GetPhrases()
{
m_PhraseFiles.push_back(index);
}
size_t CPlugin::GetLangFileCount()
{
return m_PhraseFiles.size();
}
unsigned int CPlugin::GetLangFileByIndex(unsigned int index)
{
return m_PhraseFiles.at(index);
return m_pPhrases;
}
void CPlugin::DependencyDropped(CPlugin *pOwner)
@@ -1488,8 +1483,8 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
OnLibraryAction((*s_iter).c_str(), true, false);
}
/* Finally, add the core language file */
pPlugin->AddLangFile(g_pCorePhraseID);
/* :TODO: optimize? does this even matter? */
pPlugin->GetPhrases()->AddPhraseFile("core.phrases");
return true;
}
+4 -13
View File
@@ -53,6 +53,7 @@
#else
#include "convar_sm.h"
#endif
#include "ITranslator.h"
using namespace SourceHook;
@@ -244,19 +245,9 @@ public:
bool IsRunnable();
/**
* Adds a language file index to the plugin's list.
* Get languages info.
*/
void AddLangFile(unsigned int index);
/**
* Get language file count for this plugin.
*/
size_t GetLangFileCount();
/**
* Get language file index based on the vector index.
*/
unsigned int GetLangFileByIndex(unsigned int index);
IPhraseCollection *GetPhrases();
public:
/**
* Returns the modification time during last plugin load.
@@ -300,7 +291,7 @@ private:
IdentityToken_t *m_ident;
Handle_t m_handle;
bool m_WasRunning;
CVector<unsigned int> m_PhraseFiles;
IPhraseCollection *m_pPhrases;
List<CPlugin *> m_dependents;
List<CPlugin *> m_dependsOn;
List<FakeNative *> m_fakeNatives;