diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index b64a9d7b..d9150cc8 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -35,10 +35,11 @@ SDKTools g_SdkTools; /**< Global singleton for extension's main interface */ IServerGameEnts *gameents = NULL; IEngineTrace *enginetrace = NULL; +IEngineSound *engsound = NULL; +INetworkStringTableContainer *netstringtables = NULL; IBinTools *g_pBinTools = NULL; IGameConfig *g_pGameConf = NULL; IGameHelpers *g_pGameHelpers = NULL; -IEngineSound *engsound = NULL; HandleType_t g_CallHandle = 0; HandleType_t g_TraceHandle = 0; @@ -47,6 +48,7 @@ SMEXT_LINK(&g_SdkTools); extern sp_nativeinfo_t g_CallNatives[]; extern sp_nativeinfo_t g_TENatives[]; extern sp_nativeinfo_t g_TRNatives[]; +extern sp_nativeinfo_t g_StringTableNatives[]; bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) { @@ -56,6 +58,7 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) sharesys->AddNatives(myself, g_TENatives); sharesys->AddNatives(myself, g_SoundNatives); sharesys->AddNatives(myself, g_TRNatives); + sharesys->AddNatives(myself, g_StringTableNatives); SM_GET_IFACE(GAMEHELPERS, g_pGameHelpers); @@ -107,6 +110,7 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool GET_V_IFACE_ANY(serverFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS); GET_V_IFACE_ANY(engineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); GET_V_IFACE_ANY(engineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER); + GET_V_IFACE_ANY(engineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER); return true; } diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h index 8f53e504..3dc7b6ee 100644 --- a/extensions/sdktools/extension.h +++ b/extensions/sdktools/extension.h @@ -66,12 +66,16 @@ public: //IConCommandBaseAccessor bool RegisterConCommandBase(ConCommandBase *pVar); }; +/* Interfaces from engine or gamedll */ extern IServerGameEnts *gameents; extern IEngineTrace *enginetrace; +extern IEngineSound *engsound; +extern INetworkStringTableContainer *netstringtables; +/* Interfaces from SourceMod */ extern IBinTools *g_pBinTools; extern IGameConfig *g_pGameConf; extern IGameHelpers *g_pGameHelpers; -extern IEngineSound *engsound; +/* Handle types */ extern HandleType_t g_CallHandle; extern HandleType_t g_TraceHandle; diff --git a/extensions/sdktools/msvc8/sdktools.vcproj b/extensions/sdktools/msvc8/sdktools.vcproj index fe390115..216d46ee 100644 --- a/extensions/sdktools/msvc8/sdktools.vcproj +++ b/extensions/sdktools/msvc8/sdktools.vcproj @@ -1,7 +1,7 @@ + + LockNetworkStringTables(lock) ? 1 : 0; +} + +static cell_t FindStringTable(IPluginContext *pContext, const cell_t *params) +{ + char *name; + pContext->LocalToString(params[1], &name); + + INetworkStringTable *pTable = netstringtables->FindTable(name); + + if (!pTable) + { + return INVALID_STRING_TABLE; + } + + return pTable->GetTableId(); +} + +static cell_t GetNumStringTables(IPluginContext *pContext, const cell_t *params) +{ + return netstringtables->GetNumTables(); +} + +static cell_t GetStringTableNumStrings(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + return pTable->GetNumStrings(); +} + +static cell_t GetStringTableMaxStrings(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + return pTable->GetMaxStrings(); +} + +static cell_t GetStringTableName(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + size_t numBytes; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + pContext->StringToLocalUTF8(params[2], params[3], pTable->GetTableName(), &numBytes); + + return numBytes; +} + +static cell_t FindStringIndex(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + char *str; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + pContext->LocalToString(params[2], &str); + + return pTable->FindStringIndex(str); +} + +static cell_t ReadStringTable(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + int stringidx; + const char *value; + size_t numBytes; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + stringidx = params[2]; + value = pTable->GetString(stringidx); + + if (!value) + { + return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); + } + + pContext->StringToLocalUTF8(params[3], params[4], value, &numBytes); + + return numBytes; +} + +static cell_t GetStringTableDataLength(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + int stringidx; + const void *userdata; + int datalen; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + stringidx = params[2]; + if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) + { + return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); + } + + userdata = pTable->GetStringUserData(stringidx, &datalen); + if (!userdata) + { + datalen = 0; + } + + return datalen; +} + +static cell_t GetStringTableData(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + int stringidx; + const char *userdata; + int datalen; + size_t numBytes; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + stringidx = params[2]; + if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) + { + return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); + } + + userdata = (const char *)pTable->GetStringUserData(stringidx, &datalen); + if (!userdata) + { + userdata = ""; + } + + pContext->StringToLocalUTF8(params[3], params[4], userdata, &numBytes); + + return numBytes; +} + +CON_COMMAND(sm_lockstate, "Lock state") +{ + bool save = engine->LockNetworkStringTables(false); + Msg("save: %d\n", save); + engine->LockNetworkStringTables(save); +} + +static cell_t SetStringTableData(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + int stringidx; + char *userdata; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + stringidx = params[2]; + if (stringidx < 0 || stringidx >= pTable->GetNumStrings()) + { + return pContext->ThrowNativeError("Invalid string index specified for table (index %d) (table \"%s\")", stringidx, pTable->GetTableName()); + } + + pContext->LocalToString(params[3], &userdata); + pTable->SetStringUserData(stringidx, params[4], userdata); + + return 1; +} + +static cell_t AddToStringTable(IPluginContext *pContext, const cell_t *params) +{ + TABLEID idx = static_cast(params[1]); + INetworkStringTable *pTable = netstringtables->GetTable(idx); + char *str, *userdata; + + if (!pTable) + { + return pContext->ThrowNativeError("Invalid string table index %d", idx); + } + + pContext->LocalToString(params[2], &str); + pContext->LocalToString(params[3], &userdata); + + pTable->AddString(str, params[4], userdata); + + return 1; +} + +sp_nativeinfo_t g_StringTableNatives[] = +{ + {"LockStringTables", LockStringTables}, + {"FindStringTable", FindStringTable}, + {"GetNumStringTables", GetNumStringTables}, + {"GetStringTableNumStrings", GetStringTableNumStrings}, + {"GetStringTableMaxStrings", GetStringTableMaxStrings}, + {"GetStringTableName", GetStringTableName}, + {"FindStringIndex", FindStringIndex}, + {"ReadStringTable", ReadStringTable}, + {"GetStringTableDataLength", GetStringTableDataLength}, + {"GetStringTableData", GetStringTableData}, + {"SetStringTableData", SetStringTableData}, + {"AddToStringTable", AddToStringTable}, + {NULL, NULL}, +}; diff --git a/plugins/include/sdktools.inc b/plugins/include/sdktools.inc index 223bbf3a..a68dd805 100644 --- a/plugins/include/sdktools.inc +++ b/plugins/include/sdktools.inc @@ -21,12 +21,13 @@ #include #include #include -#include -#include #if !defined SDKTOOLS_DISABLE_SOUNDAPI #include #endif +#include #include +#include +#include enum SDKCallType { diff --git a/plugins/include/sdktools_stringtables.inc b/plugins/include/sdktools_stringtables.inc new file mode 100644 index 00000000..ea42c331 --- /dev/null +++ b/plugins/include/sdktools_stringtables.inc @@ -0,0 +1,163 @@ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This file is part of the SourceMod/SourcePawn SDK. This file may only be used + * or modified under the Terms and Conditions of its License Agreement, which is found + * in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins + * may change at any time. To view the latest information, see: + * http://www.sourcemod.net/license.php + * + * Version: $Id$ + */ + +#if defined _sdktools_stringtables_included + #endinput +#endif +#define _sdktools_stringtables_included + +#define INVALID_STRING_TABLE -1 /**< An invalid string table index */ +#define INVALID_STRING_INDEX -1 /**< An invalid string index in a table */ + +/** + * Searches for a string table. + * + * @param name Name of string table to find. + * @return A string table index number if found, INVALID_STRING_TABLE otherwise. + */ +native FindStringTable(const String:name[]); + +/** + * Returns the number of string tables that currently exist. + * + * @return Number of string tables that currently exist. + */ +native GetNumStringTables(); + +/** + * Returns the number of strings that currently exist in a given string table. + * + * @param tableidx A string table index. + * @return Number of strings that currently exist. + * @error Invalid string table index. + */ +native GetStringTableNumStrings(tableidx); + +/** + * Returns the maximum number of strings that are allowed in a given string table. + * + * @param tableidx A string table index. + * @return Maximum number of strings allowed. + * @error Invalid string table index. + */ +native GetStringTableMaxStrings(tableidx); + +/** + * Retrieves the name of a string table. + * + * @param tableidx A string table index. + * @param name Buffer to store the name of the string table. + * @param maxlength Maximum length of string buffer. + * @return Number of bytes written to the buffer (UTF-8 safe). + * @error Invalid string table index. + */ +native GetStringTableName(tableidx, String:name[], maxlength); + +/** + * Searches for the index of a given string in a string table. + * + * @param tableidx A string table index. + * @param string String to find. + * @return String index if found, INVALID_STRING_INDEX otherwise. + * @error Invalid string table index. + */ +native FindStringIndex(tableidx, const String:str[]); + +/** + * Retrieves the string at a given index of a string table. + * + * @param tableidx A string table index. + * @param stringidx A string index. + * @param name Buffer to store the string value. + * @param maxlength Maximum length of string buffer. + * @return Number of bytes written to the buffer (UTF-8 safe). + * @error Invalid string table index or string index. + */ +native ReadStringTable(tableidx, stringIdx, String:str[], maxlength); + +/** + * Returns the length of the user data associated with a given string index. + * + * @param tableidx A string table index. + * @param stringidx A string index. + * @return Length of user data. This will be 0 if there is no user data. + * @error Invalid string table index or string index. + */ +native GetStringTableDataLength(tableidx, stringidx); + +/** + * Retrieves the user data associated with a given string index. + * + * @param tableidx A string table index. + * @param stringidx A string index. + * @param userdata Buffer to store the user data. This will be set to "" if there is no user data. + * @param maxlength Maximum length of string buffer. + * @return Number of bytes written to the buffer (UTF-8 safe). + * @error Invalid string table index or string index. + */ +native GetStringTableData(tableidx, stringIdx, String:userdata[], maxlength); + +/** + * Sets the user data associated with a given string index. + * + * @param tableidx A string table index. + * @param stringidx A string index. + * @param userdata User data string that will be set. + * @param length Length of user data string. This should include the null terminator. + * @return Number of bytes written to the buffer (UTF-8 safe). + * @error Invalid string table index or string index. + */ +native SetStringTableData(tableidx, stringIdx, const String:userdata[], length); + +/** + * Adds a string to a given string table. + * + * @param tableidx A string table index. + * @param string String to add. + * @param userdata An optional user data string. + * @param length Length of user data string. This should include the null terminator. + * If set to -1, then user data will be not be altered if the specified string + * already exists in the string table. + */ +native AddToStringTable(tableidx, const String:str[], const String:userdata[]="", length=-1); + +/** + * Locks or unlocks the network string tables. + * + * @param lock Determines whether network string tables should be locked. + * True means the tables should be locked for writing; false means unlocked. + * @return Previous lock state. + */ +native bool:LockStringTables(bool:lock); + +/** + * Adds a file to the downloadables network string table. + * This forces a client to download the file if they do not already have it. + * + * @param filename File that will be added to downloadables table. + */ +stock AddFileToDownloadTable(const String:filename[]) +{ + static table = INVALID_STRING_TABLE; + + if (table == INVALID_STRING_TABLE) + { + table = FindStringTable("downloadables"); + } + + new bool:save = LockStringTables(false); + AddToStringTable(table, filename); + LockStringTables(save); +}