diff --git a/core/CConVarManager.cpp b/core/CConVarManager.cpp new file mode 100644 index 00000000..185ecab0 --- /dev/null +++ b/core/CConVarManager.cpp @@ -0,0 +1,160 @@ +/** +* =============================================================== +* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. +* =============================================================== +* +* This file is not open source and may not be copied without explicit +* written permission of AlliedModders LLC. This file may not be redistributed +* in whole or significant part. +* For information, see LICENSE.txt or http://www.sourcemod.net/license.php +* +* Version: $Id$ +*/ + +#include "CConVarManager.h" +#include "CLogger.h" +#include "PluginSys.h" +#include "sm_srvcmds.h" + +CConVarManager g_ConVarManager; + +CConVarManager::CConVarManager() +{ + m_ConVarType = 0; + m_CvarCache = sm_trie_create(); +} + +CConVarManager::~CConVarManager() +{ + sm_trie_destroy(m_CvarCache); +} + +void CConVarManager::OnSourceModAllInitialized() +{ + HandleAccess sec; + + sec.access[HandleAccess_Read] = 0; + sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER; + sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER; + + m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL); + + g_RootMenu.AddRootConsoleCommand("cvars", "View convars associated with a plugin", this); +} + +void CConVarManager::OnSourceModShutdown() +{ + g_RootMenu.RemoveRootConsoleCommand("cvars", this); + + g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent); +} + +void CConVarManager::OnHandleDestroy(HandleType_t type, void *object) +{ + g_SMAPI->UnregisterConCmdBase(g_PLAPI, static_cast(object)); +} + +void CConVarManager::OnRootConsoleCommand(const char *command, unsigned int argcount) +{ + if (argcount >= 3) + { + int id = 1; + + int num = atoi(g_RootMenu.GetArgument(2)); + + if (num < 1 || num > (int)g_PluginSys.GetPluginCount()) + { + g_RootMenu.ConsolePrint("[SM] Plugin index not found."); + return; + } + + CPlugin *pl = g_PluginSys.GetPluginByOrder(num); + int convarnum = pl->GetConVarCount(); + + if (convarnum == 0) + { + g_RootMenu.ConsolePrint("[SM] No convars for \"%s\"", pl->GetPublicInfo()->name); + return; + } + + g_RootMenu.ConsolePrint("[SM] Displaying convars for \"%s\":", pl->GetPublicInfo()->name); + + for (int i = 0; i < convarnum; i++, id++) + { + ConVar *cvar = pl->GetConVarByIndex(i); + g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, cvar->GetName(), cvar->GetString()); + } + + return; + } + + g_RootMenu.ConsolePrint("[SM] Usage: sm cvars <#>"); +} + +Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, int flags, bool hasMin, float min, bool hasMax, float max) +{ + ConVar *cvar = NULL; + void *temp = NULL; + Handle_t hndl = 0; + + // Find out if the convar exists already + cvar = icvar->FindVar(name); + + // If the convar already exists... + if (cvar != NULL) + { + IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext()); + + // This isn't a fatal error because we can handle it, but user should be warned anyways + g_Logger.LogError("[SM] Warning: Plugin \"%s\" has attempted to create already existing convar \"%s\"", pl->GetFilename(), name); + + // First check if we already have a handle to it + if (sm_trie_retrieve(m_CvarCache, name, &temp)) + { + // If we do, then return that handle + return reinterpret_cast(temp); + } else { + // If we don't, then create a new handle from the convar and return it + return g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL); + } + } + + // Since we didn't find an existing convar, now we can create it + cvar = new ConVar(name, defaultVal, flags, helpText, hasMin, min, hasMax, max); + + // Add new convar to plugin's list + g_PluginSys.GetPluginByCtx(pContext->GetContext())->AddConVar(cvar); + + // Create a new handle from the convar + hndl = g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL); + + // Insert the handle into our cache + sm_trie_insert(m_CvarCache, name, reinterpret_cast(hndl)); + + return hndl; +} + +Handle_t CConVarManager::FindConVar(const char *name) +{ + ConVar *cvar = NULL; + void *temp = NULL; + + // Search for convar + cvar = icvar->FindVar(name); + + // If it doesn't exist, then return an invalid handle + if (cvar == NULL) + { + return BAD_HANDLE; + } + + // At this point, convar exists, so find out if we already have a handle for it + if (sm_trie_retrieve(m_CvarCache, name, &temp)) + { + // If we do, then return that handle + return reinterpret_cast(temp); + } + + // If we don't, then create a new handle from the convar and return it + return g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL); +} \ No newline at end of file diff --git a/core/CConVarManager.h b/core/CConVarManager.h new file mode 100644 index 00000000..e3574932 --- /dev/null +++ b/core/CConVarManager.h @@ -0,0 +1,54 @@ +/** +* =============================================================== +* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. +* =============================================================== +* +* This file is not open source and may not be copied without explicit +* written permission of AlliedModders LLC. This file may not be redistributed +* in whole or significant part. +* For information, see LICENSE.txt or http://www.sourcemod.net/license.php +* +* Version: $Id$ +*/ + +#ifndef _INCLUDE_SOURCEMOD_CCONVARMANAGER_H_ +#define _INCLUDE_SOURCEMOD_CCONVARMANAGER_H_ + +#include "sm_globals.h" +#include "sourcemm_api.h" +#include "HandleSys.h" +#include "sm_trie.h" +#include + +class CConVarManager : + public SMGlobalClass, + public IHandleTypeDispatch, + public IRootConsoleCommand +{ +public: + CConVarManager(); + ~CConVarManager(); +public: // SMGlobalClass + void OnSourceModAllInitialized(); + void OnSourceModShutdown(); +public: // IHandleTypeDispatch + void OnHandleDestroy(HandleType_t type, void *object); +public: //IRootConsoleCommand + void OnRootConsoleCommand(const char *command, unsigned int argcount); +public: + inline HandleType_t GetHandleType() + { + return m_ConVarType; + } +public: + Handle_t CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, + int flags, bool hasMin, float min, bool hasMax, float max); + Handle_t FindConVar(const char* name); +private: + HandleType_t m_ConVarType; + Trie *m_CvarCache; +}; + +extern CConVarManager g_ConVarManager; + +#endif // _INCLUDE_SOURCEMOD_CCONVARMANAGER_H_ \ No newline at end of file diff --git a/core/convar_sm.h b/core/convar_sm.h new file mode 100644 index 00000000..01f51e9e --- /dev/null +++ b/core/convar_sm.h @@ -0,0 +1,529 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: 2006-08-13 06:34:30 -0500 (Sun, 13 Aug 2006) $ +// +//----------------------------------------------------------------------------- +// $NoKeywords: $ +//=============================================================================// + +#ifndef CONVAR_H +#define CONVAR_H +#if _WIN32 +#pragma once +#endif + +#include "tier0/dbg.h" + +#ifdef _WIN32 +#define FORCEINLINE_CVAR FORCEINLINE +#elif _LINUX +#define FORCEINLINE_CVAR __inline__ FORCEINLINE +#else +#error "implement me" +#endif + +// The default, no flags at all +#define FCVAR_NONE 0 + +// Command to ConVars and ConCommands +// ConVar Systems +#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc. +#define FCVAR_LAUNCHER (1<<1) // defined by launcher +#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL +#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL +#define FCVAR_MATERIAL_SYSTEM (1<<4) // Defined by the material system. +#define FCVAR_DATACACHE (1<<19) // Defined by the datacache system. +#define FCVAR_STUDIORENDER (1<<15) // Defined by the studiorender system. +#define FCVAR_FILESYSTEM (1<<21) // Defined by the file system. +#define FCVAR_PLUGIN (1<<18) // Defined by a 3rd party plugin. +#define FCVAR_TOOLSYSTEM (1<<20) // Defined by an IToolSystem library +#define FCVAR_SOUNDSYSTEM (1<<23) // Defined by the soundsystem library +#define FCVAR_INPUTSYSTEM (1<<25) // Defined by the inputsystem dll +#define FCVAR_NETWORKSYSTEM (1<<26) // Defined by the network system +// NOTE!! if you add a cvar system, add it here too!!!! +// the engine lacks a cvar flag, but needs it for xbox +// an engine cvar is thus a cvar not marked with any other system +#define FCVAR_NON_ENGINE ((FCVAR_LAUNCHER|FCVAR_GAMEDLL|FCVAR_CLIENTDLL|FCVAR_MATERIAL_SYSTEM|FCVAR_DATACACHE|FCVAR_STUDIORENDER|FCVAR_FILESYSTEM|FCVAR_PLUGIN|FCVAR_TOOLSYSTEM|FCVAR_SOUNDSYSTEM|FCVAR_INPUTSYSTEM|FCVAR_NETWORKSYSTEM)) + +// ConVar only +#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value +#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server. +#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc +#define FCVAR_NOTIFY (1<<8) // notifies players when changed +#define FCVAR_USERINFO (1<<9) // changes the client's info string +#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats + +#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). +#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log +#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar + +// It's a ConVar that's shared between the client and the server. +// At signon, the values of all such ConVars are sent from the server to the client (skipped for local +// client, of course ) +// If a change is requested it must come from the console (i.e., no remote client changes) +// If a value is changed while a server is active, it's replicated to all connected clients +#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time +#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file +#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles + +#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server + +#define FCVAR_ARCHIVE_XBOX (1<<24) // cvar written to config.cfg on the Xbox + + +// #define FCVAR_AVAILABLE (1<<27) +// #define FCVAR_AVAILABLE (1<<28) +// #define FCVAR_AVAILABLE (1<<29) +// #define FCVAR_AVAILABLE (1<<30) +// #define FCVAR_AVAILABLE (1<<31) + + +class ConVar; +class ConCommand; +class ConCommandBase; + +// Any executable that wants to use ConVars need to implement one of +// these to hook up access to console variables. +class IConCommandBaseAccessor +{ +public: + // Flags is a combination of FCVAR flags in cvar.h. + // hOut is filled in with a handle to the variable. + virtual bool RegisterConCommandBase( ConCommandBase *pVar )=0; +}; + + +// You don't have to instantiate one of these, just call its +// OneTimeInit function when your executable is initializing. +class ConCommandBaseMgr +{ +public: + // Call this ONCE when the executable starts up. + static void OneTimeInit( IConCommandBaseAccessor *pAccessor ); +#ifdef _XBOX + static bool Fixup( ConCommandBase* pConCommandBase ); +#ifndef _RETAIL + static void PublishCommands( bool bForce ); +#endif +#endif +}; + +// Called when a ConVar changes value +typedef void ( *FnChangeCallback )( ConVar *var, char const *pOldString ); + +// Called when a ConCommand needs to execute +typedef void ( *FnCommandCallback )( void ); + +#define COMMAND_COMPLETION_MAXITEMS 64 +#define COMMAND_COMPLETION_ITEM_LENGTH 64 + +// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings +typedef int ( *FnCommandCompletionCallback )( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); + +//----------------------------------------------------------------------------- +// Purpose: The base console invoked command/cvar interface +//----------------------------------------------------------------------------- +class ConCommandBase +{ + friend class ConCommandBaseMgr; + friend class CCvar; + friend class ConVar; + friend class ConCommand; + +public: + ConCommandBase( void ); + ConCommandBase( char const *pName, char const *pHelpString = 0, + int flags = 0 ); + + virtual ~ConCommandBase( void ); + + virtual bool IsCommand( void ) const; + + // Check flag + virtual bool IsBitSet( int flag ) const; + // Set flag + virtual void AddFlags( int flags ); + + // Return name of cvar + virtual char const *GetName( void ) const; + + // Return help text for cvar + virtual char const *GetHelpText( void ) const; + + // Deal with next pointer + const ConCommandBase *GetNext( void ) const; + void SetNext( ConCommandBase *next ); + + virtual bool IsRegistered( void ) const; + + // Global methods + static ConCommandBase const *GetCommands( void ); + static void AddToList( ConCommandBase *var ); + static void RemoveFlaggedCommands( int flag ); + static void RevertFlaggedCvars( int flag ); + static ConCommandBase const *FindCommand( char const *name ); + +protected: + virtual void Create( char const *pName, char const *pHelpString = 0, + int flags = 0 ); + + // Used internally by OneTimeInit to initialize. + virtual void Init(); + + // Internal copy routine ( uses new operator from correct module ) + char *CopyString( char const *from ); + + // Next ConVar in chain + ConCommandBase *m_pNext; + +private: + // Has the cvar been added to the global list? + bool m_bRegistered; + + // Static data + char const *m_pszName; + char const *m_pszHelpString; + + // ConVar flags + int m_nFlags; + +protected: + + // ConVars add themselves to this list for the executable. Then ConVarMgr::Init() runs through + // all the console variables and registers them. + static ConCommandBase *s_pConCommandBases; + + // ConVars in this executable use this 'global' to access values. + static IConCommandBaseAccessor *s_pAccessor; + +public: // Hackalicous + int GetFlags() { return m_nFlags; } + void SetFlags(int flags) { m_nFlags = flags; } +}; + +//----------------------------------------------------------------------------- +// Purpose: The console invoked command +//----------------------------------------------------------------------------- +class ConCommand : public ConCommandBase +{ +friend class ConCommandBaseMgr; +friend class CCvar; +#ifdef _STATIC_LINKED +friend class G_ConCommand; +friend class C_ConCommand; +friend class M_ConCommand; +friend class S_ConCommand; +friend class D_ConCommand; +#endif + +public: + typedef ConCommandBase BaseClass; + + ConCommand( void ); + ConCommand( char const *pName, FnCommandCallback callback, + char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); + + virtual ~ConCommand( void ); + + virtual bool IsCommand( void ) const; + + virtual int AutoCompleteSuggest( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); + + virtual bool CanAutoComplete( void ); + + // Invoke the function + virtual void Dispatch( void ); +private: + virtual void Create( char const *pName, FnCommandCallback callback, + char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); + + // Call this function when executing the command + FnCommandCallback m_fnCommandCallback; + + FnCommandCompletionCallback m_fnCompletionCallback; + bool m_bHasCompletionCallback; +public: // Hackalicous + FnCommandCallback GetCallback() { return m_fnCommandCallback; } +}; + +//----------------------------------------------------------------------------- +// Purpose: A console variable +//----------------------------------------------------------------------------- +class ConVar : public ConCommandBase +{ +friend class ConCommandBaseMgr; +friend class CCvar; +friend class CDefaultCvar; +#ifdef _STATIC_LINKED +friend class G_ConVar; +friend class C_ConVar; +friend class M_ConVar; +friend class S_ConVar; +friend class D_ConVar; +#endif + +public: + typedef ConCommandBase BaseClass; + + ConVar( char const *pName, char const *pDefaultValue, int flags = 0); + + ConVar( char const *pName, char const *pDefaultValue, int flags, + char const *pHelpString ); + ConVar( char const *pName, char const *pDefaultValue, int flags, + char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ); + ConVar( char const *pName, char const *pDefaultValue, int flags, + char const *pHelpString, FnChangeCallback callback ); + ConVar( char const *pName, char const *pDefaultValue, int flags, + char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, + FnChangeCallback callback ); + + virtual ~ConVar( void ); + + virtual bool IsBitSet( int flag ) const; + virtual char const* GetHelpText( void ) const; + virtual bool IsRegistered( void ) const; + virtual char const *GetName( void ) const; + virtual void AddFlags( int flags ); + virtual bool IsCommand( void ) const; + + // Install a change callback (there shouldn't already be one....) + void InstallChangeCallback( FnChangeCallback callback ); + + // Retrieve value + FORCEINLINE_CVAR float GetFloat( void ) const; + FORCEINLINE_CVAR int GetInt( void ) const; + FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } + FORCEINLINE_CVAR char const *GetString( void ) const; + + // Any function that allocates/frees memory needs to be virtual or else you'll have crashes + // from alloc/free across dll/exe boundaries. + + // These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue). + virtual void SetValue( char const *value ); + virtual void SetValue( float value ); + virtual void SetValue( int value ); + + // Reset to default value + void Revert( void ); + + // True if it has a min/max setting + bool GetMin( float& minVal ) const; + bool GetMax( float& maxVal ) const; + char const *GetDefault( void ) const; + + static void RevertAll( void ); +private: + // Called by CCvar when the value of a var is changing. + virtual void InternalSetValue(char const *value); + // For CVARs marked FCVAR_NEVER_AS_STRING + virtual void InternalSetFloatValue( float fNewValue ); + virtual void InternalSetIntValue( int nValue ); + + virtual bool ClampValue( float& value ); + virtual void ChangeStringValue( char const *tempVal ); + + virtual void Create( char const *pName, char const *pDefaultValue, int flags = 0, + char const *pHelpString = 0, bool bMin = false, float fMin = 0.0, + bool bMax = false, float fMax = false, FnChangeCallback callback = 0 ); + + // Used internally by OneTimeInit to initialize. + virtual void Init(); + +private: + + // This either points to "this" or it points to the original declaration of a ConVar. + // This allows ConVars to exist in separate modules, and they all use the first one to be declared. + // m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). + ConVar *m_pParent; + + // Static data + char const *m_pszDefaultValue; + + // Value + // Dynamically allocated + char *m_pszString; + int m_StringLength; + + // Values + float m_fValue; + int m_nValue; + + // Min/Max values + bool m_bHasMin; + float m_fMinVal; + bool m_bHasMax; + float m_fMaxVal; + + // Call this function when ConVar changes + FnChangeCallback m_fnChangeCallback; +public: // Hackalicous + FnChangeCallback GetCallback() { return m_fnChangeCallback; } +}; + + +//----------------------------------------------------------------------------- +// Purpose: Return ConVar value as a float +// Output : float +//----------------------------------------------------------------------------- +FORCEINLINE_CVAR float ConVar::GetFloat( void ) const +{ + return m_pParent->m_fValue; +} + +//----------------------------------------------------------------------------- +// Purpose: Return ConVar value as an int +// Output : int +//----------------------------------------------------------------------------- +FORCEINLINE_CVAR int ConVar::GetInt( void ) const +{ + return m_pParent->m_nValue; +} + + +//----------------------------------------------------------------------------- +// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. +// Output : char const * +//----------------------------------------------------------------------------- +FORCEINLINE_CVAR char const *ConVar::GetString( void ) const +{ + if ( m_nFlags & FCVAR_NEVER_AS_STRING ) + { + return "FCVAR_NEVER_AS_STRING"; + } + + return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : ""; +} + + +#ifdef _STATIC_LINKED +// identifies subsystem via piggybacking constructors with flags +class G_ConCommand : public ConCommand +{ +public: + G_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_GAMEDLL, completionFunc) {} +}; + +class C_ConCommand : public ConCommand +{ +public: + C_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_CLIENTDLL, completionFunc) {} +}; + +class M_ConCommand : public ConCommand +{ +public: + M_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_MATERIAL_SYSTEM, completionFunc) {} +}; + +class S_ConCommand : public ConCommand +{ +public: + S_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_STUDIORENDER, completionFunc) {} +}; + +class D_ConCommand : public ConCommand +{ +public: + D_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_DATACACHE, completionFunc) {} +}; + +typedef void ( *G_FnChangeCallback )( G_ConVar *var, char const *pOldString ); +typedef void ( *C_FnChangeCallback )( C_ConVar *var, char const *pOldString ); +typedef void ( *M_FnChangeCallback )( M_ConVar *var, char const *pOldString ); +typedef void ( *S_FnChangeCallback )( S_ConVar *var, char const *pOldString ); +typedef void ( *D_FnChangeCallback )( D_ConVar *var, char const *pOldString ); + +class G_ConVar : public ConVar +{ +public: + G_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL) {} + G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString ) {} + G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax) {} + G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, (FnChangeCallback)callback ) {} + G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} +}; + +class C_ConVar : public ConVar +{ +public: + C_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL) {} + C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString ) {} + C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax) {} + C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, (FnChangeCallback)callback ) {} + C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} +}; + +class M_ConVar : public ConVar +{ +public: + M_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM) {} + M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString ) {} + M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax) {} + M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, (FnChangeCallback)callback ) {} + M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} +}; + +class S_ConVar : public ConVar +{ +public: + S_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER) {} + S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString ) {} + S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax) {} + S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, (FnChangeCallback)callback ) {} + S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, S_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} +}; + +class D_ConVar : public ConVar +{ +public: + D_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE) {} + D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString ) {} + D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax) {} + D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, (FnChangeCallback)callback ) {} + D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, D_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} +}; + +// redirect these declarations to their specific subsystem +#ifdef GAME_DLL +#define ConCommand G_ConCommand +#define ConVar G_ConVar +#endif +#ifdef CLIENT_DLL +#define ConCommand C_ConCommand +#define ConVar C_ConVar +#endif +#ifdef MATERIALSYSTEM_DLL +#define ConCommand M_ConCommand +#define ConVar M_ConVar +#endif +#ifdef STUDIORENDER_DLL +#define ConCommand S_ConCommand +#define ConVar S_ConVar +#endif +#ifdef DATACACHE_DLL +#define ConCommand D_ConCommand +#define ConVar D_ConVar +#endif +#endif // _STATIC_LINKED + +//----------------------------------------------------------------------------- +// Purpose: Utility to quicky generate a simple console command +//----------------------------------------------------------------------------- +#define CON_COMMAND( name, description ) \ + static void name(); \ + static ConCommand name##_command( #name, name, description ); \ + static void name() + +//----------------------------------------------------------------------------- +// Purpose: Utility to quicky generate a simple console command +//----------------------------------------------------------------------------- +#define CON_COMMAND_F( name, description, flags ) \ + static void name(); \ + static ConCommand name##_command( #name, name, description, flags ); \ + static void name() + + +#endif // CONVAR_H diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 02e152f4..7dfbbdde 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -183,6 +183,10 @@ RelativePath="..\AdminCache.cpp" > + + @@ -227,6 +231,10 @@ RelativePath="..\smn_admin.cpp" > + + @@ -273,6 +281,10 @@ RelativePath="..\AdminCache.h" > + + @@ -626,6 +638,14 @@ > + + + + diff --git a/core/sm_srvcmds.h b/core/sm_srvcmds.h index 11b399ee..1b190f3c 100644 --- a/core/sm_srvcmds.h +++ b/core/sm_srvcmds.h @@ -18,7 +18,6 @@ #include #include "PluginSys.h" #include "sourcemm_api.h" -#include #include #include #include "sm_trie.h" diff --git a/core/sm_stringutil.cpp b/core/sm_stringutil.cpp index 1839fa5c..f544704c 100644 --- a/core/sm_stringutil.cpp +++ b/core/sm_stringutil.cpp @@ -50,7 +50,7 @@ inline bool TryTranslation(CPlugin *pl, const char *key, unsigned int langid, un for (size_t i=0; iGetFileByIndex(i)); + phrfl = g_Translator.GetFileByIndex(pl->GetLangFileByIndex(i)); err = phrfl->GetTranslation(key, langid, pTrans); } diff --git a/core/smn_convar.cpp b/core/smn_convar.cpp new file mode 100644 index 00000000..716fb70e --- /dev/null +++ b/core/smn_convar.cpp @@ -0,0 +1,293 @@ +/** +* =============================================================== +* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. +* =============================================================== +* +* This file is not open source and may not be copied without explicit +* written permission of AlliedModders LLC. This file may not be redistributed +* in whole or significant part. +* For information, see LICENSE.txt or http://www.sourcemod.net/license.php +* +* Version: $Id$ +*/ + +#include "sm_globals.h" +#include "sourcemm_api.h" +#include "HandleSys.h" +#include "CConVarManager.h" + +static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params) +{ + char *name, *defaultVal, *helpText; + + pContext->LocalToString(params[1], &name); + + // While the engine seems to accept a blank convar name, it causes a crash upon server quit + if (name == NULL || strcmp(name, "") == 0) + { + pContext->ThrowNativeError("Null or blank convar name is not allowed."); + return BAD_HANDLE; + } + + pContext->LocalToString(params[2], &defaultVal); + pContext->LocalToString(params[3], &helpText); + + bool hasMin = params[5] ? true : false; + bool hasMax = params[7] ? true : false; + float min = sp_ctof(params[6]); + float max = sp_ctof(params[8]); + + return g_ConVarManager.CreateConVar(pContext, name, defaultVal, helpText, params[4], hasMin, min, hasMax, max); +} + +static cell_t sm_FindConVar(IPluginContext *pContext, const cell_t *params) +{ + char *name; + + pContext->LocalToString(params[1], &name); + + // While the engine seems to accept a blank convar name, it causes a crash upon server quit + if (name == NULL || strcmp(name, "") == 0) + { + return BAD_HANDLE; + } + + return g_ConVarManager.FindConVar(name); +} + +static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + return cvar->GetBool(); +} + +static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + return cvar->GetInt(); +} + +/* This handles both SetConVarBool() and SetConVarInt() */ +static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + cvar->SetValue(params[2]); + + return 1; +} + +static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + float value = cvar->GetFloat(); + + return sp_ftoc(value); +} + +static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + float value = sp_ctof(params[2]); + cvar->SetValue(value); + + return 1; +} + +static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + pContext->StringToLocalUTF8(params[2], params[3], cvar->GetString(), NULL); + + return 1; +} + +static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + char *value; + pContext->LocalToString(params[2], &value); + + cvar->SetValue(value); + + return 1; +} + +static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + return cvar->GetFlags(); +} + +static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + cvar->SetFlags(params[2]); + + return 1; +} + +static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + cell_t *addr; + bool hasMin; + float min; + + pContext->LocalToPhysAddr(params[2], &addr); + + hasMin = cvar->GetMin(min); + *addr = sp_ftoc(min); + + return hasMin; +} + +static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + cell_t *addr; + bool hasMax; + float max; + + pContext->LocalToPhysAddr(params[2], &addr); + + hasMax = cvar->GetMax(max); + *addr = sp_ftoc(max); + + return hasMax; +} + +static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError err; + ConVar *cvar; + + if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err); + } + + cvar->Revert(); + + return 1; +} + +REGISTER_NATIVES(convarNatives) +{ + {"CreateConVar", sm_CreateConVar}, + {"FindConVar", sm_FindConVar}, + {"GetConVarBool", sm_GetConVarBool}, + {"SetConVarBool", sm_SetConVarNum}, + {"GetConVarInt", sm_GetConVarInt}, + {"SetConVarInt", sm_SetConVarNum}, + {"GetConVarFloat", sm_GetConVarFloat}, + {"SetConVarFloat", sm_SetConVarFloat}, + {"GetConVarString", sm_GetConVarString}, + {"SetConVarString", sm_SetConVarString}, + {"GetConVarFlags", sm_GetConVarFlags}, + {"SetConVarFlags", sm_SetConVarFlags}, + {"GetConVarMin", sm_GetConVarMin}, + {"GetConVarMax", sm_GetConVarMax}, + {"ResetConVar", sm_ResetConVar}, + {NULL, NULL} +}; diff --git a/core/sourcemm_api.cpp b/core/sourcemm_api.cpp index bc53626f..2980ab61 100644 --- a/core/sourcemm_api.cpp +++ b/core/sourcemm_api.cpp @@ -22,6 +22,7 @@ IServerGameDLL *gamedll = NULL; IServerGameClients *serverClients = NULL; ISmmPluginManager *g_pMMPlugins = NULL; CGlobalVars *gpGlobals = NULL; +ICvar *icvar = NULL; IGameEventManager2 *gameevents = NULL; PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core); @@ -33,6 +34,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); GET_V_IFACE_CURRENT(serverFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); + GET_V_IFACE_CURRENT(engineFactory, icvar, ICvar, VENGINE_CVAR_INTERFACE_VERSION); GET_V_IFACE_CURRENT(engineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2); if ((g_pMMPlugins = (ISmmPluginManager *)g_SMAPI->MetaFactory(MMIFACE_PLMANAGER, NULL, NULL)) == NULL) diff --git a/core/sourcemm_api.h b/core/sourcemm_api.h index a6627af6..10a2d346 100644 --- a/core/sourcemm_api.h +++ b/core/sourcemm_api.h @@ -14,8 +14,10 @@ #ifndef _INCLUDE_SOURCEMOD_MM_API_H_ #define _INCLUDE_SOURCEMOD_MM_API_H_ +#include "convar_sm.h" #include #include +#include #include /** @@ -45,6 +47,7 @@ extern SourceMod_Core g_SourceMod_Core; extern IVEngineServer *engine; extern IServerGameDLL *gamedll; extern IServerGameClients *serverClients; +extern ICvar *icvar; extern ISmmPluginManager *g_pMMPlugins; extern CGlobalVars *gpGlobals; extern IGameEventManager2 *gameevents; diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index d941ef0e..6699cf26 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -504,11 +504,26 @@ size_t CPlugin::GetLangFileCount() const return m_PhraseFiles.size(); } -unsigned int CPlugin::GetFileByIndex(unsigned int index) const +unsigned int CPlugin::GetLangFileByIndex(unsigned int index) const { return m_PhraseFiles.at(index); } +void CPlugin::AddConVar(ConVar *convar) +{ + m_ConVarList.push_back(convar); +} + +size_t CPlugin::GetConVarCount() const +{ + return m_ConVarList.size(); +} + +ConVar *CPlugin::GetConVarByIndex(size_t index) const +{ + return m_ConVarList.at(index); +} + /******************* * PLUGIN ITERATOR * *******************/ diff --git a/core/systems/PluginSys.h b/core/systems/PluginSys.h index 4954fe40..c2e97786 100644 --- a/core/systems/PluginSys.h +++ b/core/systems/PluginSys.h @@ -28,6 +28,7 @@ #include "sm_trie.h" #include "sourcemod.h" #include +#include "convar_sm.h" using namespace SourceHook; @@ -191,7 +192,7 @@ public: /** * Get language file index based on the vector index. */ - unsigned int GetFileByIndex(unsigned int index) const; + unsigned int GetLangFileByIndex(unsigned int index) const; public: /** * Returns the modification time during last plugin load. @@ -207,6 +208,21 @@ public: * Returns true if the plugin was running, but is now invalid. */ bool WasRunning(); + + /** + * Adds a convar to the plugin's list + */ + void AddConVar(ConVar *convar); + + /** + * Get convar count for this plugin. + */ + size_t GetConVarCount() const; + + /** + * Get convar pointer based on the vector index. + */ + ConVar *GetConVarByIndex(size_t index) const; protected: void UpdateInfo(); void SetTimeStamp(time_t t); @@ -224,6 +240,7 @@ private: Handle_t m_handle; bool m_WasRunning; CVector m_PhraseFiles; + CVector m_ConVarList; }; class CPluginManager : @@ -316,6 +333,14 @@ public: */ CPlugin *GetPluginByOrder(int num); + /** + * Internal version of FindPluginByContext() + */ + inline CPlugin *GetPluginByCtx(const sp_context_t *ctx) + { + return reinterpret_cast(ctx->user[SM_CONTEXTVAR_MYSELF]); + } + /** * Gets status text for a status code */ diff --git a/plugins/include/console.inc b/plugins/include/console.inc new file mode 100644 index 00000000..fdf9cf5e --- /dev/null +++ b/plugins/include/console.inc @@ -0,0 +1,201 @@ +/** + * =============================================================== + * 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 _console_included + #endinput +#endif +#define _console_included + +/** + * Flags for console commands and console variables + * @note The descriptions for each constant come directly from the Source SDK. + */ +#define FCVAR_NONE 0 /**< The default, no flags at all */ +#define FCVAR_UNREGISTERED (1<<0) /**< If this is set, don't add to linked list, etc. */ +#define FCVAR_LAUNCHER (1<<1) /**< Defined by launcher. */ +#define FCVAR_GAMEDLL (1<<2) /**< Defined by the game DLL. */ +#define FCVAR_CLIENTDLL (1<<3) /**< Defined by the client DLL. */ +#define FCVAR_MATERIAL_SYSTEM (1<<4) /**< Defined by the material system. */ +#define FCVAR_PROTECTED (1<<5) /**< It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value. */ +#define FCVAR_SPONLY (1<<6) /**< This cvar cannot be changed by clients connected to a multiplayer server. */ +#define FCVAR_ARCHIVE (1<<7) /**< Set to cause it to be saved to vars.rc */ +#define FCVAR_NOTIFY (1<<8) /**< Notifies players when changed. */ +#define FCVAR_USERINFO (1<<9) /**< Changes the client's info string. */ +#define FCVAR_PRINTABLEONLY (1<<10) /**< This cvar's string cannot contain unprintable characters (e.g., used for player name, etc.) */ +#define FCVAR_UNLOGGED (1<<11) /**< If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log */ +#define FCVAR_NEVER_AS_STRING (1<<12) /**< Never try to print that cvar. */ +#define FCVAR_REPLICATED (1<<13) /**< Server setting enforced on clients. */ +#define FCVAR_CHEAT (1<<14) /**< Only useable in singleplayer / debug / multiplayer & sv_cheats */ +#define FCVAR_STUDIORENDER (1<<15) /**< Defined by the studiorender system. */ +#define FCVAR_DEMO (1<<16) /**< Record this cvar when starting a demo file. */ +#define FCVAR_DONTRECORD (1<<17) /**< Don't record these command in demo files. */ +#define FCVAR_PLUGIN (1<<18) /**< Defined by a 3rd party plugin. */ +#define FCVAR_DATACACHE (1<<19) /**< Defined by the datacache system. */ +#define FCVAR_TOOLSYSTEM (1<<20) /**< Defined by an IToolSystem library */ +#define FCVAR_FILESYSTEM (1<<21) /**< Defined by the file system. */ +#define FCVAR_NOT_CONNECTED (1<<22) /**< Cvar cannot be changed by a client that is connected to a server. */ +#define FCVAR_SOUNDSYSTEM (1<<23) /**< Defined by the soundsystem library. */ +#define FCVAR_ARCHIVE_XBOX (1<<24) /**< Cvar written to config.cfg on the Xbox. */ +#define FCVAR_INPUTSYSTEM (1<<25) /**< Defined by the inputsystem DLL. */ +#define FCVAR_NETWORKSYSTEM (1<<26) /**< Defined by the network system. */ +#define FCVAR_VPHYSICS (1<<27) /**< Defined by vphysics. */ + +/** + * Creates a new console variable. + * + * @param name Name of new convar. + * @param defaultValue String containing the default value of new convar. + * @param helpText Optional description of the convar. + * @param flags Optional bitstream of flags determining how the convar should be handled. (See FCVAR_* constants for more details) + * @param hasMin Optional boolean that determines if the convar has a minimum value. + * @param min Minimum floating point value that the convar can have if hasMin is true. + * @param hasMax Optional boolean that determines if the convar has a maximum value. + * @param max Maximum floating point value that the convar can have if hasMax is true. + * @return A handle to the newly created convar. If the convar already exists, INVALID_HANDLE is returned. + */ +native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:helpText[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0); + +/** + * Searches for a console variable. + * + * @param name Name of convar to find. + * @return A handle to the convar if it is found. INVALID_HANDLE otherwise. + */ +native Handle:FindConVar(const String:name[]); + +/** + * Returns the boolean value of a console variable. + * + * @param convar Handle to the convar. + * @return The boolean value of the convar. + * @error Invalid or corrupt Handle. + */ +native bool:GetConVarBool(Handle:convar); + +/** + * Sets the boolean value of a console variable. + * + * @param convar Handle to the convar. + * @param value New boolean value. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native SetConVarBool(Handle:convar, bool:value); + +/** + * Returns the integer value of a console variable. + * + * @param convar Handle to the convar. + * @return The integer value of the convar. + * @error Invalid or corrupt Handle. + */ +native GetConVarInt(Handle:convar); + +/** + * Sets the integer value of a console variable. + * + * @param convar Handle to the convar. + * @param value New integer value. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native SetConVarInt(Handle:convar, value); + +/** + * Returns the floating point value of a console variable. + * + * @param convar Handle to the convar. + * @return The floating point value of the convar. + * @error Invalid or corrupt Handle. + */ +native Float:GetConVarFloat(Handle:convar); + +/** + * Sets the floating point value of a console variable. + * + * @param convar Handle to the convar. + * @param value New floating point value. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native SetConVarFloat(Handle:convar, Float:value); + +/** + * Retrieves the string value of a console variable. + * + * @param convar Handle to the convar. + * @param value Buffer to store the value of the convar. + * @param maxlen Maximum length of string buffer. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native GetConVarString(Handle:convar, String:value[], maxlen); + +/** + * Sets the string value of a console variable. + * + * @param convar Handle to the convar. + * @param value New string value. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native SetConVarString(Handle:convar, const String:value[]); + +/** + * Returns the bitstring of flags on a console variable. + * + * @param convar Handle to the convar. + * @return A bitstring containing the FCVAR_* flags that are enabled. + * @error Invalid or corrupt Handle. + */ +native GetConVarFlags(Handle:convar); + +/** + * Sets the bitstring of flags on a console variable. + * + * @param convar Handle to the convar. + * @param flags A bitstring containing the FCVAR_* flags to enable. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native SetConVarFlags(Handle:convar, flags); + +/** + * Retrieves the minimum floating point value that a console variable can contain. + * + * @param convar Handle to the convar. + * @param min By-reference cell to store the minimum floating point value. + * @return True if the convar has a minimum value set, false otherwise. + * @error Invalid or corrupt Handle. + */ +native bool:GetConVarMin(Handle:convar, &Float:min); + +/** + * Retrieves the maximum floating point value that a console variable can contain. + * + * @param convar Handle to the convar. + * @param min By-reference cell to store the maximum floating point value. + * @return True if the convar has a maximum value set, false otherwise. + * @error Invalid or corrupt Handle. + */ +native bool:GetConVarMax(Handle:convar, &Float:max); + +/** + * Resets the console variable to its default value. + * + * @param convar Handle to the convar. + * @noreturn + * @error Invalid or corrupt Handle. + */ +native ResetConVar(Handle:convar); diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index 3aa2a633..5cde54a1 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -32,6 +32,7 @@ struct Plugin #include #include #include +#include /** * Declare this as a struct in your plugin to expose its information.