From 9137e92c09d32ea4041abb4a36cebcfbe26db880 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 14 May 2010 19:43:53 -0700 Subject: [PATCH] Move translator from logic to core (bug 4406 part 6, r=ds). --HG-- rename : core/PhraseCollection.cpp => core/logic/PhraseCollection.cpp rename : core/PhraseCollection.h => core/logic/PhraseCollection.h rename : core/Translator.cpp => core/logic/Translator.cpp rename : core/Translator.h => core/logic/Translator.h rename : core/sm_memtable.h => core/logic/sm_memtable.h rename : core/smn_lang.cpp => core/logic/smn_lang.cpp --- core/AMBuilder | 3 - core/ChatTriggers.cpp | 15 +-- core/ConCmdManager.cpp | 4 +- core/Makefile | 6 +- core/MenuManager.cpp | 12 +- core/MenuStyle_Valve.cpp | 1 - core/MenuVoting.cpp | 15 ++- core/PlayerManager.cpp | 7 +- core/PluginSys.cpp | 4 +- core/logic/AMBuilder | 3 + core/logic/Makefile | 3 + core/{ => logic}/PhraseCollection.cpp | 6 +- core/{ => logic}/PhraseCollection.h | 0 core/{ => logic}/Translator.cpp | 148 ++++++++++------------- core/{ => logic}/Translator.h | 12 +- core/logic/common_logic.cpp | 11 +- core/logic/intercom.h | 9 +- core/logic/sm_memtable.h | 163 ++++++++++++++++++++++++++ core/{ => logic}/smn_lang.cpp | 16 +-- core/logic/stringutil.cpp | 17 +++ core/logic/stringutil.h | 1 + core/logic_bridge.cpp | 3 + core/logic_bridge.h | 1 + core/sm_stringutil.cpp | 18 +-- core/sourcemod.cpp | 1 - public/IPluginSys.h | 11 +- public/ITranslator.h | 21 +++- 27 files changed, 353 insertions(+), 158 deletions(-) rename core/{ => logic}/PhraseCollection.cpp (90%) rename core/{ => logic}/PhraseCollection.h (100%) rename core/{ => logic}/Translator.cpp (81%) rename core/{ => logic}/Translator.h (94%) create mode 100644 core/logic/sm_memtable.h rename core/{ => logic}/smn_lang.cpp (88%) diff --git a/core/AMBuilder b/core/AMBuilder index 412e990be..82ed608a9 100644 --- a/core/AMBuilder +++ b/core/AMBuilder @@ -44,7 +44,6 @@ for i in SM.sdkInfo: 'smn_profiler.cpp', 'ConCmdManager.cpp', 'HandleSys.cpp', - 'PhraseCollection.cpp', 'ConVarManager.cpp', 'LibrarySys.cpp', 'PlayerManager.cpp', @@ -56,7 +55,6 @@ for i in SM.sdkInfo: 'PluginInfoDatabase.cpp', 'smn_bitbuffer.cpp', 'smn_halflife.cpp', - 'Translator.cpp', 'PluginSys.cpp', 'smn_console.cpp', 'smn_handles.cpp', @@ -76,7 +74,6 @@ for i in SM.sdkInfo: 'MenuStyle_Radio.cpp', 'sm_autonatives.cpp', 'smn_datapacks.cpp', - 'smn_lang.cpp', 'sm_srvcmds.cpp', 'ConsoleDetours.cpp' ] diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp index 9c9ad4f82..4f1db6d89 100644 --- a/core/ChatTriggers.cpp +++ b/core/ChatTriggers.cpp @@ -34,8 +34,8 @@ #include "sm_stringutil.h" #include "ConCmdManager.h" #include "PlayerManager.h" -#include "Translator.h" #include "HalfLife2.h" +#include "logic_bridge.h" /* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does. * While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one @@ -113,7 +113,7 @@ void ChatTriggers::OnSourceModAllInitialized() void ChatTriggers::OnSourceModAllInitialized_Post() { - g_pCorePhrases->AddPhraseFile("antiflood.phrases"); + logicore.AddCorePhraseFile("antiflood.phrases"); } void ChatTriggers::OnSourceModGameInitialized() @@ -189,17 +189,8 @@ void ChatTriggers::OnSayCommand_Pre() { char buffer[128]; - if (!CoreTranslate( - buffer, - sizeof(buffer), - "%T", - 2, - NULL, - "Flooding the server", - &client)) - { + if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "Flooding the server", &client)) UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!"); - } /* :TODO: we should probably kick people who spam too much. */ diff --git a/core/ConCmdManager.cpp b/core/ConCmdManager.cpp index 119f2fd10..320c8b6fe 100644 --- a/core/ConCmdManager.cpp +++ b/core/ConCmdManager.cpp @@ -34,9 +34,9 @@ #include "AdminCache.h" #include "sm_stringutil.h" #include "PlayerManager.h" -#include "Translator.h" #include "HalfLife2.h" #include "ChatTriggers.h" +#include "logic_bridge.h" ConCmdManager g_ConCmds; @@ -540,7 +540,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi /* If we got here, the command failed... */ char buffer[128]; - if (!CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client)) + if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client)) { UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command"); } diff --git a/core/Makefile b/core/Makefile index 22fcbb799..4fe69aedd 100644 --- a/core/Makefile +++ b/core/Makefile @@ -16,17 +16,17 @@ MMSOURCE17 = ../../mmsource-central OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreConfig.cpp \ Database.cpp DebugReporter.cpp EventManager.cpp GameConfigs.cpp HalfLife2.cpp Logger.cpp \ - PlayerManager.cpp TimerSys.cpp Translator.cpp UserMessages.cpp \ + PlayerManager.cpp TimerSys.cpp UserMessages.cpp \ sm_autonatives.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \ sourcemm_api.cpp sourcemod.cpp MenuStyle_Base.cpp MenuStyle_Valve.cpp MenuManager.cpp \ MenuStyle_Radio.cpp ChatTriggers.cpp ADTFactory.cpp MenuVoting.cpp \ - frame_hooks.cpp concmd_cleaner.cpp PhraseCollection.cpp NextMap.cpp \ + frame_hooks.cpp concmd_cleaner.cpp NextMap.cpp \ NativeOwner.cpp logic_bridge.cpp ConsoleDetours.cpp OBJECTS += smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \ smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \ smn_filesystem.cpp smn_gameconfigs.cpp smn_halflife.cpp \ smn_handles.cpp smn_keyvalues.cpp \ - smn_lang.cpp smn_player.cpp smn_string.cpp \ + smn_player.cpp smn_string.cpp \ smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp \ smn_hudtext.cpp smn_nextmap.cpp OBJECTS += ExtensionSys.cpp \ diff --git a/core/MenuManager.cpp b/core/MenuManager.cpp index f5eb9d87f..ab92280e3 100644 --- a/core/MenuManager.cpp +++ b/core/MenuManager.cpp @@ -41,7 +41,7 @@ #include "ShareSys.h" #include "HandleSys.h" #include "sourcemm_api.h" -#include "Translator.h" +#include "logic_bridge.h" MenuManager g_Menus; VoteMenuHandler s_VoteHandler; @@ -446,7 +446,7 @@ skip_search: if (novoteButton) { char text[50]; - if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "No Vote", &client)) + if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "No Vote", &client)) { UTIL_Format(text, sizeof(text), "No Vote"); } @@ -606,7 +606,7 @@ skip_search: { if (exitBackButton) { - if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client)) + if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client)) { UTIL_Format(text, sizeof(text), "Back"); } @@ -616,7 +616,7 @@ skip_search: } else { - if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client)) + if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client)) { UTIL_Format(text, sizeof(text), "Previous"); } @@ -637,7 +637,7 @@ skip_search: /* NEXT */ if (displayNext || canDrawDisabled) { - if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client)) + if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client)) { UTIL_Format(text, sizeof(text), "Next"); } @@ -668,7 +668,7 @@ skip_search: /* EXIT */ if (exitButton) { - if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client)) + if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client)) { UTIL_Format(text, sizeof(text), "Exit"); } diff --git a/core/MenuStyle_Valve.cpp b/core/MenuStyle_Valve.cpp index 12edf620c..5324d2be2 100644 --- a/core/MenuStyle_Valve.cpp +++ b/core/MenuStyle_Valve.cpp @@ -32,7 +32,6 @@ #include "sm_stringutil.h" #include "PlayerManager.h" #include "MenuStyle_Valve.h" -#include "Translator.h" #include "PlayerManager.h" #include "ConCmdManager.h" diff --git a/core/MenuVoting.cpp b/core/MenuVoting.cpp index a8641b5e7..ddd6d1fbb 100644 --- a/core/MenuVoting.cpp +++ b/core/MenuVoting.cpp @@ -39,7 +39,8 @@ #include #include #include -#include +#include +#include "logic_bridge.h" float g_next_vote = 0.0f; @@ -526,7 +527,8 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite if (sm_vote_console.GetBool()) { int target = SOURCEMOD_SERVER_LANGUAGE; - CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", &target, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); + logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", + &target, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); Engine_LogPrintWrapper(buffer); } @@ -542,11 +544,13 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite { if (m_Revoting[client]) { - CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Changed Vote", &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); + logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Changed Vote", + &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); } else { - CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); + logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", + &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display); } if (sm_vote_chat.GetBool()) @@ -634,7 +638,8 @@ void VoteMenuHandler::DrawHintProgress() { if (g_Players.GetPlayerByIndex(i)->IsInGame()) { - CoreTranslate(buffer, sizeof(buffer), "%T%s", 6, NULL, "Vote Count", &i, &m_NumVotes, &m_TotalClients, &iTimeRemaining, &m_leaderList); + logicore.CoreTranslate(buffer, sizeof(buffer), "%T%s", 6, NULL, "Vote Count", + &i, &m_NumVotes, &m_TotalClients, &iTimeRemaining, &m_leaderList); g_HL2.HintTextMsg(i, buffer); } } diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 159a39ff4..03ef9de52 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -39,7 +39,6 @@ #include "sm_stringutil.h" #include "CoreConfig.h" #include "TimerSys.h" -#include "Translator.h" #include "Logger.h" #include "ChatTriggers.h" #include "HalfLife2.h" @@ -549,9 +548,9 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language"))) { unsigned int langid; - pPlayer->m_LangId = (g_Translator.GetLanguageByName(name, &langid)) ? langid : g_Translator.GetServerLanguage(); + pPlayer->m_LangId = (translator->GetLanguageByName(name, &langid)) ? langid : translator->GetServerLanguage(); } else { - pPlayer->m_LangId = g_Translator.GetServerLanguage(); + pPlayer->m_LangId = translator->GetServerLanguage(); } } @@ -1456,7 +1455,7 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) m_Ip.assign(ip); m_pEdict = pEntity; m_iIndex = IndexOfEdict(pEntity); - m_LangId = g_Translator.GetServerLanguage(); + m_LangId = translator->GetServerLanguage(); m_Serial.bits.index = m_iIndex; m_Serial.bits.serial = g_PlayerSerialCount++; diff --git a/core/PluginSys.cpp b/core/PluginSys.cpp index 6ee5786e4..316c8026c 100644 --- a/core/PluginSys.cpp +++ b/core/PluginSys.cpp @@ -44,7 +44,7 @@ #include "ConCmdManager.h" #include "PlayerManager.h" #include "CoreConfig.h" -#include "Translator.h" +#include "logic_bridge.h" CPluginManager g_PluginSys; HandleType_t g_PluginType = 0; @@ -67,7 +67,7 @@ CPlugin::CPlugin(const char *file) m_FakeNativesMissing = false; m_LibraryMissing = false; m_bGotAllLoaded = false; - m_pPhrases = g_Translator.CreatePhraseCollection(); + m_pPhrases = translator->CreatePhraseCollection(); m_MaxClientsVar = NULL; } diff --git a/core/logic/AMBuilder b/core/logic/AMBuilder index 8be3ca3a6..2b897eb9d 100644 --- a/core/logic/AMBuilder +++ b/core/logic/AMBuilder @@ -36,6 +36,9 @@ files = [ 'smn_admin.cpp', 'smn_banning.cpp', 'stringutil.cpp', + 'Translator.cpp', + 'PhraseCollection.cpp', + 'smn_lang.cpp', 'sm_crc32.cpp' ] if AMBuild.target['platform'] == 'windows': diff --git a/core/logic/Makefile b/core/logic/Makefile index a98ac39b8..4147ce958 100644 --- a/core/logic/Makefile +++ b/core/logic/Makefile @@ -32,6 +32,9 @@ OBJECTS = \ smn_admin.cpp \ smn_banning.cpp \ stringutil.cpp \ + Translator.cpp \ + PhraseCollection.cpp \ + smn_lang.cpp \ smn_players.cpp ############################################## diff --git a/core/PhraseCollection.cpp b/core/logic/PhraseCollection.cpp similarity index 90% rename from core/PhraseCollection.cpp rename to core/logic/PhraseCollection.cpp index 0af77da88..a26bdd937 100644 --- a/core/PhraseCollection.cpp +++ b/core/logic/PhraseCollection.cpp @@ -29,9 +29,9 @@ * Version: $Id$ */ +#include "common_logic.h" #include "PhraseCollection.h" #include "Translator.h" -#include "sm_stringutil.h" CPhraseCollection::CPhraseCollection() { @@ -54,7 +54,7 @@ IPhraseFile *CPhraseCollection::AddPhraseFile(const char *filename) 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); + smcore.Format(full_name, sizeof(full_name), "%s.txt", filename); fid = g_Translator.FindOrAddPhraseFile(full_name); pFile = g_Translator.GetFileByIndex(fid); @@ -113,7 +113,7 @@ bool CPhraseCollection::FormatString(char *buffer, unsigned int arg; arg = 0; - if (!gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase)) + if (!smcore.gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase)) { return false; } diff --git a/core/PhraseCollection.h b/core/logic/PhraseCollection.h similarity index 100% rename from core/PhraseCollection.h rename to core/logic/PhraseCollection.h diff --git a/core/Translator.cpp b/core/logic/Translator.cpp similarity index 81% rename from core/Translator.cpp rename to core/logic/Translator.cpp index 49f1e2711..4d380ef1a 100644 --- a/core/Translator.cpp +++ b/core/logic/Translator.cpp @@ -29,22 +29,23 @@ * Version: $Id$ */ +#include "common_logic.h" #include #include #include #include "Translator.h" -#include "Logger.h" -#include "LibrarySys.h" -#include "sm_stringutil.h" -#include "sourcemod.h" -#include "PlayerManager.h" +#include +#include +#include #include "PhraseCollection.h" -#include "ShareSys.h" +#include "stringutil.h" Translator g_Translator; IPhraseCollection *g_pCorePhrases = NULL; unsigned int g_pCorePhraseID = 0; +using namespace SourceMod; + struct trans_t { int stridx; @@ -67,15 +68,10 @@ CPhraseFile::CPhraseFile(Translator *pTranslator, const char *file) m_LangCount = pTranslator->GetLanguageCount(); m_File.assign(file); m_pTranslator = pTranslator; - m_pPhraseLookup = NULL; } CPhraseFile::~CPhraseFile() { - if (m_pPhraseLookup) - { - sm_trie_destroy(m_pPhraseLookup); - } } void CPhraseFile::ParseError(const char *message, ...) @@ -99,20 +95,16 @@ void CPhraseFile::ParseWarning(const char *message, ...) if (!m_FileLogged) { - g_Logger.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str()); + smcore.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str()); m_FileLogged = true; } - g_Logger.LogError("[SM] %s", buffer); + smcore.LogError("[SM] %s", buffer); } void CPhraseFile::ReparseFile() { - if (m_pPhraseLookup) - { - sm_trie_destroy(m_pPhraseLookup); - } - m_pPhraseLookup = sm_trie_create(); + m_PhraseLookup.clear(); m_LangCount = m_pTranslator->GetLanguageCount(); @@ -123,19 +115,19 @@ void CPhraseFile::ReparseFile() SMCError err; char path[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "translations/%s", m_File.c_str()); + g_pSM->BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "translations/%s", m_File.c_str()); //backwards compatibility shim /* :HACKHACK: Change .cfg/.txt and vice versa for compatibility */ - if (!g_LibSys.PathExists(path)) + if (!libsys->PathExists(path)) { if (m_File.compare("common.cfg") == 0) { - UTIL_ReplaceAll(path, sizeof(path), "common.cfg", "common.phrases.txt"); + smcore.ReplaceAll(path, sizeof(path), "common.cfg", "common.phrases.txt", true); } else if (strstr(path, ".cfg")) { - UTIL_ReplaceAll(path, sizeof(path), ".cfg", ".txt"); + smcore.ReplaceAll(path, sizeof(path), ".cfg", ".txt", true); } else if (strstr(path, ".txt")) { - UTIL_ReplaceAll(path, sizeof(path), ".txt", ".cfg"); + smcore.ReplaceAll(path, sizeof(path), ".txt", ".cfg", true); } } @@ -149,8 +141,8 @@ void CPhraseFile::ReparseFile() msg = m_ParseError.c_str(); } - g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str()); - g_Logger.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); + smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str()); + smcore.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); } const char *code; @@ -161,7 +153,7 @@ void CPhraseFile::ReparseFile() continue; } - g_SourceMod.BuildPath(Path_SM, + g_pSM->BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "translations/%s/%s", @@ -169,7 +161,7 @@ void CPhraseFile::ReparseFile() m_File.c_str()); /* Speculatively load these. */ - if (!g_LibSys.PathExists(path)) + if (!libsys->PathExists(path)) { continue; } @@ -182,10 +174,10 @@ void CPhraseFile::ReparseFile() msg = m_ParseError.c_str(); } - g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"", + smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"", code, m_File.c_str()); - g_Logger.LogError("[SM] Error (line %d, column %d): %s", + smcore.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); @@ -217,17 +209,17 @@ SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *n m_ParseState = PPS_InPhrase; recognized = true; - void *value; - if (sm_trie_retrieve(m_pPhraseLookup, name, &value)) + int *pvalue; + if ((pvalue = m_PhraseLookup.retrieve(name)) != NULL) { - m_CurPhrase = reinterpret_cast(value); + m_CurPhrase = *pvalue; } else { phrase_t *pPhrase; m_CurPhrase = m_pMemory->CreateMem(sizeof(phrase_t), (void **)&pPhrase); - sm_trie_insert(m_pPhraseLookup, name, reinterpret_cast(m_CurPhrase)); + m_PhraseLookup.insert(name, m_CurPhrase); /* Initialize new phrase */ trans_t *pTrans; @@ -639,9 +631,7 @@ SMCResult CPhraseFile::ReadSMC_LeavingSection(const SMCStates *states) if (m_ParseState == PPS_InPhrase) { if (m_CurPhrase == -1 && m_LastPhraseString.size()) - { - sm_trie_delete(m_pPhraseLookup, m_LastPhraseString.c_str()); - } + m_PhraseLookup.remove(m_LastPhraseString.c_str()); m_CurPhrase = -1; m_ParseState = PPS_Phrases; m_LastPhraseString.assign(""); @@ -658,9 +648,7 @@ void CPhraseFile::ReadSMC_ParseEnd(bool halted, bool failed) { /* Check to see if we have any dangling phrases that weren't completed, and scrap them */ if ((halted || failed) && m_LastPhraseString.size()) - { - sm_trie_delete(m_pPhraseLookup, m_LastPhraseString.c_str()); - } + m_PhraseLookup.remove(m_LastPhraseString.c_str()); } TransError CPhraseFile::GetTranslation(const char *szPhrase, unsigned int lang_id, Translation *pTrans) @@ -670,13 +658,11 @@ TransError CPhraseFile::GetTranslation(const char *szPhrase, unsigned int lang_i return Trans_BadLanguage; } - void *object; - if (!sm_trie_retrieve(m_pPhraseLookup, szPhrase, &object)) - { + int *pvalue; + if ((pvalue = m_PhraseLookup.retrieve(szPhrase)) == NULL) return Trans_BadPhrase; - } - phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(reinterpret_cast(object)); + phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(*pvalue); trans_t *trans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl); trans = &trans[lang_id]; @@ -705,7 +691,6 @@ const char *CPhraseFile::GetFilename() Translator::Translator() : m_ServerLang(SOURCEMOD_LANGUAGE_ENGLISH) { m_pStringTab = new BaseStringTable(2048); - m_pLCodeLookup = sm_trie_create(); strncopy(m_InitialLang, "en", sizeof(m_InitialLang)); } @@ -721,8 +706,6 @@ Translator::~Translator() delete m_Languages[i]; } - sm_trie_destroy(m_pLCodeLookup); - delete m_pStringTab; } @@ -739,13 +722,13 @@ ConfigResult Translator::OnSourceModConfigChanged(const char *key, unsigned int index; if (!GetLanguageByCode(value, &index)) { - UTIL_Format(error, maxlength, "Language code \"%s\" is not registered", value); + smcore.Format(error, maxlength, "Language code \"%s\" is not registered", value); return ConfigResult_Reject; } m_ServerLang = index; } else { - strncopy(m_InitialLang, value, sizeof(m_InitialLang)); + smcore.strncopy(m_InitialLang, value, sizeof(m_InitialLang)); } return ConfigResult_Accept; @@ -758,7 +741,7 @@ void Translator::OnSourceModLevelChange(const char *mapName) { /* Refresh language stuff */ char path[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg"); + g_pSM->BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg"); RebuildLanguageDatabase(path); } @@ -769,7 +752,7 @@ void Translator::OnSourceModAllInitialized() g_pCorePhrases = CreatePhraseCollection(); g_pCorePhrases->AddPhraseFile("core.phrases"); - g_ShareSys.AddInterface(NULL, this); + sharesys->AddInterface(NULL, this); } void Translator::OnSourceModShutdown() @@ -779,17 +762,13 @@ void Translator::OnSourceModShutdown() bool Translator::GetLanguageByCode(const char *code, unsigned int *index) { - void *_index; + unsigned int *pindex; - if (!sm_trie_retrieve(m_pLCodeLookup, code, &_index)) - { + if ((pindex = m_LCodeLookup.retrieve(code)) == NULL) return false; - } if (index) - { - *index = reinterpret_cast(_index); - } + *index = *pindex; return true; } @@ -853,8 +832,7 @@ unsigned int Translator::FindOrAddPhraseFile(const char *phrase_file) void Translator::RebuildLanguageDatabase(const char *lang_header_file) { /* Erase everything we have */ - sm_trie_destroy(m_pLCodeLookup); - m_pLCodeLookup = sm_trie_create(); + m_LCodeLookup.clear(); m_pStringTab->Reset(); for (size_t i=0; i(serverLang); + m_ServerLang = *pServerLang; if (!m_Languages.size()) { - g_Logger.LogError("[SM] Fatal error, no languages found! Translation will not work."); + smcore.LogError("[SM] Fatal error, no languages found! Translation will not work."); } for (size_t i=0; i 3) { - g_Logger.LogError("[SM] Warning encountered parsing languages.cfg file."); - g_Logger.LogError("[SM] Invalid language code \"%s\" is being ignored.", key); + smcore.LogError("[SM] Warning encountered parsing languages.cfg file."); + smcore.LogError("[SM] Invalid language code \"%s\" is being ignored.", key); } AddLanguage(key, value); @@ -949,18 +927,16 @@ SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, bool Translator::AddLanguage(const char *langcode, const char *description) { - if (sm_trie_retrieve(m_pLCodeLookup, langcode, NULL)) - { + if (m_LCodeLookup.retrieve(langcode) != NULL) return false; - } Language *pLanguage = new Language; unsigned int idx = m_Languages.size(); - UTIL_Format(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode); + smcore.Format(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode); pLanguage->m_FullName = m_pStringTab->AddString(description); - sm_trie_insert(m_pLCodeLookup, langcode, reinterpret_cast(idx)); + m_LCodeLookup.insert(langcode, idx); m_Languages.push_back(pLanguage); @@ -984,7 +960,7 @@ unsigned int Translator::GetServerLanguage() unsigned int Translator::GetClientLanguage(int client) { - CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); + IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); return pPlayer->GetLanguageId(); } @@ -1025,20 +1001,16 @@ IPhraseCollection *Translator::CreatePhraseCollection() int Translator::SetGlobalTarget(int index) { - return g_SourceMod.SetGlobalTarget(index); + return g_pSM->SetGlobalTarget(index); } int Translator::GetGlobalTarget() const { - return g_SourceMod.GetGlobalTarget(); + return g_pSM->GetGlobalTarget(); } -bool CoreTranslate(char *buffer, - size_t maxlength, - const char *format, - unsigned int numparams, - size_t *pOutLength, - ...) +bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned int numparams, + size_t *pOutLength, ...) { va_list ap; unsigned int i; @@ -1068,11 +1040,11 @@ bool CoreTranslate(char *buffer, { if (fail_phrase != NULL) { - g_Logger.LogError("[SM] Could not find core phrase: %s", fail_phrase); + smcore.LogError("[SM] Could not find core phrase: %s", fail_phrase); } else { - g_Logger.LogError("[SM] Unknown fatal error while translating a core phrase."); + smcore.LogError("[SM] Unknown fatal error while translating a core phrase."); } return false; @@ -1093,7 +1065,7 @@ bool Translator::FormatString(char *buffer, unsigned int arg; arg = 0; - if (!gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase)) + if (!smcore.gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase)) { return false; } diff --git a/core/Translator.h b/core/logic/Translator.h similarity index 94% rename from core/Translator.h rename to core/logic/Translator.h index 255739188..4c2275f59 100644 --- a/core/Translator.h +++ b/core/logic/Translator.h @@ -32,17 +32,14 @@ #ifndef _INCLUDE_SOURCEMOD_TRANSLATOR_H_ #define _INCLUDE_SOURCEMOD_TRANSLATOR_H_ -#include "sm_trie.h" +#include "common_logic.h" +#include #include #include -#include "sm_globals.h" #include "sm_memtable.h" #include "ITextParsers.h" #include -#define MAX_TRANSLATE_PARAMS 32 -#define CORELANG_ENGLISH 0 - /* :TODO: write a templatized version of tries? */ using namespace SourceHook; @@ -82,7 +79,7 @@ private: void ParseError(const char *message, ...); void ParseWarning(const char *message, ...); private: - Trie *m_pPhraseLookup; + KTrie m_PhraseLookup; String m_File; Translator *m_pTranslator; PhraseParseState m_ParseState; @@ -155,7 +152,7 @@ private: CVector m_Languages; CVector m_Files; BaseStringTable *m_pStringTab; - Trie *m_pLCodeLookup; + KTrie m_LCodeLookup; bool m_InLanguageSection; String m_CustomError; unsigned int m_ServerLang; @@ -175,3 +172,4 @@ extern unsigned int g_pCorePhraseID; extern Translator g_Translator; #endif //_INCLUDE_SOURCEMOD_TRANSLATOR_H_ + diff --git a/core/logic/common_logic.cpp b/core/logic/common_logic.cpp index 1c881dcdf..d22b4c42f 100644 --- a/core/logic/common_logic.cpp +++ b/core/logic/common_logic.cpp @@ -39,6 +39,7 @@ #include "sm_crc32.h" #include "MemoryUtils.h" #include "stringutil.h" +#include "Translator.h" sm_core_t smcore; IHandleSys *handlesys; @@ -58,14 +59,22 @@ IPlayerManager *playerhelpers; IAdminSystem *adminsys; IGameHelpers *gamehelpers; +static void AddCorePhraseFile(const char *filename) +{ + g_pCorePhrases->AddPhraseFile("antiflood.phrases"); +} + static sm_logic_t logic = { NULL, g_pThreader, sm_profiler, &g_MemUtils, + &g_Translator, UTIL_CRC32, - stristr + stristr, + CoreTranslate, + AddCorePhraseFile }; static void logic_init(const sm_core_t* core, sm_logic_t* _logic) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index b28c58d41..308542e59 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -42,7 +42,7 @@ using namespace SourceMod; * Add 1 to the RHS of this expression to bump the intercom file * This is to prevent mismatching core/logic binaries */ -#define SM_LOGIC_MAGIC (0x0F47C0DE - 9) +#define SM_LOGIC_MAGIC (0x0F47C0DE - 10) #if defined SM_LOGIC class IVEngineServer @@ -69,6 +69,8 @@ namespace SourceMod class IMemoryUtils; class IAdminSystem; class IGameHelpers; + class IPhraseCollection; + class ITranslator; } class IVEngineServer; @@ -107,6 +109,8 @@ struct sm_core_t size_t (*Format)(char*, size_t, const char*, ...); unsigned int (*ReplaceAll)(char*, size_t, const char *, const char *, bool); void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...); + bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **, + unsigned int, unsigned int &, size_t *, const char **); /* Data */ ServerGlobals *serverGlobals; }; @@ -117,8 +121,11 @@ struct sm_logic_t IThreader *threader; IProfiler *profiler; IMemoryUtils *memutils; + ITranslator *translator; unsigned int (*CRC32)(const void *, size_t); const char *(*stristr)(const char *, const char *); + bool (*CoreTranslate)(char *, size_t, const char *, unsigned int, size_t *, ...); + void (*AddCorePhraseFile)(const char *filename); }; typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic); diff --git a/core/logic/sm_memtable.h b/core/logic/sm_memtable.h new file mode 100644 index 000000000..8789e68eb --- /dev/null +++ b/core/logic/sm_memtable.h @@ -0,0 +1,163 @@ +/** + * 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 . + * + * 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 . + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ +#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ + +#include +#include + +class BaseMemTable +{ +public: + BaseMemTable(unsigned int init_size) + { + membase = (unsigned char *)malloc(init_size); + size = init_size; + tail = 0; + } + ~BaseMemTable() + { + free(membase); + membase = NULL; + } +public: + /** + * Allocates 'size' bytes of memory. + * Optionally outputs the address through 'addr'. + * Returns an index >= 0 on success, < 0 on failure. + */ + int CreateMem(unsigned int addsize, void **addr) + { + int idx = (int)tail; + + while (tail + addsize >= size) { + size *= 2; + membase = (unsigned char *)realloc(membase, size); + } + + tail += addsize; + if (addr) + *addr = (void *)&membase[idx]; + + return idx; + } + + /** + * Given an index into the memory table, returns its address. + * Returns NULL if invalid. + */ + void *GetAddress(int index) + { + if (index < 0 || (unsigned int)index >= tail) + return NULL; + return &membase[index]; + } + + /** + * Scraps the memory table. For caching purposes, the memory + * is not freed, however subsequent calls to CreateMem() will + * begin at the first index again. + */ + void Reset() + { + tail = 0; + } + + inline unsigned int GetMemUsage() + { + return size; + } + + inline unsigned int GetActualMemUsed() + { + return tail; + } + +private: + unsigned char *membase; + unsigned int size; + unsigned int tail; +}; + +class BaseStringTable +{ +public: + BaseStringTable(unsigned int init_size) : m_table(init_size) + { + } +public: + /** + * Adds a string to the string table and returns its index. + */ + int AddString(const char *string) + { + size_t len = strlen(string) + 1; + int idx; + char *addr; + + idx = m_table.CreateMem(len, (void **)&addr); + strcpy(addr, string); + + return idx; + } + + /** + * Given an index into the string table, returns the associated string. + */ + inline const char *GetString(int str) + { + return (const char *)m_table.GetAddress(str); + } + + /** + * Scraps the string table. For caching purposes, the memory + * is not freed, however subsequent calls to AddString() will + * begin at the first index again. + */ + void Reset() + { + m_table.Reset(); + } + + /** + * Returns the parent BaseMemTable that this string table uses. + */ + inline BaseMemTable *GetMemTable() + { + return &m_table; + } +private: + BaseMemTable m_table; +}; + +#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_ + diff --git a/core/smn_lang.cpp b/core/logic/smn_lang.cpp similarity index 88% rename from core/smn_lang.cpp rename to core/logic/smn_lang.cpp index da31706a7..dc94870bc 100644 --- a/core/smn_lang.cpp +++ b/core/logic/smn_lang.cpp @@ -29,20 +29,20 @@ * Version: $Id$ */ -#include "PluginSys.h" +#include "common_logic.h" #include "Translator.h" -#include "LibrarySys.h" -#include "sm_stringutil.h" -#include "PlayerManager.h" +#include +#include +#include static cell_t sm_LoadTranslations(IPluginContext *pCtx, const cell_t *params) { char *filename, *ext; char buffer[PLATFORM_MAX_PATH]; - CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext()); + IPlugin *pl = pluginsys->FindPluginByContext(pCtx->GetContext()); pCtx->LocalToString(params[1], &filename); - UTIL_Format(buffer, sizeof(buffer), "%s", filename); + smcore.Format(buffer, sizeof(buffer), "%s", filename); /* Make sure there is no extension */ if ((ext = strstr(buffer, ".txt")) != NULL @@ -62,14 +62,14 @@ static cell_t sm_LoadTranslations(IPluginContext *pCtx, const cell_t *params) static cell_t sm_SetGlobalTransTarget(IPluginContext *pContext, const cell_t *params) { - g_SourceMod.SetGlobalTarget(params[1]); + g_pSM->SetGlobalTarget(params[1]); return 1; } static cell_t sm_GetClientLanguage(IPluginContext *pContext, const cell_t *params) { - CPlayer *player = g_Players.GetPlayerByIndex(params[1]); + IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); if (!player || !player->IsConnected()) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); diff --git a/core/logic/stringutil.cpp b/core/logic/stringutil.cpp index d03a39e34..249c9f0a4 100644 --- a/core/logic/stringutil.cpp +++ b/core/logic/stringutil.cpp @@ -64,4 +64,21 @@ const char *stristr(const char *str, const char *substr) return NULL; } +unsigned int strncopy(char *dest, const char *src, size_t count) +{ + if (!count) + { + return 0; + } + + char *start = dest; + while ((*src) && (--count)) + { + *dest++ = *src++; + } + *dest = '\0'; + + return (dest - start); +} + diff --git a/core/logic/stringutil.h b/core/logic/stringutil.h index 7b19e95e0..5a4fae4b3 100644 --- a/core/logic/stringutil.h +++ b/core/logic/stringutil.h @@ -33,6 +33,7 @@ #define _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ const char *stristr(const char *str, const char *substr); +unsigned int strncopy(char *dest, const char *src, size_t count); #endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */ diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 216118fd5..df280015f 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -58,6 +58,7 @@ ITextParsers *textparsers; SM_FN_CRC32 UTIL_CRC32; IMemoryUtils *memutils; sm_logic_t logicore; +ITranslator *translator; class VEngineServer_Logic : public IVEngineServer_Logic { @@ -136,6 +137,7 @@ static sm_core_t core_bridge = UTIL_Format, UTIL_ReplaceAll, generate_error, + gnprintf, &serverGlobals }; @@ -161,6 +163,7 @@ void InitLogicBridge() g_pSourcePawn2->SetProfiler(logicore.profiler); UTIL_CRC32 = logicore.CRC32; memutils = logicore.memutils; + translator = logicore.translator; } bool StartLogicBridge(char *error, size_t maxlength) diff --git a/core/logic_bridge.h b/core/logic_bridge.h index a16f35d3c..1b2e3f1d9 100644 --- a/core/logic_bridge.h +++ b/core/logic_bridge.h @@ -43,6 +43,7 @@ typedef unsigned int (*SM_FN_CRC32)(const void *, size_t); extern SM_FN_CRC32 UTIL_CRC32; extern sm_logic_t logicore; +extern ITranslator *translator; #endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */ diff --git a/core/sm_stringutil.cpp b/core/sm_stringutil.cpp index 02018d5d4..821edd2d9 100644 --- a/core/sm_stringutil.cpp +++ b/core/sm_stringutil.cpp @@ -35,8 +35,8 @@ #include "sm_stringutil.h" #include "Logger.h" #include "PluginSys.h" -#include "Translator.h" #include "PlayerManager.h" +#include "logic_bridge.h" #define LADJUST 0x00000004 /* left adjustment */ #define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */ @@ -81,11 +81,11 @@ size_t Translate(char *buffer, try_serverlang: if (target == SOURCEMOD_SERVER_LANGUAGE) { - langid = g_Translator.GetServerLanguage(); + langid = translator->GetServerLanguage(); } else if ((target >= 1) && (target <= g_Players.GetMaxClients())) { - langid = g_Translator.GetClientLanguage(target); + langid = translator->GetClientLanguage(target); } else { @@ -95,7 +95,7 @@ try_serverlang: if (pPhrases->FindTranslation(key, langid, &pTrans) != Trans_Okay) { - if (target != SOURCEMOD_SERVER_LANGUAGE && langid != g_Translator.GetServerLanguage()) + if (target != SOURCEMOD_SERVER_LANGUAGE && langid != translator->GetServerLanguage()) { target = SOURCEMOD_SERVER_LANGUAGE; goto try_serverlang; @@ -785,21 +785,21 @@ reswitch: } else { - target = g_Translator.GetGlobalTarget(); + target = translator->GetGlobalTarget(); } try_again: if (target == SOURCEMOD_SERVER_LANGUAGE) { - lang_id = g_Translator.GetServerLanguage(); + lang_id = translator->GetServerLanguage(); } else if (target >= 1 && target <= g_Players.GetMaxClients()) { - lang_id = g_Translator.GetClientLanguage(target); + lang_id = translator->GetClientLanguage(target); } else { - lang_id = g_Translator.GetServerLanguage(); + lang_id = translator->GetServerLanguage(); } if (pPhrases == NULL) @@ -813,7 +813,7 @@ try_again: if (pPhrases->FindTranslation(key, lang_id, &trans) != Trans_Okay) { - if (target != SOURCEMOD_SERVER_LANGUAGE && lang_id != g_Translator.GetServerLanguage()) + if (target != SOURCEMOD_SERVER_LANGUAGE && lang_id != translator->GetServerLanguage()) { target = SOURCEMOD_SERVER_LANGUAGE; goto try_again; diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index aa6b38bc8..c5a74c269 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -42,7 +42,6 @@ #include "AdminCache.h" #include "sm_stringutil.h" #include "PlayerManager.h" -#include "Translator.h" #include "ForwardSys.h" #include "TimerSys.h" #include "GameConfigs.h" diff --git a/public/IPluginSys.h b/public/IPluginSys.h index 54fdf6ed5..1e92d9e4a 100644 --- a/public/IPluginSys.h +++ b/public/IPluginSys.h @@ -42,7 +42,7 @@ #include #define SMINTERFACE_PLUGINSYSTEM_NAME "IPluginManager" -#define SMINTERFACE_PLUGINSYSTEM_VERSION 3 +#define SMINTERFACE_PLUGINSYSTEM_VERSION 4 /** Context user slot 3 is used Core for holding an IPluginContext pointer. */ #define SM_CONTEXTVAR_USER 3 @@ -93,6 +93,8 @@ namespace SourceMod PluginType_Global, /**< Plugin will never be unloaded or updated */ }; + class IPhraseCollection; + /** * @brief Encapsulates a run-time plugin as maintained by SourceMod. */ @@ -197,6 +199,13 @@ namespace SourceMod * @return IPluginRuntime pointer, or NULL if not loaded. */ virtual SourcePawn::IPluginRuntime *GetRuntime() =0; + + /** + * @brief Returns the plugin's phrase collection. + * + * @return Plugin's phrase collection. + */ + virtual IPhraseCollection *GetPhrases() =0; }; diff --git a/public/ITranslator.h b/public/ITranslator.h index cdd0e8f9c..748407289 100644 --- a/public/ITranslator.h +++ b/public/ITranslator.h @@ -35,7 +35,10 @@ #include #define SMINTERFACE_TRANSLATOR_NAME "ITranslator" -#define SMINTERFACE_TRANSLATOR_VERSION 1 +#define SMINTERFACE_TRANSLATOR_VERSION 2 + +#define MAX_TRANSLATE_PARAMS 32 +#define CORELANG_ENGLISH 0 /** * @file ITranslator.h @@ -322,6 +325,22 @@ namespace SourceMod unsigned int numparams, size_t *pOutLength, const char **pFailPhrase) =0; + + /** + * @brief Get number of languages. + * + * @return Number of languages. + */ + virtual unsigned int GetLanguageCount() =0; + + /** + * @brief Find a language number by name. + * + * @param name Language name. + * @param index Optional pointer to store language index. + * @return True if found, false otherwise. + */ + virtual bool GetLanguageByName(const char *name, unsigned int *index) =0; }; }