From ae5dfd096601ceafacf0f7c9e8aaf1f227e6981c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 17 Feb 2007 19:03:18 +0000 Subject: [PATCH] added helper a core translation helper to the translator regadmincmd is now officially done and tested, as are overrides printtoplayers now prints to the server on id==0 as a convenience fixed a crash bug in the admin system fixed up console.inc a bit --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40526 --- core/AdminCache.cpp | 15 +++++++---- core/AdminCache.h | 1 + core/CConCmdManager.cpp | 23 +++++++++++++--- core/CTranslator.cpp | 54 ++++++++++++++++++++++++++++++++++--- core/CTranslator.h | 11 +++++++- core/smn_console.cpp | 32 ++++++++++++++-------- core/sourcemod.cpp | 6 +++++ plugins/include/console.inc | 9 ++++--- 8 files changed, 124 insertions(+), 27 deletions(-) diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index e8557bc0..0cc9e833 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -34,10 +34,12 @@ AdminCache::AdminCache() m_FirstGroup = -1; m_pAuthTables = sm_trie_create(); m_InvalidatingAdmins = false; + m_destroying = false; } AdminCache::~AdminCache() { + m_destroying = true; DumpAdminCache(AdminCache_Overrides, false); DumpAdminCache(AdminCache_Groups, false); @@ -549,7 +551,7 @@ bool AdminCache::InvalidateAdmin(AdminId id) return false; } - if (!m_InvalidatingAdmins) + if (!m_InvalidatingAdmins && !m_destroying) { g_Players.ClearAdminId(id); } @@ -749,7 +751,10 @@ void AdminCache::RegisterAuthIdentType(const char *name) void AdminCache::InvalidateAdminCache(bool unlink_admins) { m_InvalidatingAdmins = true; - g_Players.ClearAllAdmins(); + if (!m_destroying) + { + g_Players.ClearAllAdmins(); + } /* Wipe the identity cache first */ List::iterator iter; for (iter=m_AuthMethods.begin(); @@ -783,7 +788,7 @@ void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild) { DumpCommandOverrideCache(Override_Command); DumpCommandOverrideCache(Override_CommandGroup); - if (rebuild) + if (rebuild && !m_destroying) { for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) { @@ -797,7 +802,7 @@ void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild) if (part == AdminCache_Groups) { InvalidateGroupCache(); - if (rebuild) + if (rebuild && !m_destroying) { for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) { @@ -809,7 +814,7 @@ void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild) } } InvalidateAdminCache(true); - if (rebuild) + if (rebuild && !m_destroying) { for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) { diff --git a/core/AdminCache.h b/core/AdminCache.h index 9d4eaae9..eb40a5cf 100644 --- a/core/AdminCache.h +++ b/core/AdminCache.h @@ -159,6 +159,7 @@ public: int m_LastUser; int m_FreeUserList; bool m_InvalidatingAdmins; + bool m_destroying; }; extern AdminCache g_Admins; diff --git a/core/CConCmdManager.cpp b/core/CConCmdManager.cpp index 9bc10721..546fe4be 100644 --- a/core/CConCmdManager.cpp +++ b/core/CConCmdManager.cpp @@ -306,7 +306,7 @@ bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdm } /* See if our other flags match */ - if ((bits & cmdflags) != cmdflags) + if ((bits & cmdflags) == cmdflags) { return true; } @@ -338,8 +338,25 @@ bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdm } } + if (player->IsFakeClient() + || player->GetEdict() == NULL) + { + return false; + } + /* If we got here, the command failed... */ - /* :TODO: send a message to the client about this! */ + char buffer[128]; + if (g_Translator.CoreTrans(client, buffer, sizeof(buffer), "No Access", NULL, NULL) + != Trans_Okay) + { + snprintf(buffer, sizeof(buffer), "You do not have access to this command"); + } + + char fullbuffer[192]; + snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer); + + engine->ClientPrintf(player->GetEdict(), fullbuffer); + return false; } @@ -403,7 +420,7 @@ bool CConCmdManager::AddAdminCommand(IPluginFunction *pFunction, } pAdmin->cmdGrpId = grpid; - pAdmin->flags = flags; + pAdmin->flags = adminflags; /* First get the command group override, if any */ bool override = g_Admins.GetCommandOverride(group, diff --git a/core/CTranslator.cpp b/core/CTranslator.cpp index 11a37c6f..ce73c044 100644 --- a/core/CTranslator.cpp +++ b/core/CTranslator.cpp @@ -604,6 +604,7 @@ CTranslator::~CTranslator() void CTranslator::OnSourceModAllInitialized() { + AddLanguage("en", "English"); unsigned int id = FindOrAddPhraseFile("core.cfg"); g_pCorePhrases = GetFileByIndex(id); } @@ -735,17 +736,31 @@ SMCParseResult CTranslator::ReadSMC_KeyValue(const char *key, const char *value, g_Logger.LogError("[SM] Invalid language code \"%s\" is being ignored.", key); } + AddLanguage(key, value); + + return SMCParse_Continue; +} + +bool CTranslator::AddLanguage(const char *langcode, const char *description) +{ + if (sm_trie_retrieve(m_pLCodeLookup, langcode, NULL)) + { + return false; + } + Language *pLanguage = new Language; unsigned int idx = m_Languages.size(); - strcpy(pLanguage->m_code2, key); - pLanguage->m_FullName = m_pStringTab->AddString(value); + pLanguage->m_code2[0] = langcode[0]; + pLanguage->m_code2[1] = langcode[1]; + pLanguage->m_code2[2] = langcode[2]; + pLanguage->m_FullName = m_pStringTab->AddString(description); - sm_trie_insert(m_pLCodeLookup, key, reinterpret_cast(idx)); + sm_trie_insert(m_pLCodeLookup, langcode, reinterpret_cast(idx)); m_Languages.push_back(pLanguage); - return SMCParse_Continue; + return true; } CPhraseFile *CTranslator::GetFileByIndex(unsigned int index) @@ -770,3 +785,34 @@ size_t CTranslator::Translate(char *buffer, size_t maxlength, void **params, con return gnprintf(buffer, maxlength, pTrans->szPhrase, new_params); } + +TransError CTranslator::CoreTrans(int client, + char *buffer, + size_t maxlength, + const char *phrase, + void **params, + size_t *outlen) +{ + /* :TODO: do language stuff here */ + + if (!g_pCorePhrases) + { + return Trans_BadPhraseFile; + } + + Translation trans; + TransError err; + if ((err=g_pCorePhrases->GetTranslation(phrase, 0, &trans)) != Trans_Okay) + { + return err; + } + + size_t len = Translate(buffer, maxlength, params, &trans); + + if (outlen) + { + *outlen = len; + } + + return Trans_Okay; +} diff --git a/core/CTranslator.h b/core/CTranslator.h index a487198c..3138e91c 100644 --- a/core/CTranslator.h +++ b/core/CTranslator.h @@ -53,7 +53,8 @@ enum TransError Trans_Okay = 0, Trans_BadLanguage = 1, Trans_BadPhrase = 2, - Trans_BadPhraseLanguage = 3 + Trans_BadPhraseLanguage = 3, + Trans_BadPhraseFile = 4, }; class CPhraseFile : public ITextListener_SMC @@ -112,6 +113,14 @@ public: bool GetLanguageByCode(const char *code, unsigned int *index); size_t Translate(char *buffer, size_t maxlength, void **params, const Translation *pTrans); CPhraseFile *GetFileByIndex(unsigned int index); + TransError CoreTrans(int client, + char *buffer, + size_t maxlength, + const char *phrase, + void **params, + size_t *outlen=NULL); +private: + bool AddLanguage(const char *langcode, const char *description); private: CVector m_Languages; CVector m_Files; diff --git a/core/smn_console.cpp b/core/smn_console.cpp index 410b6645..acc09148 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -436,21 +436,25 @@ static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params) static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params) { int index = params[1]; - if ((index < 1) || (index > g_Players.GetMaxClients())) + if ((index < 0) || (index > g_Players.GetMaxClients())) { return pCtx->ThrowNativeError("Invalid client index %d", index); } - CPlayer *pPlayer = g_Players.GetPlayerByIndex(index); - if (!pPlayer->IsInGame()) + CPlayer *pPlayer = NULL; + if (index != 0) { - return pCtx->ThrowNativeError("Client %d is not in game", index); - } - - /* Silent fail on bots, engine will crash */ - if (pPlayer->IsFakeClient()) - { - return 0; + pPlayer = g_Players.GetPlayerByIndex(index); + if (!pPlayer->IsInGame()) + { + return pCtx->ThrowNativeError("Client %d is not in game", index); + } + + /* Silent fail on bots, engine will crash */ + if (pPlayer->IsFakeClient()) + { + return 0; + } } char buffer[1024]; @@ -463,7 +467,12 @@ static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params) buffer[res++] = '\n'; buffer[res] = '\0'; - engine->ClientPrintf(pPlayer->GetEdict(), buffer); + if (index != 0) + { + engine->ClientPrintf(pPlayer->GetEdict(), buffer); + } else { + META_CONPRINT(buffer); + } return 1; } @@ -495,5 +504,6 @@ REGISTER_NATIVES(consoleNatives) {"GetCmdArg", sm_GetCmdArg}, {"PrintToServer", sm_PrintToServer}, {"PrintToConsole", sm_PrintToConsole}, + {"RegAdminCmd", sm_RegAdminCmd}, {NULL, NULL} }; diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index 375844f8..c13b2a10 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -24,6 +24,7 @@ #include "AdminCache.h" #include "sm_stringutil.h" #include "CPlayerManager.h" +#include "CTranslator.h" SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); @@ -190,6 +191,11 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch g_Logger.MapChange(pMapName); + /* Refresh language stuff */ + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg"); + g_Translator.RebuildLanguageDatabase(path); + DoGlobalPluginLoads(); m_IsMapLoading = false; diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 4bfb27b4..74e10906 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -76,10 +76,11 @@ native PrintToConsole(client, const String:format[], {Handle,Float,String,_}:... /** * Called when a server-only command is invoked. * + * @params args Number of arguments that were in the argument string. * @return A Result value. Not handling the command * means that Source will report it as "not found." */ -functag SrvCmd Action:public(argCount); +functag SrvCmd Action:public(args); /** * Creates a server-only console command, or hooks an already existing one. @@ -96,10 +97,11 @@ native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:descriptio * Called when a generic console command is invoked. * * @param client Index of the client, or 0 from the server. + * @param args Number of arguments that were in the argument string. * @return A Result value. Not handling the command * means that Source will report it as "not found." */ -functag ConCmd Action:public(client, argCount); +functag ConCmd Action:public(client, args); /** * Creates a console command, or hooks an already existing one. @@ -114,7 +116,8 @@ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:descripti /** * Creates a console command as an administrative command. If the command does not exist, - * it is created. + * it is created. When this command is invoked, the access rights of the player are + * automatically checked before allowing it to continue. * * @param cmd String containing command to register. * @param callback A function to use as a callback for when the command is invoked.