From e63a5cd3dc56fd286fff635c315be755d86e216e Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Thu, 17 Apr 2008 04:58:09 +0000 Subject: [PATCH] Initial import of amb734 - Client preferences extension. --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402072 --- configs/databases.cfg | 11 + .../mysql/clientprefs-mysql.sql | 16 + .../sqlite/clientprefs-sqlite.sq3 | Bin 0 -> 6144 bytes .../sqlite/clientprefs-sqlite.sql | 15 + extensions/clientprefs/Makefile | 126 +++ extensions/clientprefs/cookie.cpp | 304 +++++++ extensions/clientprefs/cookie.h | 129 +++ extensions/clientprefs/extension.cpp | 173 ++++ extensions/clientprefs/extension.h | 143 ++++ extensions/clientprefs/msvc8/clientprefs.sln | 38 + .../clientprefs/msvc8/clientprefs.vcproj | 742 ++++++++++++++++++ extensions/clientprefs/natives.cpp | 164 ++++ extensions/clientprefs/query.cpp | 107 +++ extensions/clientprefs/query.h | 76 ++ extensions/clientprefs/sdk/smsdk_config.h | 81 ++ extensions/clientprefs/sdk/smsdk_ext.cpp | 455 +++++++++++ extensions/clientprefs/sdk/smsdk_ext.h | 327 ++++++++ extensions/clientprefs/svn_version.h | 42 + extensions/clientprefs/svn_version.tpl | 42 + extensions/clientprefs/version.rc | 104 +++ plugins/include/clientprefs.inc | 108 +++ plugins/testsuite/clientprefstest.sp | 26 + tools/builder/PkgCore.cs | 7 + 23 files changed, 3236 insertions(+) create mode 100644 configs/sql-init-scripts/mysql/clientprefs-mysql.sql create mode 100644 configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 create mode 100644 configs/sql-init-scripts/sqlite/clientprefs-sqlite.sql create mode 100644 extensions/clientprefs/Makefile create mode 100644 extensions/clientprefs/cookie.cpp create mode 100644 extensions/clientprefs/cookie.h create mode 100644 extensions/clientprefs/extension.cpp create mode 100644 extensions/clientprefs/extension.h create mode 100644 extensions/clientprefs/msvc8/clientprefs.sln create mode 100644 extensions/clientprefs/msvc8/clientprefs.vcproj create mode 100644 extensions/clientprefs/natives.cpp create mode 100644 extensions/clientprefs/query.cpp create mode 100644 extensions/clientprefs/query.h create mode 100644 extensions/clientprefs/sdk/smsdk_config.h create mode 100644 extensions/clientprefs/sdk/smsdk_ext.cpp create mode 100644 extensions/clientprefs/sdk/smsdk_ext.h create mode 100644 extensions/clientprefs/svn_version.h create mode 100644 extensions/clientprefs/svn_version.tpl create mode 100644 extensions/clientprefs/version.rc create mode 100644 plugins/include/clientprefs.inc create mode 100644 plugins/testsuite/clientprefstest.sp diff --git a/configs/databases.cfg b/configs/databases.cfg index 07faf188..22643aa9 100644 --- a/configs/databases.cfg +++ b/configs/databases.cfg @@ -18,4 +18,15 @@ "driver" "sqlite" "database" "sourcemod-local" } + + "clientprefs" + { + "driver" "default" + "host" "localhost" + "database" "clientprefs-sqlite" + "user" "root" + "pass" "" + //"timeout" "0" + //"port" "0" + } } diff --git a/configs/sql-init-scripts/mysql/clientprefs-mysql.sql b/configs/sql-init-scripts/mysql/clientprefs-mysql.sql new file mode 100644 index 00000000..08ce04b8 --- /dev/null +++ b/configs/sql-init-scripts/mysql/clientprefs-mysql.sql @@ -0,0 +1,16 @@ +CREATE TABLE sm_cookies +( + id INTEGER unsigned NOT NULL auto_increment, + name varchar(30) NOT NULL UNIQUE, + description varchar(255), + PRIMARY KEY (id) +); + +CREATE TABLE sm_cookie_cache +( + player varchar(65) NOT NULL, + cookie_id int(10) NOT NULL, + value varchar(100), + timestamp int NOT NULL, + PRIMARY KEY (player, cookie_id) +); diff --git a/configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 b/configs/sql-init-scripts/sqlite/clientprefs-sqlite.sq3 new file mode 100644 index 0000000000000000000000000000000000000000..491062a19ede7fef1cdffb5565ce904c53e549e3 GIT binary patch literal 6144 zcmeH}&u@Y-6vtaYmzi)}Jgy#=K=hz9?zUuZA%;xx7alw;q{A+f2`ELg9k)MVf6xAd zo%SE?Fglfh9u}^oBqV*W-}lP<^fhHX>^dPqPk!Ly5H*1WAOtrE0RV*PO+L(q2}g3A za32q4@dp&(ClJrYFX0=03LnQB?#V{rZ7iLXt5x{^5aP!Lp{`~7{6>~ZE#@EaiCnaRAlr`WK6oKifL^aI10PC=SFTV=~<$*@jcHS`*JEyKH+?N+U^Y6%V_l7D?5&3wTnlRN(tr z8Z(WTrb0T?ek16XYeY;pOs%7hP_q2?#O&)v6xq`Zld)kd#sr%QzG!0T!->W;GeYga zS%!}9#nQ`Gi-Btj#d4?eFF2ZDM#ZS(B$>6Hl&$x;niJpz@&1 | cut -b1) +ifeq "$(GCC_VERSION)" "4" + CFLAGS += $(C_GCC4_FLAGS) + CPPFLAGS += $(CPP_GCC4_FLAGS) +endif + +BINARY = $(PROJECT).ext.so + +OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) + +$(BIN_DIR)/%.o: %.cpp + $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< + +all: check + mkdir -p $(BIN_DIR)/sdk + if [ "$(USEMETA)" == "true" ]; then \ + ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so; \ + ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so; \ + fi + $(MAKE) -f Makefile extension + +check: + if [ "$(USEMETA)" == "true" ] && [ "$(ENGSET)" == "false" ]; then \ + echo "You must supply ENGINE=orangebox or ENGINE=original"; \ + exit 1; \ + fi + +extension: check $(OBJ_LINUX) + $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) + +debug: + $(MAKE) -f Makefile all DEBUG=true + +default: all + +clean: check + rm -rf $(BIN_DIR)/*.o + rm -rf $(BIN_DIR)/sdk/*.o + rm -rf $(BIN_DIR)/$(BINARY) diff --git a/extensions/clientprefs/cookie.cpp b/extensions/clientprefs/cookie.cpp new file mode 100644 index 00000000..d13e7a1e --- /dev/null +++ b/extensions/clientprefs/cookie.cpp @@ -0,0 +1,304 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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$ + */ + +#include "cookie.h" +#include "query.h" + +CookieManager g_CookieManager; + +CookieManager::CookieManager() +{ + for (int i=0; i<=MAXCLIENTS; i++) + { + connected[i] = false; + statsLoaded[i] = false; + } + + cookiesLoadedForward = NULL; +} +CookieManager::~CookieManager(){} + +void CookieManager::Unload() +{ + /* If clients are connected we should try save their data */ + + int maxclients = playerhelpers->GetMaxClients(); + + for (int i=1; i<=maxclients; i++) + { + if (connected[i]) + { + OnClientDisconnecting(i); + } + } + + /* Find all cookies and delete them */ + + SourceHook::List::iterator _iter; + + Cookie *current; + + _iter = cookieList.begin(); + + while (_iter != cookieList.end()) + { + current = (Cookie *)*_iter; + + if (current == NULL) + { + _iter++; + continue; + } + + delete current; + + _iter = cookieList.erase(_iter); + } +} + +Cookie *CookieManager::FindCookie(const char *name) +{ + Cookie **pCookie = cookieTrie.retrieve(name); + + if (pCookie == NULL) + { + return NULL; + } + + return *pCookie; +} + + +Cookie *CookieManager::CreateCookie(const char *name, const char *description) +{ + Cookie *pCookie = FindCookie(name); + + /* Check if cookie already exists */ + if (pCookie != NULL) + { + return pCookie; + } + + /* First time cookie - Create from scratch */ + pCookie = new Cookie(name, description); + cookieTrie.insert(name, pCookie); + cookieList.push_back(pCookie); + + + /* Attempt to load cookie from the db and get its ID num */ + g_ClientPrefs.Query_InsertCookie->BindParamString(0, name, true); + g_ClientPrefs.Query_InsertCookie->BindParamString(1, description, true); + TQueryOp *op = new TQueryOp(g_ClientPrefs.Database, g_ClientPrefs.Query_InsertCookie, Query_InsertCookie, pCookie); + dbi->AddToThreadQueue(op, PrioQueue_Normal); + + return pCookie; +} + +bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value) +{ + if (pCookie == NULL) + { + return false; + } + + CookieData *data = pCookie->data[client]; + + /* Check if a value has been set before */ + if (data == NULL) + { + data = new CookieData(""); + data->parent = pCookie; + clientData[client].push_back(data); + pCookie->data[client] = data; + data->changed = true; + } + + *value = &data->value[0]; + + return true; +} + +bool CookieManager::SetCookieValue(Cookie *pCookie, int client, char *value) +{ + if (pCookie == NULL) + { + return false; + } + + CookieData *data = pCookie->data[client]; + + if (data == NULL) + { + data = new CookieData(value); + data->parent = pCookie; + clientData[client].push_back(data); + pCookie->data[client] = data; + } + else + { + strncpy(data->value, value, MAX_VALUE_LENGTH); + data->value[MAX_VALUE_LENGTH-1] = '\0'; + } + + data->changed = true; + + return true; +} + +void CookieManager::OnClientAuthorized(int client, const char *authstring) +{ + connected[client] = true; + + g_ClientPrefs.Query_SelectData->BindParamString(0, authstring, true); + TQueryOp *op = new TQueryOp(g_ClientPrefs.Database, g_ClientPrefs.Query_SelectData, Query_SelectData, client); + dbi->AddToThreadQueue(op, PrioQueue_Normal); +} + +void CookieManager::OnClientDisconnecting(int client) +{ + connected[client] = false; + statsLoaded[client] = false; + + SourceHook::List::iterator _iter; + + CookieData *current; + + _iter = clientData[client].begin(); + + while (_iter != clientData[client].end()) + { + current = (CookieData *)*_iter; + + if (!current->changed) + { + _iter = clientData[client].erase(_iter); + continue; + } + + /* Save this cookie to the database */ + IGamePlayer *player = playerhelpers->GetGamePlayer(client); + + if (player == NULL) + { + /* panic! */ + return; + } + + int dbId = current->parent->dbid; + + if (dbId == -1) + { + /* Insert/Find Query must be still running or failed. */ + return; + } + + g_ClientPrefs.Query_InsertData->BindParamString(0, player->GetAuthString(), true); + g_ClientPrefs.Query_InsertData->BindParamInt(1, dbId, false); + g_ClientPrefs.Query_InsertData->BindParamString(2, current->value, true); + g_ClientPrefs.Query_InsertData->BindParamInt(3, time(NULL), false); + + if (driver == DRIVER_MYSQL) + { + g_ClientPrefs.Query_InsertData->BindParamString(4, current->value, true); + g_ClientPrefs.Query_InsertData->BindParamInt(5, time(NULL), false); + } + + TQueryOp *op = new TQueryOp(g_ClientPrefs.Database, g_ClientPrefs.Query_InsertData, Query_InsertData, client); + dbi->AddToThreadQueue(op, PrioQueue_Normal); + + current->parent->data[client] = NULL; + delete current; + + _iter = clientData[client].erase(_iter); + } +} + +void CookieManager::ClientConnectCallback(int client, IPreparedQuery *data) +{ + IResultSet *results = data->GetResultSet(); + if (results == NULL) + { + return; + } + + do + { + IResultRow *row = results->FetchRow(); + + if (row == NULL) + { + continue; + } + + const char *name; + row->GetString(0, &name, NULL); + + const char *value; + row->GetString(1, &value, NULL); + + CookieData *pData = new CookieData(value); + pData->changed = false; + + Cookie *parent = FindCookie(name); + + if (parent == NULL) + { + const char *desc; + row->GetString(2, &desc, NULL); + + parent = CreateCookie(name, desc); + cookieTrie.insert(name, parent); + cookieList.push_back(parent); + } + + pData->parent = parent; + parent->data[client] = pData; + + clientData[client].push_back(pData); + + } while (results->MoreRows()); + + statsLoaded[client] = true; + + cookiesLoadedForward->PushCell(client); + cookiesLoadedForward->Execute(NULL); +} + +void CookieManager::InsertCookieCallback(Cookie *pCookie, int dbId) +{ + pCookie->dbid = dbId; +} + +bool CookieManager::AreClientCookiesCached(int client) +{ + return statsLoaded[client]; +} + diff --git a/extensions/clientprefs/cookie.h b/extensions/clientprefs/cookie.h new file mode 100644 index 00000000..c9425108 --- /dev/null +++ b/extensions/clientprefs/cookie.h @@ -0,0 +1,129 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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_CLIENTPREFS_COOKIE_H_ +#define _INCLUDE_SOURCEMOD_CLIENTPREFS_COOKIE_H_ + +#include "extension.h" +#include "sh_list.h" +#include "sm_trie_tpl.h" + + +#define MAX_NAME_LENGTH 30 +#define MAX_DESC_LENGTH 255 +#define MAX_VALUE_LENGTH 100 + +struct Cookie; + +struct CookieData +{ + CookieData(const char *value) + { + strncpy(this->value, value, MAX_VALUE_LENGTH); + this->value[MAX_VALUE_LENGTH-1] = '\0'; + } + + char value[MAX_VALUE_LENGTH]; + bool changed; + Cookie *parent; +}; + +struct Cookie +{ + Cookie(const char *name, const char *description) + { + strncpy(this->name, name, MAX_NAME_LENGTH); + this->name[MAX_NAME_LENGTH-1] = '\0'; + strncpy(this->description, description, MAX_DESC_LENGTH); + this->description[MAX_DESC_LENGTH-1] = '\0'; + + dbid = -1; + + for (int i=0; i<=MAXCLIENTS; i++) + { + data[i] = NULL; + } + } + + ~Cookie() + { + for (int i=0; i<=MAXCLIENTS; i++) + { + if (data[i] != NULL) + { + delete data[i]; + } + } + } + + char name[MAX_NAME_LENGTH]; + char description[MAX_DESC_LENGTH]; + int dbid; + CookieData *data[MAXCLIENTS+1]; +}; + + +class CookieManager : public IClientListener +{ +public: + CookieManager(); + ~CookieManager(); + + void OnClientAuthorized(int client, const char *authstring); + void OnClientDisconnecting(int client); + + bool GetCookieValue(Cookie *pCookie, int client, char **value); + bool SetCookieValue(Cookie *pCookie, int client, char *value); + + void Unload(); + + void ClientConnectCallback(int client, IPreparedQuery *data); + void InsertCookieCallback(Cookie *pCookie, int dbId); + + Cookie *FindCookie(const char *name); + Cookie *CreateCookie(const char *name, const char *description); + + bool AreClientCookiesCached(int client); + + IForward *cookiesLoadedForward; + +private: + SourceHook::List cookieList; + KTrie cookieTrie; + SourceHook::List clientData[MAXCLIENTS]; + + bool connected[MAXCLIENTS+1]; + bool statsLoaded[MAXCLIENTS+1]; +}; + +extern CookieManager g_CookieManager; + +#endif // _INCLUDE_SOURCEMOD_CLIENTPREFS_COOKIE_H_ diff --git a/extensions/clientprefs/extension.cpp b/extensions/clientprefs/extension.cpp new file mode 100644 index 00000000..5599d34b --- /dev/null +++ b/extensions/clientprefs/extension.cpp @@ -0,0 +1,173 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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$ + */ + +#include "extension.h" + +/** + * @file extension.cpp + * @brief Implement extension code here. + */ + +ClientPrefs g_ClientPrefs; /**< Global singleton for extension's main interface */ + +SMEXT_LINK(&g_ClientPrefs); + +HandleType_t g_CookieType = 0; +CookieTypeHandler g_CookieTypeHandler; + + +int driver = 0; + +bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late) +{ + const DatabaseInfo *DBInfo = dbi->FindDatabaseConf("clientprefs"); + + if (DBInfo == NULL) + { + DBInfo = dbi->FindDatabaseConf("default"); + + if (DBInfo == NULL) + { + snprintf(error, maxlength, "Could not find \"clientprefs\" or \"default\" database configs"); + return false; + } + + } + + if (DBInfo->driver[0] != '\0') + { + Driver = dbi->FindOrLoadDriver(DBInfo->driver); + } + else + { + Driver = dbi->GetDefaultDriver(); + } + + if (Driver == NULL) + { + snprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver); + return false; + } + + Database = Driver->Connect(DBInfo, true, error, maxlength); + + if (Database == NULL) + { + return false; + } + + const char *identifier = Driver->GetIdentifier(); + + if (strcmp(identifier, "sqlite") == 0) + { + driver = DRIVER_SQLITE; + } + else if (strcmp(identifier, "mysql") == 0) + { + driver = DRIVER_MYSQL; + } + else + { + snprintf(error, maxlength, "Unsupported driver \"%s\"", identifier); + return false; + } + + if (driver == DRIVER_SQLITE) + { + Query_InsertCookie = Database->PrepareQuery("INSERT OR IGNORE INTO sm_cookies(name, description) VALUES(?, ?)", error, maxlength); + } + else + { + Query_InsertCookie = Database->PrepareQuery("INSERT IGNORE INTO sm_cookies(name, description) VALUES(?, ?)", error, maxlength); + } + + if (Query_InsertCookie == NULL) + { + return false; + } + + Query_SelectData = Database->PrepareQuery("SELECT sm_cookies.name, sm_cookie_cache.value, sm_cookies.description FROM sm_cookies JOIN sm_cookie_cache ON sm_cookies.id = sm_cookie_cache.cookie_id WHERE player = ?", error, maxlength); + + if (Query_SelectData == NULL) + { + return false; + } + + if (driver == DRIVER_SQLITE) + { + Query_InsertData = Database->PrepareQuery("INSERT OR REPLACE INTO sm_cookie_cache(player,cookie_id, value, timestamp) VALUES(?, ?, ?, ?)", error, maxlength); + } + else + { + Query_InsertData = Database->PrepareQuery("INSERT INTO sm_cookie_cache(player,cookie_id, value, timestamp) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE value = ?, timestamp = ?", error, maxlength); + } + + if (Query_InsertData == NULL) + { + return false; + } + + sharesys->AddNatives(myself, g_ClientPrefNatives); + sharesys->RegisterLibrary(myself, "clientprefs"); + g_CookieManager.cookiesLoadedForward = forwards->CreateForward("OnClientCookiesLoaded", ET_Ignore, 1, NULL, Param_Cell); + + g_CookieType = handlesys->CreateType("Cookie", + &g_CookieTypeHandler, + 0, + NULL, + NULL, + myself->GetIdentity(), + NULL); + + return true; +} + +void ClientPrefs::SDK_OnAllLoaded() +{ + playerhelpers->AddClientListener(&g_CookieManager); +} + +void ClientPrefs::SDK_OnUnload() +{ + handlesys->RemoveType(g_CookieType, myself->GetIdentity()); + + g_CookieManager.Unload(); + + Query_InsertCookie->Destroy(); + Query_InsertData->Destroy(); + Query_SelectData->Destroy(); + + Database->Close(); + + forwards->ReleaseForward(g_CookieManager.cookiesLoadedForward); +} + + diff --git a/extensions/clientprefs/extension.h b/extensions/clientprefs/extension.h new file mode 100644 index 00000000..0f1ccc90 --- /dev/null +++ b/extensions/clientprefs/extension.h @@ -0,0 +1,143 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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_EXTENSION_PROPER_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ + +#define MAXCLIENTS 64 + +#include "smsdk_ext.h" +#include "cookie.h" + +#define DRIVER_MYSQL 1 +#define DRIVER_SQLITE 0 + +/** + * @brief Sample implementation of the SDK Extension. + * Note: Uncomment one of the pre-defined virtual functions in order to use it. + */ +class ClientPrefs : public SDKExtension +{ +public: + /** + * @brief This is called after the initial loading sequence has been processed. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @param late Whether or not the module was loaded after map load. + * @return True to succeed loading, false to fail. + */ + virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); + + /** + * @brief This is called right before the extension is unloaded. + */ + virtual void SDK_OnUnload(); + + /** + * @brief This is called once all known extensions have been loaded. + * Note: It is is a good idea to add natives here, if any are provided. + */ + virtual void SDK_OnAllLoaded(); + + /** + * @brief Called when the pause state is changed. + */ + //virtual void SDK_OnPauseChange(bool paused); + + /** + * @brief this is called when Core wants to know if your extension is working. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @return True if working, false otherwise. + */ + //virtual bool QueryRunning(char *error, size_t maxlength); +public: +#if defined SMEXT_CONF_METAMOD + /** + * @brief Called when Metamod is attached, before the extension version is called. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @param late Whether or not Metamod considers this a late load. + * @return True to succeed, false to fail. + */ + //virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); + + /** + * @brief Called when Metamod is detaching, after the extension version is called. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); + + /** + * @brief Called when Metamod's pause state is changing. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param paused Pause state being set. + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); +#endif +public: + IDBDriver *Driver; + IDatabase *Database; + + IPreparedQuery *Query_InsertCookie; + IPreparedQuery *Query_SelectData; + IPreparedQuery *Query_InsertData; +}; + +class CookieTypeHandler : public IHandleTypeDispatch +{ +public: + void OnHandleDestroy(HandleType_t type, void *object) + { + /* No delete needed since this Cookies are persistant */ + } +}; + +extern sp_nativeinfo_t g_ClientPrefNatives[]; + +extern ClientPrefs g_ClientPrefs; +extern HandleType_t g_CookieType; +extern CookieTypeHandler g_CookieTypeHandler; + +extern int driver; + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/extensions/clientprefs/msvc8/clientprefs.sln b/extensions/clientprefs/msvc8/clientprefs.sln new file mode 100644 index 00000000..d437656f --- /dev/null +++ b/extensions/clientprefs/msvc8/clientprefs.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clientprefs", "clientprefs.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug - Episode 1|Win32 = Debug - Episode 1|Win32 + Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32 + Debug - Orange Box|Win32 = Debug - Orange Box|Win32 + Debug|Win32 = Debug|Win32 + Release - Episode 1|Win32 = Release - Episode 1|Win32 + Release - Old Metamod|Win32 = Release - Old Metamod|Win32 + Release - Orange Box|Win32 = Release - Orange Box|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32 + {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extensions/clientprefs/msvc8/clientprefs.vcproj b/extensions/clientprefs/msvc8/clientprefs.vcproj new file mode 100644 index 00000000..86b35b0b --- /dev/null +++ b/extensions/clientprefs/msvc8/clientprefs.vcproj @@ -0,0 +1,742 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extensions/clientprefs/natives.cpp b/extensions/clientprefs/natives.cpp new file mode 100644 index 00000000..8edab7bd --- /dev/null +++ b/extensions/clientprefs/natives.cpp @@ -0,0 +1,164 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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$ + */ + +#include "extension.h" +#include "cookie.h" + +cell_t RegClientPrefCookie(IPluginContext *pContext, const cell_t *params) +{ + char *name; + pContext->LocalToString(params[1], &name); + + if (name[0] == '\0') + { + return pContext->ThrowNativeError("Cannot create preference cookie with no name"); + } + + char *desc; + pContext->LocalToString(params[2], &desc); + + Cookie *pCookie = g_CookieManager.CreateCookie(name, desc); + + if (!pCookie) + { + return BAD_HANDLE; + } + + return handlesys->CreateHandle(g_CookieType, + pCookie, + pContext->GetIdentity(), + myself->GetIdentity(), + NULL); +} + +cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params) +{ + char *name; + pContext->LocalToString(params[1], &name); + + Cookie *pCookie = g_CookieManager.FindCookie(name); + + if (!pCookie) + { + return BAD_HANDLE; + } + + return handlesys->CreateHandle(g_CookieType, + pCookie, + pContext->GetIdentity(), + myself->GetIdentity(), + NULL); +} + +cell_t SetClientPrefCookie(IPluginContext *pContext, const cell_t *params) +{ + int client = params[1]; + + if ((client < 1) || (client > playerhelpers->GetMaxClients())) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + + Handle_t hndl = static_cast(params[2]); + HandleError err; + HandleSecurity sec; + + sec.pOwner = NULL; + sec.pIdentity = myself->GetIdentity(); + + Cookie *pCookie; + + if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err); + } + + char *value; + pContext->LocalToString(params[3], &value); + + return g_CookieManager.SetCookieValue(pCookie, client, value); +} + +cell_t GetClientPrefCookie(IPluginContext *pContext, const cell_t *params) +{ + int client = params[1]; + + if ((client < 1) || (client > playerhelpers->GetMaxClients())) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + + Handle_t hndl = static_cast(params[2]); + HandleError err; + HandleSecurity sec; + + sec.pOwner = NULL; + sec.pIdentity = myself->GetIdentity(); + + Cookie *pCookie; + + if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err); + } + + char *value = NULL; + + g_CookieManager.GetCookieValue(pCookie, client, &value); + + pContext->StringToLocal(params[3], params[4], value); + + return 1; +} + +cell_t AreClientCookiesCached(IPluginContext *pContext, const cell_t *params) +{ + int client = params[1]; + + if ((client < 1) || (client > playerhelpers->GetMaxClients())) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + + return g_CookieManager.AreClientCookiesCached(client); +} + +sp_nativeinfo_t g_ClientPrefNatives[] = +{ + {"RegClientPrefCookie", RegClientPrefCookie}, + {"FindClientPrefCookie", FindClientPrefCookie}, + {"SetClientPrefCookie", SetClientPrefCookie}, + {"GetClientPrefCookie", GetClientPrefCookie}, + {"AreClientCookiesCached", AreClientCookiesCached}, + {NULL, NULL} +}; diff --git a/extensions/clientprefs/query.cpp b/extensions/clientprefs/query.cpp new file mode 100644 index 00000000..e9fb1ead --- /dev/null +++ b/extensions/clientprefs/query.cpp @@ -0,0 +1,107 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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$ + */ + +#include "query.h" + + +void TQueryOp::RunThinkPart() +{ + //handler for threaded sql queries + + if (m_pQuery) + { + switch (m_type) + { + case Query_InsertCookie: + g_CookieManager.InsertCookieCallback(pCookie, m_insertId); + break; + case Query_SelectData: + g_CookieManager.ClientConnectCallback(m_client, m_pQuery); + break; + case Query_InsertData: + g_pSM->LogMessage(myself, "Inserted data into table"); + //No specific handling + break; + default: + break; + } + } + else + { + g_pSM->LogError(myself,"Failed SQL Query Error: \"%s\"- Ref Id: %i, Client num: %i",error ,m_type, m_client); + } +} + +void TQueryOp::RunThreadPart() +{ + m_pDatabase->LockForFullAtomicOperation(); + if (!m_pQuery->Execute()) + { + g_pSM->LogError(myself, m_pQuery->GetError()); + } + + m_insertId = m_pQuery->GetInsertID(); + + m_pDatabase->UnlockFromFullAtomicOperation(); +} + +IDBDriver *TQueryOp::GetDriver() +{ + return m_pDatabase->GetDriver(); +} +IdentityToken_t *TQueryOp::GetOwner() +{ + return myself->GetIdentity(); +} +void TQueryOp::Destroy() +{ + delete this; +} + +TQueryOp::TQueryOp(IDatabase *db, IPreparedQuery *query, enum querytype type, int client) +{ + m_pDatabase = db; + m_pQuery = query; + m_type = type; + m_client = client; + + m_pDatabase->IncReferenceCount(); +} + +TQueryOp::TQueryOp(IDatabase *db, IPreparedQuery *query, enum querytype type, Cookie *cookie) +{ + m_pDatabase = db; + m_pQuery = query; + m_type = type; + pCookie = cookie; + + m_pDatabase->IncReferenceCount(); +} diff --git a/extensions/clientprefs/query.h b/extensions/clientprefs/query.h new file mode 100644 index 00000000..2aa87b48 --- /dev/null +++ b/extensions/clientprefs/query.h @@ -0,0 +1,76 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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_CLIENTPREFS_QUERY_H_ +#define _INCLUDE_SOURCEMOD_CLIENTPREFS_QUERY_H_ + +#include "extension.h" +#include "cookie.h" +#include "sh_string.h" + +enum querytype +{ + Query_InsertCookie = 0, + Query_SelectData, + Query_InsertData, +}; + +class TQueryOp : public IDBThreadOperation +{ +public: + TQueryOp(IDatabase *db, IPreparedQuery *query, enum querytype type, int client); + TQueryOp(IDatabase *db, IPreparedQuery *query, enum querytype type, Cookie *cookie); + ~TQueryOp() {} + + IDBDriver *GetDriver(); + IdentityToken_t *GetOwner(); + + void Destroy(); + + void RunThreadPart(); + /* Thread has been cancelled due to driver unloading. Nothing else to do? */ + void CancelThinkPart() + { + } + void RunThinkPart(); + +private: + IDatabase *m_pDatabase; + IPreparedQuery *m_pQuery; + char error[255]; + enum querytype m_type; + int m_client; + int m_insertId; + Cookie *pCookie; +}; + + +#endif // _INCLUDE_SOURCEMOD_CLIENTPREFS_QUERY_H_ diff --git a/extensions/clientprefs/sdk/smsdk_config.h b/extensions/clientprefs/sdk/smsdk_config.h new file mode 100644 index 00000000..d85a467e --- /dev/null +++ b/extensions/clientprefs/sdk/smsdk_config.h @@ -0,0 +1,81 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Client Preferences Extension + * 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_EXTENSION_CONFIG_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ + +/** + * @file smsdk_config.h + * @brief Contains macros for configuring basic extension information. + */ + +#include "svn_version.h" + +/* Basic information exposed publicly */ +#define SMEXT_CONF_NAME "Client Preferences Extension" +#define SMEXT_CONF_DESCRIPTION "Saves client preference settings" +#define SMEXT_CONF_VERSION SVN_FULL_VERSION +#define SMEXT_CONF_AUTHOR "AlliedModders" +#define SMEXT_CONF_URL "http://www.sourcemod.net/" +#define SMEXT_CONF_LOGTAG "CLIENTPREFS" +#define SMEXT_CONF_LICENSE "GPL" +#define SMEXT_CONF_DATESTRING __DATE__ + +/** + * @brief Exposes plugin's main interface. + */ +#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name; + +/** + * @brief Sets whether or not this plugin required Metamod. + * NOTE: Uncomment to enable, comment to disable. + */ +//#define SMEXT_CONF_METAMOD + +/** Enable interfaces you want to use here by uncommenting lines */ +#define SMEXT_ENABLE_FORWARDSYS +#define SMEXT_ENABLE_HANDLESYS +#define SMEXT_ENABLE_PLAYERHELPERS +#define SMEXT_ENABLE_DBMANAGER +//#define SMEXT_ENABLE_GAMECONF +//#define SMEXT_ENABLE_MEMUTILS +//#define SMEXT_ENABLE_GAMEHELPERS +//#define SMEXT_ENABLE_TIMERSYS +//#define SMEXT_ENABLE_THREADER +//#define SMEXT_ENABLE_LIBSYS +//#define SMEXT_ENABLE_MENUS +//#define SMEXT_ENABLE_ADTFACTORY +//#define SMEXT_ENABLE_PLUGINSYS +//#define SMEXT_ENABLE_ADMINSYS +//#define SMEXT_ENABLE_TEXTPARSERS +//#define SMEXT_ENABLE_USERMSGS + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ diff --git a/extensions/clientprefs/sdk/smsdk_ext.cpp b/extensions/clientprefs/sdk/smsdk_ext.cpp new file mode 100644 index 00000000..674e04e4 --- /dev/null +++ b/extensions/clientprefs/sdk/smsdk_ext.cpp @@ -0,0 +1,455 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Base Extension Code + * 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$ + */ + +#include +#include +#include "smsdk_ext.h" + +/** + * @file smsdk_ext.cpp + * @brief Contains wrappers for making Extensions easier to write. + */ + +IExtension *myself = NULL; /**< Ourself */ +IShareSys *g_pShareSys = NULL; /**< Share system */ +IShareSys *sharesys = NULL; /**< Share system */ +ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ +ISourceMod *smutils = NULL; /**< SourceMod helpers */ + +#if defined SMEXT_ENABLE_FORWARDSYS +IForwardManager *g_pForwards = NULL; /**< Forward system */ +IForwardManager *forwards = NULL; /**< Forward system */ +#endif +#if defined SMEXT_ENABLE_HANDLESYS +IHandleSys *g_pHandleSys = NULL; /**< Handle system */ +IHandleSys *handlesys = NULL; /**< Handle system */ +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS +IPlayerManager *playerhelpers = NULL; /**< Player helpers */ +#endif //SMEXT_ENABLE_PLAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +IDBManager *dbi = NULL; /**< DB Manager */ +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +IGameConfigManager *gameconfs = NULL; /**< Game config manager */ +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_MEMUTILS +IMemoryUtils *memutils = NULL; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMEHELPERS +IGameHelpers *gamehelpers = NULL; +#endif +#if defined SMEXT_ENABLE_TIMERSYS +ITimerSystem *timersys = NULL; +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +IADTFactory *adtfactory = NULL; +#endif +#if defined SMEXT_ENABLE_THREADER +IThreader *threader = NULL; +#endif +#if defined SMEXT_ENABLE_LIBSYS +ILibrarySys *libsys = NULL; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +SourceMod::IPluginManager *plsys; +#endif +#if defined SMEXT_ENABLE_MENUS +IMenuManager *menus = NULL; +#endif +#if defined SMEXT_ENABLE_ADMINSYS +IAdminSystem *adminsys = NULL; +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS +ITextParsers *textparsers = NULL; +#endif +#if defined SMEXT_ENABLE_USERMSGS +IUserMessages *usermsgs = NULL; +#endif + +/** Exports the main interface */ +PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() +{ + return g_pExtensionIface; +} + +SDKExtension::SDKExtension() +{ +#if defined SMEXT_CONF_METAMOD + m_SourceMMLoaded = false; + m_WeAreUnloaded = false; + m_WeGotPauseChange = false; +#endif +} + +bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) +{ + g_pShareSys = sharesys = sys; + myself = me; + +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; + + if (!m_SourceMMLoaded) + { + if (error) + { + snprintf(error, maxlength, "Metamod attach failed"); + } + return false; + } +#endif + SM_GET_IFACE(SOURCEMOD, g_pSM); + smutils = g_pSM; +#if defined SMEXT_ENABLE_HANDLESYS + SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); + handlesys = g_pHandleSys; +#endif +#if defined SMEXT_ENABLE_FORWARDSYS + SM_GET_IFACE(FORWARDMANAGER, g_pForwards); + forwards = g_pForwards; +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS + SM_GET_IFACE(PLAYERMANAGER, playerhelpers); +#endif +#if defined SMEXT_ENABLE_DBMANAGER + SM_GET_IFACE(DBI, dbi); +#endif +#if defined SMEXT_ENABLE_GAMECONF + SM_GET_IFACE(GAMECONFIG, gameconfs); +#endif +#if defined SMEXT_ENABLE_MEMUTILS + SM_GET_IFACE(MEMORYUTILS, memutils); +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS + SM_GET_IFACE(GAMEHELPERS, gamehelpers); +#endif +#if defined SMEXT_ENABLE_TIMERSYS + SM_GET_IFACE(TIMERSYS, timersys); +#endif +#if defined SMEXT_ENABLE_ADTFACTORY + SM_GET_IFACE(ADTFACTORY, adtfactory); +#endif +#if defined SMEXT_ENABLE_THREADER + SM_GET_IFACE(THREADER, threader); +#endif +#if defined SMEXT_ENABLE_LIBSYS + SM_GET_IFACE(LIBRARYSYS, libsys); +#endif +#if defined SMEXT_ENABLE_PLUGINSYS + SM_GET_IFACE(PLUGINSYSTEM, plsys); +#endif +#if defined SMEXT_ENABLE_MENUS + SM_GET_IFACE(MENUMANAGER, menus); +#endif +#if defined SMEXT_ENABLE_ADMINSYS + SM_GET_IFACE(ADMINSYS, adminsys); +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS + SM_GET_IFACE(TEXTPARSERS, textparsers); +#endif +#if defined SMEXT_ENABLE_USERMSGS + SM_GET_IFACE(USERMSGS, usermsgs); +#endif + + if (SDK_OnLoad(error, maxlength, late)) + { +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; +#endif + return true; + } + + return false; +} + +bool SDKExtension::IsMetamodExtension() +{ +#if defined SMEXT_CONF_METAMOD + return true; +#else + return false; +#endif +} + +void SDKExtension::OnExtensionPauseChange(bool state) +{ +#if defined SMEXT_CONF_METAMOD + m_WeGotPauseChange = true; +#endif + SDK_OnPauseChange(state); +} + +void SDKExtension::OnExtensionsAllLoaded() +{ + SDK_OnAllLoaded(); +} + +void SDKExtension::OnExtensionUnload() +{ +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; +#endif + SDK_OnUnload(); +} + +const char *SDKExtension::GetExtensionAuthor() +{ + return SMEXT_CONF_AUTHOR; +} + +const char *SDKExtension::GetExtensionDateString() +{ + return SMEXT_CONF_DATESTRING; +} + +const char *SDKExtension::GetExtensionDescription() +{ + return SMEXT_CONF_DESCRIPTION; +} + +const char *SDKExtension::GetExtensionVerString() +{ + return SMEXT_CONF_VERSION; +} + +const char *SDKExtension::GetExtensionName() +{ + return SMEXT_CONF_NAME; +} + +const char *SDKExtension::GetExtensionTag() +{ + return SMEXT_CONF_LOGTAG; +} + +const char *SDKExtension::GetExtensionURL() +{ + return SMEXT_CONF_URL; +} + +bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) +{ + return true; +} + +void SDKExtension::SDK_OnUnload() +{ +} + +void SDKExtension::SDK_OnPauseChange(bool paused) +{ +} + +void SDKExtension::SDK_OnAllLoaded() +{ +} + +#if defined SMEXT_CONF_METAMOD + +PluginId g_PLID = 0; /**< Metamod plugin ID */ +ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ +SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ +ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ + +IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ +IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ + +/** Exposes the extension to Metamod */ +SMM_API void *PL_EXPOSURE(const char *name, int *code) +{ +#if defined METAMOD_PLAPI_VERSION + if (name && !strcmp(name, METAMOD_PLAPI_NAME)) +#else + if (name && !strcmp(name, PLAPI_NAME)) +#endif + { + if (code) + { + *code = IFACE_OK; + } + return static_cast(g_pExtensionIface); + } + + if (code) + { + *code = IFACE_FAILED; + } + + return NULL; +} + +bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) +{ + PLUGIN_SAVEVARS(); + +#if !defined METAMOD_PLAPI_VERSION + GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); + GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); +#else + GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); + GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); +#endif + + m_SourceMMLoaded = true; + + return SDK_OnMetamodLoad(ismm, error, maxlen, late); +} + +bool SDKExtension::Unload(char *error, size_t maxlen) +{ + if (!m_WeAreUnloaded) + { + if (error) + { + snprintf(error, maxlen, "This extension must be unloaded by SourceMod."); + } + return false; + } + + return SDK_OnMetamodUnload(error, maxlen); +} + +bool SDKExtension::Pause(char *error, size_t maxlen) +{ + if (!m_WeGotPauseChange) + { + if (error) + { + snprintf(error, maxlen, "This extension must be paused by SourceMod."); + } + return false; + } + + m_WeGotPauseChange = false; + + return SDK_OnMetamodPauseChange(true, error, maxlen); +} + +bool SDKExtension::Unpause(char *error, size_t maxlen) +{ + if (!m_WeGotPauseChange) + { + if (error) + { + snprintf(error, maxlen, "This extension must be unpaused by SourceMod."); + } + return false; + } + + m_WeGotPauseChange = false; + + return SDK_OnMetamodPauseChange(false, error, maxlen); +} + +const char *SDKExtension::GetAuthor() +{ + return GetExtensionAuthor(); +} + +const char *SDKExtension::GetDate() +{ + return GetExtensionDateString(); +} + +const char *SDKExtension::GetDescription() +{ + return GetExtensionDescription(); +} + +const char *SDKExtension::GetLicense() +{ + return SMEXT_CONF_LICENSE; +} + +const char *SDKExtension::GetLogTag() +{ + return GetExtensionTag(); +} + +const char *SDKExtension::GetName() +{ + return GetExtensionName(); +} + +const char *SDKExtension::GetURL() +{ + return GetExtensionURL(); +} + +const char *SDKExtension::GetVersion() +{ + return GetExtensionVerString(); +} + +bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) +{ + return true; +} + +bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) +{ + return true; +} + +bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) +{ + return true; +} + +#endif + +/* Overload a few things to prevent libstdc++ linking */ +#if defined __linux__ +extern "C" void __cxa_pure_virtual(void) +{ +} + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void *ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} +#endif diff --git a/extensions/clientprefs/sdk/smsdk_ext.h b/extensions/clientprefs/sdk/smsdk_ext.h new file mode 100644 index 00000000..0ee0dfa2 --- /dev/null +++ b/extensions/clientprefs/sdk/smsdk_ext.h @@ -0,0 +1,327 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Base Extension Code + * 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_EXTENSION_BASESDK_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ + +/** + * @file smsdk_ext.h + * @brief Contains wrappers for making Extensions easier to write. + */ + +#include "smsdk_config.h" +#include +#include +#include +#include +#include +#if defined SMEXT_ENABLE_FORWARDSYS +#include +#endif //SMEXT_ENABLE_FORWARDSYS +#if defined SMEXT_ENABLE_PLAYERHELPERS +#include +#endif //SMEXT_ENABLE_PlAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +#include +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +#include +#endif +#if defined SMEXT_ENABLE_MEMUTILS +#include +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +#include +#endif +#if defined SMEXT_ENABLE_TIMERSYS +#include +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +#include +#endif +#if defined SMEXT_ENABLE_THREADER +#include +#endif +#if defined SMEXT_ENABLE_LIBSYS +#include +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +#include +#endif +#if defined SMEXT_ENABLE_MENUS +#include +#endif +#if defined SMEXT_ENABLE_ADMINSYS +#include +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS +#include +#endif +#if defined SMEXT_ENABLE_USERMSGS +#include +#endif + +#if defined SMEXT_CONF_METAMOD +#include +#include +#endif + +using namespace SourceMod; +using namespace SourcePawn; + +class SDKExtension : +#if defined SMEXT_CONF_METAMOD + public ISmmPlugin, +#endif + public IExtensionInterface +{ +public: + /** Constructor */ + SDKExtension(); +public: + /** + * @brief This is called after the initial loading sequence has been processed. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @param late Whether or not the module was loaded after map load. + * @return True to succeed loading, false to fail. + */ + virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); + + /** + * @brief This is called right before the extension is unloaded. + */ + virtual void SDK_OnUnload(); + + /** + * @brief This is called once all known extensions have been loaded. + */ + virtual void SDK_OnAllLoaded(); + + /** + * @brief Called when the pause state is changed. + */ + virtual void SDK_OnPauseChange(bool paused); + +#if defined SMEXT_CONF_METAMOD + /** + * @brief Called when Metamod is attached, before the extension version is called. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @param late Whether or not Metamod considers this a late load. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); + + /** + * @brief Called when Metamod is detaching, after the extension version is called. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); + + /** + * @brief Called when Metamod's pause state is changing. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param paused Pause state being set. + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); +#endif + +public: //IExtensionInterface + virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late); + virtual void OnExtensionUnload(); + virtual void OnExtensionsAllLoaded(); + + /** Returns whether or not this is a Metamod-based extension */ + virtual bool IsMetamodExtension(); + + /** + * @brief Called when the pause state changes. + * + * @param state True if being paused, false if being unpaused. + */ + virtual void OnExtensionPauseChange(bool state); + + /** Returns name */ + virtual const char *GetExtensionName(); + /** Returns URL */ + virtual const char *GetExtensionURL(); + /** Returns log tag */ + virtual const char *GetExtensionTag(); + /** Returns author */ + virtual const char *GetExtensionAuthor(); + /** Returns version string */ + virtual const char *GetExtensionVerString(); + /** Returns description string */ + virtual const char *GetExtensionDescription(); + /** Returns date string */ + virtual const char *GetExtensionDateString(); +#if defined SMEXT_CONF_METAMOD +public: //ISmmPlugin + /** Called when the extension is attached to Metamod. */ + virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late); + /** Returns the author to MM */ + virtual const char *GetAuthor(); + /** Returns the name to MM */ + virtual const char *GetName(); + /** Returns the description to MM */ + virtual const char *GetDescription(); + /** Returns the URL to MM */ + virtual const char *GetURL(); + /** Returns the license to MM */ + virtual const char *GetLicense(); + /** Returns the version string to MM */ + virtual const char *GetVersion(); + /** Returns the date string to MM */ + virtual const char *GetDate(); + /** Returns the logtag to MM */ + virtual const char *GetLogTag(); + /** Called on unload */ + virtual bool Unload(char *error, size_t maxlength); + /** Called on pause */ + virtual bool Pause(char *error, size_t maxlength); + /** Called on unpause */ + virtual bool Unpause(char *error, size_t maxlength); +private: + bool m_SourceMMLoaded; + bool m_WeAreUnloaded; + bool m_WeGotPauseChange; +#endif +}; + +extern SDKExtension *g_pExtensionIface; +extern IExtension *myself; + +extern IShareSys *g_pShareSys; +extern IShareSys *sharesys; /* Note: Newer name */ +extern ISourceMod *g_pSM; +extern ISourceMod *smutils; /* Note: Newer name */ + +/* Optional interfaces are below */ +#if defined SMEXT_ENABLE_FORWARDSYS +extern IForwardManager *g_pForwards; +extern IForwardManager *forwards; /* Note: Newer name */ +#endif //SMEXT_ENABLE_FORWARDSYS +#if defined SMEXT_ENABLE_HANDLESYS +extern IHandleSys *g_pHandleSys; +extern IHandleSys *handlesys; /* Note: Newer name */ +#endif //SMEXT_ENABLE_HANDLESYS +#if defined SMEXT_ENABLE_PLAYERHELPERS +extern IPlayerManager *playerhelpers; +#endif //SMEXT_ENABLE_PLAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +extern IDBManager *dbi; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +extern IGameConfigManager *gameconfs; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_MEMUTILS +extern IMemoryUtils *memutils; +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +extern IGameHelpers *gamehelpers; +#endif +#if defined SMEXT_ENABLE_TIMERSYS +extern ITimerSystem *timersys; +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +extern IADTFactory *adtfactory; +#endif +#if defined SMEXT_ENABLE_THREADER +extern IThreader *threader; +#endif +#if defined SMEXT_ENABLE_LIBSYS +extern ILibrarySys *libsys; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +extern SourceMod::IPluginManager *plsys; +#endif +#if defined SMEXT_ENABLE_MENUS +extern IMenuManager *menus; +#endif +#if defined SMEXT_ENABLE_ADMINSYS +extern IAdminSystem *adminsys; +#endif +#if defined SMEXT_ENABLE_USERMSGS +extern IUserMessages *usermsgs; +#endif + +#if defined SMEXT_CONF_METAMOD +PLUGIN_GLOBALVARS(); +extern IVEngineServer *engine; +extern IServerGameDLL *gamedll; +#endif + +/** Creates a SourceMod interface macro pair */ +#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION +/** Automates retrieving SourceMod interfaces */ +#define SM_GET_IFACE(prefix, addr) \ + if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \ + { \ + if (error != NULL && maxlength) \ + { \ + size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ + if (len >= maxlength) \ + { \ + error[maxlength - 1] = '\0'; \ + } \ + } \ + return false; \ + } +/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */ +#define SM_GET_LATE_IFACE(prefix, addr) \ + g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr) +/** Validates a SourceMod interface pointer */ +#define SM_CHECK_IFACE(prefix, addr) \ + if (!addr) \ + { \ + if (error != NULL && maxlength) \ + { \ + size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ + if (len >= maxlength) \ + { \ + error[maxlength - 1] = '\0'; \ + } \ + } \ + return false; \ + } + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ diff --git a/extensions/clientprefs/svn_version.h b/extensions/clientprefs/svn_version.h new file mode 100644 index 00000000..e7ff7336 --- /dev/null +++ b/extensions/clientprefs/svn_version.h @@ -0,0 +1,42 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod SDKTools Extension + * 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$ + */ + +/** + * Autogenerated by build scripts + */ + +#ifndef _INCLUDE_CLIENTPREFS_VERSION_H_ +#define _INCLUDE_CLIENTPREFS_VERSION_H_ + +#define SVN_FULL_VERSION "1.1.0.1982" +#define SVN_FILE_VERSION 1,1,0,1982 + +#endif //_INCLUDE_SDKTOOLS_VERSION_H_ diff --git a/extensions/clientprefs/svn_version.tpl b/extensions/clientprefs/svn_version.tpl new file mode 100644 index 00000000..5b381a8d --- /dev/null +++ b/extensions/clientprefs/svn_version.tpl @@ -0,0 +1,42 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod SDKTools Extension + * 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$ + */ + +/** + * Autogenerated by build scripts + */ + +#ifndef _INCLUDE_CLIENTPREFS_VERSION_H_ +#define _INCLUDE_CLIENTPREFS_VERSION_H_ + +#define SVN_FULL_VERSION "$PMAJOR$.$PMINOR$.$PREVISION$.$LOCAL_BUILD$" +#define SVN_FILE_VERSION $PMAJOR$,$PMINOR$,$PREVISION$,$LOCAL_BUILD$ + +#endif //_INCLUDE_CLIENTPREFS_VERSION_H_ diff --git a/extensions/clientprefs/version.rc b/extensions/clientprefs/version.rc new file mode 100644 index 00000000..9816b495 --- /dev/null +++ b/extensions/clientprefs/version.rc @@ -0,0 +1,104 @@ +// Microsoft Visual C++ generated resource script. +// +//#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +#include "svn_version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION SVN_FILE_VERSION + PRODUCTVERSION SVN_FILE_VERSION + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Client Preferences Extension" + VALUE "FileDescription", "SourceMod Client Preferences Extension" + VALUE "FileVersion", SVN_FULL_VERSION + VALUE "InternalName", "SourceMod Client Preferences Extension" + VALUE "LegalCopyright", "Copyright (c) 2004-2008, AlliedModders LLC" + VALUE "OriginalFilename", "clientprefs.ext.dll" + VALUE "ProductName", "SourceMod Client Preferences Extension" + VALUE "ProductVersion", SVN_FULL_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/include/clientprefs.inc b/plugins/include/clientprefs.inc new file mode 100644 index 00000000..332a1a5e --- /dev/null +++ b/plugins/include/clientprefs.inc @@ -0,0 +1,108 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * 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$ + */ + +#if defined _clientprefs_included + #endinput +#endif +#define _clientprefs_included + +/** + * Creates a new Client preference cookie. + * + * @param name Name of the new preference cookie. + * @param description Optional description of the preference cookie. + * @return A handle to the newly created cookie. If the cookie already exists, a handle to it will still be returned. + * @error Cookie name is blank. + */ +native Handle:RegClientPrefCookie(const String:name[], const String:description[]); + +/** + * Searches for a Client preference cookie. + * + * @param name Name of cookie to find. + * @return A handle to the cookie if it is found. INVALID_HANDLE otherwise. + */ +native Handle:FindClientPrefCookie(const String:name[]); + +/** + * Set the value of a Client preference cookie. + * + * @param client Client index. + * @param cookie Client preference cookie handle. + * @param value String value to set. + * @noreturn + * @error Invalid cookie handle or invalid client index. + */ +native SetClientPrefCookie(client, Handle:cookie, const String:value[]); + +/** + * Retrieve the value of a Client preference cookie. + * + * @param client Client index. + * @param cookie Client preference cookie handle. + * @param buffer Copyback buffer for value. + * @param maxlen Maximum length of the buffer. + * @error Invalid cookie handle or invalid client index. + */ +native GetClientPrefCookie(client, Handle:cookie, String:buffer[], maxlen); + +/** + * Checks if a clients cookies have been loaded from the database. + * + * @param client Client index. + * @return True if loaded, false otherwise. + * @error Invalid client index. + */ +native bool:AreClientCookiesCached(client); + +/** + * Called once a client's saved cookies have been loaded from the database. + * + * @param client Client index. + */ +forward OnClientCookiesLoaded(client); + + +/** + * Do not edit below this line! + */ +public Extension:__ext_clientprefs = +{ + name = "Client Preferences", + file = "clientprefs.ext", + autoload = 1, +#if defined REQUIRE_EXTENSIONS + required = 1, +#else + required = 0, +#endif +}; diff --git a/plugins/testsuite/clientprefstest.sp b/plugins/testsuite/clientprefstest.sp new file mode 100644 index 00000000..14ada077 --- /dev/null +++ b/plugins/testsuite/clientprefstest.sp @@ -0,0 +1,26 @@ +#include +#include "../include/clientprefs.inc" + +new Handle:g_Cookie; + +public OnPluginStart() +{ + g_Cookie = RegClientPrefCookie("test-cookie", "A basic testing cookie"); +} + +public bool:OnClientConnect(client, String:rejectmsg[], maxlen) +{ + LogMessage("Connect Cookie state: %s", AreClientCookiesCached(client) ? "YES" : "NO"); +} + +public OnClientCookiesLoaded(client) +{ + LogMessage("Loaded Cookie state: %s", AreClientCookiesCached(client) ? "YES" : "NO"); + + new String:hi[100]; + GetClientPrefCookie(client, g_Cookie, hi, sizeof(hi)); + LogMessage("Test: %s",hi); + SetClientPrefCookie(client, g_Cookie, "somethingsomething"); + GetClientPrefCookie(client, g_Cookie, hi, sizeof(hi)); + LogMessage("Test: %s",hi); +} \ No newline at end of file diff --git a/tools/builder/PkgCore.cs b/tools/builder/PkgCore.cs index f6428084..f58365f0 100644 --- a/tools/builder/PkgCore.cs +++ b/tools/builder/PkgCore.cs @@ -277,6 +277,13 @@ namespace builder lib.vcproj_name = "regex"; libraries.Add(lib); + lib = new Library(); + lib.package_path = "addons/sourcemod/extensions"; + lib.source_path = "extensions/clientprefs"; + lib.binary_name = "clientprefs.ext"; + lib.vcproj_name = "clientprefs"; + libraries.Add(lib); + return (Library [])libraries.ToArray(typeof(Library)); }