Merge branch 'master' into calli-5
Conflicts: public/amtl/am-utility.h
This commit is contained in:
commit
60eb8ca4bd
core
AMBuilderConCmdManager.cppEventManager.cppEventManager.hPlayerManager.cppPlayerManager.h
logic
logic_bridge.cppsm_stringutil.cppextensions
clientprefs
mysql/mysql
sdkhooks
sqlite/driver
gamedata
core.games
engine.bgt.txtengine.css.txtengine.darkm.txtengine.ep1.txtengine.ep2.txtengine.ep2valve.txtengine.eye.txtengine.sdk2013.txt
sdkhooks.games
plugins
admin-flatfile
include
public
IPlayerHelpers.h
amtl
sourcepawn/compiler
@ -52,17 +52,14 @@ for sdk_name in SM.sdks:
|
||||
compiler = binary.compiler
|
||||
|
||||
if sdk.name == 'csgo':
|
||||
# Protobuf 2.3 headers have some signed/unsigned compares. I believe that it's fixed in later versions, but Valve.
|
||||
if compiler.cxx.behavior == 'gcc':
|
||||
compiler.cflags += ['-Wno-sign-compare']
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.3.0', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
|
||||
]
|
||||
elif sdk.name == 'dota':
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.4.1', 'src'),
|
||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf')
|
||||
@ -109,6 +106,7 @@ for sdk_name in SM.sdks:
|
||||
binary.sources += [
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'networkbasetypes.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'network_connection.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'ai_activity.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'usermessages.pb.cc'),
|
||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_commonmessages.pb.cc'),
|
||||
|
@ -383,7 +383,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
{
|
||||
if (!m_CmdGrps.add(i, group))
|
||||
return false;
|
||||
i->value = NoAddRef(new CommandGroup());
|
||||
i->value = new CommandGroup();
|
||||
}
|
||||
Ref<CommandGroup> cmdgroup = i->value;
|
||||
|
||||
|
@ -155,7 +155,7 @@ void EventManager::FireGameEvent(IGameEvent *pEvent)
|
||||
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
int EventManager::GetEventDebugID()
|
||||
{
|
||||
return EVENT_DEBUG_ID_INIT;
|
||||
|
@ -110,7 +110,7 @@ public: // IPluginsListener
|
||||
void OnPluginUnloaded(IPlugin *plugin);
|
||||
public: // IGameEventListener2
|
||||
void FireGameEvent(IGameEvent *pEvent);
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
||||
int GetEventDebugID();
|
||||
#endif
|
||||
public:
|
||||
|
@ -1914,7 +1914,7 @@ CPlayer::CPlayer()
|
||||
m_bIsSourceTV = false;
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
m_SteamAccountID = 0;
|
||||
m_SteamId = k_steamIDNil;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
@ -1997,7 +1997,7 @@ void CPlayer::Disconnect()
|
||||
m_bIsSourceTV = false;
|
||||
m_bIsReplay = false;
|
||||
m_Serial.value = -1;
|
||||
m_SteamAccountID = 0;
|
||||
m_SteamId = k_steamIDNil;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||
#endif
|
||||
@ -2033,16 +2033,17 @@ const char *CPlayer::GetAuthString(bool validated)
|
||||
return m_AuthID.c_str();
|
||||
}
|
||||
|
||||
unsigned int CPlayer::GetSteamAccountID(bool validated)
|
||||
const CSteamID &CPlayer::GetSteamId(bool validated)
|
||||
{
|
||||
if (IsFakeClient() || (validated && !IsAuthStringValidated()))
|
||||
{
|
||||
return 0;
|
||||
static const CSteamID invalidId = k_steamIDNil;
|
||||
return invalidId;
|
||||
}
|
||||
|
||||
if (m_SteamAccountID != 0)
|
||||
if (m_SteamId.IsValid())
|
||||
{
|
||||
return m_SteamAccountID;
|
||||
return m_SteamId;
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE < SE_ORANGEBOX
|
||||
@ -2050,22 +2051,35 @@ unsigned int CPlayer::GetSteamAccountID(bool validated)
|
||||
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
|
||||
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
|
||||
{
|
||||
m_SteamAccountID = (atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1));
|
||||
m_SteamId = CSteamID(atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1),
|
||||
k_unSteamUserDesktopInstance, k_EUniversePublic, k_EAccountTypeIndividual);
|
||||
}
|
||||
#else
|
||||
unsigned long long *steamId;
|
||||
const CSteamID *steamId;
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
steamId = (unsigned long long *)engine->GetClientSteamID(m_iIndex);
|
||||
steamId = engine->GetClientSteamID(m_iIndex);
|
||||
#else
|
||||
steamId = (unsigned long long *)engine->GetClientSteamID(m_pEdict);
|
||||
steamId = engine->GetClientSteamID(m_pEdict);
|
||||
#endif
|
||||
|
||||
if (steamId)
|
||||
{
|
||||
m_SteamAccountID = (*steamId & 0xFFFFFFFF);
|
||||
m_SteamId = (*steamId);
|
||||
}
|
||||
#endif
|
||||
return m_SteamAccountID;
|
||||
return m_SteamId;
|
||||
}
|
||||
|
||||
unsigned int CPlayer::GetSteamAccountID(bool validated)
|
||||
{
|
||||
if (!IsFakeClient() && (!validated || IsAuthStringValidated()))
|
||||
{
|
||||
const CSteamID &id = GetSteamId();
|
||||
if (id.IsValid())
|
||||
return id.GetAccountID();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
edict_t *CPlayer::GetEdict()
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include <sh_vector.h>
|
||||
#include "ConVarManager.h"
|
||||
|
||||
#include <steam/steamclientpublic.h>
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
#define PLAYER_LIFE_UNKNOWN 0
|
||||
@ -71,6 +73,8 @@ public:
|
||||
const char *GetIPAddress();
|
||||
const char *GetAuthString(bool validated = true);
|
||||
unsigned int GetSteamAccountID(bool validated = true);
|
||||
const CSteamID &GetSteamId(bool validated = true);
|
||||
uint64_t GetSteamId64(bool validated = true) { return GetSteamId(validated).ConvertToUint64(); }
|
||||
edict_t *GetEdict();
|
||||
bool IsInGame();
|
||||
bool WasCountedAsInGame();
|
||||
@ -130,7 +134,7 @@ private:
|
||||
bool m_bIsSourceTV;
|
||||
bool m_bIsReplay;
|
||||
serial_t m_Serial;
|
||||
unsigned int m_SteamAccountID;
|
||||
CSteamID m_SteamId;
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
QueryCvarCookie_t m_LanguageCookie;
|
||||
#endif
|
||||
|
@ -1082,6 +1082,7 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
|
||||
}
|
||||
|
||||
pConfig = new CGameConfig(file);
|
||||
pConfig->AddRef();
|
||||
|
||||
/* :HACKHACK: Don't parse the main config file */
|
||||
bool retval = true;
|
||||
|
@ -375,7 +375,7 @@ PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nat
|
||||
if (i.found())
|
||||
return NULL;
|
||||
|
||||
Ref<Native> entry = Newborn<Native>(new Native(pOwner, ntv));
|
||||
Ref<Native> entry = new Native(pOwner, ntv);
|
||||
m_NtvCache.insert(ntv->name, entry);
|
||||
return entry;
|
||||
}
|
||||
@ -415,7 +415,7 @@ PassRef<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *n
|
||||
|
||||
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
|
||||
|
||||
entry = Newborn<Native>(new Native(owner, fake.take()));
|
||||
entry = new Native(owner, fake.take());
|
||||
m_NtvCache.insert(name, entry);
|
||||
|
||||
return entry;
|
||||
|
@ -83,6 +83,7 @@ class IFileSystem_Logic
|
||||
public:
|
||||
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
|
||||
virtual const char *FindNext(FileFindHandle_t handle) = 0;
|
||||
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
|
||||
virtual void FindClose(FileFindHandle_t handle) = 0;
|
||||
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0) = 0;
|
||||
virtual void Close(FileHandle_t file) = 0;
|
||||
@ -90,6 +91,17 @@ public:
|
||||
virtual bool EndOfFile(FileHandle_t file) = 0;
|
||||
virtual bool FileExists(const char *pFileName, const char *pPathID = 0) = 0;
|
||||
virtual unsigned int Size(const char *pFileName, const char *pPathID = 0) = 0;
|
||||
virtual int Read(void* pOutput, int size, FileHandle_t file) = 0;
|
||||
virtual int Write(void const* pInput, int size, FileHandle_t file) = 0;
|
||||
virtual void Seek(FileHandle_t file, int post, int seekType) = 0;
|
||||
virtual unsigned int Tell(FileHandle_t file) = 0;
|
||||
virtual int FPrint(FileHandle_t file, const char *pData) = 0;
|
||||
virtual void Flush(FileHandle_t file) = 0;
|
||||
virtual bool IsOk(FileHandle_t file) = 0;
|
||||
virtual void RemoveFile(const char *pRelativePath, const char *pathID = 0) = 0;
|
||||
virtual void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID = 0) = 0;
|
||||
virtual bool IsDirectory(const char *pFileName, const char *pathID = 0) = 0;
|
||||
virtual void CreateDirHierarchy(const char *path, const char *pathID = 0) = 0;
|
||||
};
|
||||
|
||||
namespace SourceMod
|
||||
|
@ -163,7 +163,7 @@ private:
|
||||
cell_t data_;
|
||||
};
|
||||
|
||||
struct CellTrie : public ke::Refcounted<CellTrie>
|
||||
struct CellTrie
|
||||
{
|
||||
StringHashMap<Entry> map;
|
||||
};
|
||||
@ -204,8 +204,7 @@ public: //IHandleTypeDispatch
|
||||
{
|
||||
if (type == htCellTrie)
|
||||
{
|
||||
CellTrie *pTrie = (CellTrie *)object;
|
||||
pTrie->Release();
|
||||
delete (CellTrie *)object;
|
||||
} else {
|
||||
TrieSnapshot *snapshot = (TrieSnapshot *)object;
|
||||
delete snapshot;
|
||||
|
@ -55,9 +55,135 @@
|
||||
#endif
|
||||
|
||||
HandleType_t g_FileType;
|
||||
HandleType_t g_ValveFileType;
|
||||
HandleType_t g_DirType;
|
||||
HandleType_t g_ValveDirType;
|
||||
IChangeableForward *g_pLogHook = NULL;
|
||||
|
||||
enum class FSType
|
||||
{
|
||||
STDIO,
|
||||
VALVE,
|
||||
};
|
||||
|
||||
class FSHelper
|
||||
{
|
||||
public:
|
||||
void SetFSType(FSType fstype)
|
||||
{
|
||||
_fstype = fstype;
|
||||
}
|
||||
public:
|
||||
inline void *Open(const char *filename, const char *mode, const char *pathID)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->Open(filename, mode, pathID);
|
||||
else
|
||||
return fopen(filename, mode);
|
||||
}
|
||||
|
||||
inline int Read(void *pOut, int size, void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->Read(pOut, size, (FileHandle_t)pFile);
|
||||
else
|
||||
return fread(pOut, 1, size, (FILE *)pFile) * size;
|
||||
}
|
||||
|
||||
inline char *ReadLine(char *pOut, int size, void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->ReadLine(pOut, size, (FileHandle_t)pFile);
|
||||
else
|
||||
return fgets(pOut, size, (FILE *)pFile);
|
||||
}
|
||||
|
||||
inline size_t Write(const void *pData, int size, void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return (size_t)smcore.filesystem->Write(pData, size, (FileHandle_t)pFile);
|
||||
else
|
||||
return fwrite(pData, 1, size, (FILE *)pFile);
|
||||
}
|
||||
|
||||
inline void Seek(void *pFile, int pos, int seekType)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
smcore.filesystem->Seek((FileHandle_t)pFile, pos, seekType);
|
||||
else
|
||||
fseek((FILE *)pFile, pos, seekType);
|
||||
}
|
||||
|
||||
inline int Tell(void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->Tell((FileHandle_t)pFile);
|
||||
else
|
||||
return ftell((FILE *)pFile);
|
||||
}
|
||||
|
||||
inline bool HasError(void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return !smcore.filesystem->IsOk((FileHandle_t)pFile);
|
||||
else
|
||||
return ferror((FILE *)pFile) != 0;
|
||||
}
|
||||
|
||||
inline void Close(void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
smcore.filesystem->Close((FileHandle_t)pFile);
|
||||
else
|
||||
fclose((FILE *)pFile);
|
||||
}
|
||||
|
||||
inline bool Remove(const char *pFilePath, const char *pathID)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
{
|
||||
if (!smcore.filesystem->FileExists(pFilePath, pathID))
|
||||
return false;
|
||||
|
||||
smcore.filesystem->RemoveFile(pFilePath, pathID);
|
||||
|
||||
if (smcore.filesystem->FileExists(pFilePath, pathID))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return unlink(pFilePath) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool EndOfFile(void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->EndOfFile((FileHandle_t)pFile);
|
||||
else
|
||||
return feof((FILE *)pFile) != 0;
|
||||
}
|
||||
|
||||
inline bool Flush(void *pFile)
|
||||
{
|
||||
if (_fstype == FSType::VALVE)
|
||||
return smcore.filesystem->Flush((FileHandle_t)pFile), true;
|
||||
else
|
||||
return fflush((FILE *)pFile) == 0;
|
||||
}
|
||||
private:
|
||||
FSType _fstype;
|
||||
};
|
||||
|
||||
struct ValveDirectory
|
||||
{
|
||||
FileFindHandle_t hndl;
|
||||
char szFirstPath[PLATFORM_MAX_PATH];
|
||||
bool bHandledFirstPath;
|
||||
};
|
||||
|
||||
class FileNatives :
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch,
|
||||
@ -70,7 +196,9 @@ public:
|
||||
virtual void OnSourceModAllInitialized()
|
||||
{
|
||||
g_FileType = handlesys->CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_ValveFileType = handlesys->CreateType("ValveFile", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_DirType = handlesys->CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_ValveDirType = handlesys->CreateType("ValveDirectory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_pLogHook = forwardsys->CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String);
|
||||
pluginsys->AddPluginsListener(this);
|
||||
}
|
||||
@ -80,8 +208,12 @@ public:
|
||||
forwardsys->ReleaseForward(g_pLogHook);
|
||||
handlesys->RemoveType(g_DirType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_FileType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_ValveFileType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_ValveDirType, g_pCoreIdent);
|
||||
g_DirType = 0;
|
||||
g_FileType = 0;
|
||||
g_ValveFileType = 0;
|
||||
g_ValveDirType = 0;
|
||||
}
|
||||
virtual void OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
@ -95,6 +227,17 @@ public:
|
||||
IDirectory *pDir = (IDirectory *)object;
|
||||
libsys->CloseDirectory(pDir);
|
||||
}
|
||||
else if (type == g_ValveFileType)
|
||||
{
|
||||
FileHandle_t fp = (FileHandle_t) object;
|
||||
smcore.filesystem->Close(fp);
|
||||
}
|
||||
else if (type == g_ValveDirType)
|
||||
{
|
||||
ValveDirectory *valveDir = (ValveDirectory *)object;
|
||||
smcore.filesystem->FindClose(valveDir->hndl);
|
||||
delete valveDir;
|
||||
}
|
||||
}
|
||||
virtual void AddLogHook(IPluginFunction *pFunc)
|
||||
{
|
||||
@ -127,23 +270,56 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
IDirectory *pDir = libsys->OpenDirectory(realpath);
|
||||
if (!pDir)
|
||||
|
||||
Handle_t handle = 0;
|
||||
|
||||
if (params[0] >= 2 && params[2])
|
||||
{
|
||||
return 0;
|
||||
char wildcardedPath[PLATFORM_MAX_PATH];
|
||||
snprintf(wildcardedPath, sizeof(wildcardedPath), "%s*", path);
|
||||
ValveDirectory *valveDir = new ValveDirectory;
|
||||
|
||||
char *pathID;
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *pFirst = smcore.filesystem->FindFirstEx(wildcardedPath, pathID, &valveDir->hndl);
|
||||
if (pFirst)
|
||||
{
|
||||
valveDir->bHandledFirstPath = false;
|
||||
strncpy(valveDir->szFirstPath, pFirst, sizeof(valveDir->szFirstPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
valveDir->bHandledFirstPath = true;
|
||||
}
|
||||
|
||||
handle = handlesys->CreateHandle(g_ValveDirType, valveDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
return handlesys->CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
IDirectory *pDir = libsys->OpenDirectory(realpath);
|
||||
if (!pDir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle = handlesys->CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
IDirectory *pDir;
|
||||
void *pTempDir;
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
int err;
|
||||
@ -151,44 +327,90 @@ static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
|
||||
!= HandleError_None)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DirType, &sec, &pTempDir)) == HandleError_None)
|
||||
{
|
||||
IDirectory *pDir = (IDirectory *)pTempDir;
|
||||
if (!pDir->MoreFiles())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t *filetype;
|
||||
if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pDir->IsEntryDirectory())
|
||||
{
|
||||
*filetype = 1;
|
||||
} else if (pDir->IsEntryFile()) {
|
||||
*filetype = 2;
|
||||
} else {
|
||||
*filetype = 0;
|
||||
}
|
||||
|
||||
const char *path = pDir->GetEntryName();
|
||||
if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
return pContext->ThrowNativeErrorEx(err, NULL);
|
||||
}
|
||||
|
||||
pDir->NextEntry();
|
||||
}
|
||||
else if ((herr=handlesys->ReadHandle(hndl, g_ValveDirType, &sec, &pTempDir)) == HandleError_None)
|
||||
{
|
||||
ValveDirectory *valveDir = (ValveDirectory *)pTempDir;
|
||||
|
||||
const char *pEntry = NULL;
|
||||
if (!valveDir->bHandledFirstPath)
|
||||
{
|
||||
if (valveDir->szFirstPath[0])
|
||||
{
|
||||
pEntry = valveDir->szFirstPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntry = smcore.filesystem->FindNext(valveDir->hndl);
|
||||
}
|
||||
|
||||
valveDir->bHandledFirstPath = true;
|
||||
|
||||
// No more entries
|
||||
if (!pEntry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err=pContext->StringToLocalUTF8(params[2], params[3], pEntry, NULL))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
return pContext->ThrowNativeErrorEx(err, NULL);
|
||||
}
|
||||
|
||||
cell_t *filetype;
|
||||
if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (smcore.filesystem->FindIsDirectory(valveDir->hndl))
|
||||
{
|
||||
*filetype = 1;
|
||||
} else {
|
||||
*filetype = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDir->MoreFiles())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cell_t *filetype;
|
||||
if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pDir->IsEntryDirectory())
|
||||
{
|
||||
*filetype = 1;
|
||||
} else if (pDir->IsEntryFile()) {
|
||||
*filetype = 2;
|
||||
} else {
|
||||
*filetype = 0;
|
||||
}
|
||||
|
||||
const char *path = pDir->GetEntryName();
|
||||
if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pDir->NextEntry();
|
||||
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
|
||||
@ -206,16 +428,40 @@ static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
|
||||
FILE *pFile = fopen(realpath, mode);
|
||||
if (!pFile)
|
||||
Handle_t handle = 0;
|
||||
HandleType_t handleType;
|
||||
FSHelper fshelper;
|
||||
const char *openpath;
|
||||
char *pathID;
|
||||
if (params[0] <= 2 || !params[3])
|
||||
{
|
||||
return 0;
|
||||
handleType = g_FileType;
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
openpath = realpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((err=pContext->LocalToStringNULL(params[4], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
handleType = g_ValveFileType;
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
openpath = name;
|
||||
}
|
||||
|
||||
return handlesys->CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
void *pFile = fshelper.Open(openpath, mode, pathID);
|
||||
if (pFile)
|
||||
{
|
||||
handle = handlesys->CreateHandle(handleType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
|
||||
@ -228,10 +474,29 @@ static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
FSHelper fshelper;
|
||||
const char *filepath;
|
||||
char *pathID;
|
||||
if (params[0] < 2 || !params[2])
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
filepath = realpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
filepath = name;
|
||||
}
|
||||
|
||||
return (unlink(realpath)) ? 0 : 1;
|
||||
return fshelper.Remove(filepath, pathID) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
|
||||
@ -239,18 +504,12 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
int err;
|
||||
|
||||
void *pFile;
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *buf;
|
||||
if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE)
|
||||
{
|
||||
@ -258,12 +517,22 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fgets(buf, params[3], pFile) == NULL)
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
return 0;
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return fshelper.ReadLine(buf, params[3], pFile) == NULL ? 0 : 1;
|
||||
}
|
||||
|
||||
static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
|
||||
@ -271,18 +540,26 @@ static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
FSHelper fshelper;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return (feof(pFile)) ? 1 : 0;
|
||||
return fshelper.EndOfFile(pFile) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
|
||||
@ -290,18 +567,26 @@ static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
FSHelper fshelper;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
fseek(pFile, params[2], params[3]);
|
||||
fshelper.Seek(pFile, params[2], params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -311,18 +596,27 @@ static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return ftell(pFile);
|
||||
return (cell_t)fshelper.Tell(pFile);
|
||||
}
|
||||
|
||||
static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
|
||||
@ -337,7 +631,17 @@ static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (params[0] >= 2 && params[2] == 1)
|
||||
{
|
||||
return smcore.filesystem->FileExists(name) ? 1 : 0;
|
||||
char *pathID = NULL;
|
||||
if (params[0] >= 3)
|
||||
{
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return smcore.filesystem->FileExists(name, pathID) ? 1 : 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
@ -381,6 +685,19 @@ static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[0] >= 3 && params[3] == 1)
|
||||
{
|
||||
char *pathID;
|
||||
if ((err=pContext->LocalToStringNULL(params[4], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
smcore.filesystem->RenameFile(oldpath, newpath, pathID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char new_realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath);
|
||||
@ -403,6 +720,18 @@ static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[0] >= 2 && params[2] == 1)
|
||||
{
|
||||
char *pathID;
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return smcore.filesystem->IsDirectory(name, pathID) ? 1 : 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
@ -443,9 +772,19 @@ static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (params[0] >= 2 && params[2] == 1)
|
||||
{
|
||||
if (smcore.filesystem->FileExists(name))
|
||||
char *pathID = NULL;
|
||||
if (params[0] >= 3)
|
||||
{
|
||||
return smcore.filesystem->Size(name);
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (smcore.filesystem->FileExists(name, pathID))
|
||||
{
|
||||
return smcore.filesystem->Size(name, pathID);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -508,9 +847,29 @@ static cell_t sm_SetFilePermissions(IPluginContext *pContext, const cell_t *para
|
||||
static cell_t sm_CreateDirectory(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *name;
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
|
||||
pContext->LocalToString(params[1], &name);
|
||||
|
||||
if (params[0] >= 3 && params[3] == 1)
|
||||
{
|
||||
int err;
|
||||
char *pathID;
|
||||
if ((err=pContext->LocalToStringNULL(params[4], &pathID)) != SP_ERROR_NONE)
|
||||
{
|
||||
return pContext->ThrowNativeErrorEx(err, NULL);
|
||||
}
|
||||
|
||||
if (smcore.filesystem->IsDirectory(name, pathID))
|
||||
return 0;
|
||||
|
||||
smcore.filesystem->CreateDirHierarchy(name, pathID);
|
||||
|
||||
if (smcore.filesystem->IsDirectory(name, pathID))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
@ -541,19 +900,14 @@ static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
void *pTempFile;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *fmt;
|
||||
int err;
|
||||
|
||||
if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
@ -562,8 +916,23 @@ static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
char buffer[2048];
|
||||
int arg = 3;
|
||||
smcore.atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
|
||||
fprintf(pFile, "%s\n", buffer);
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pTempFile)) == HandleError_None)
|
||||
{
|
||||
FILE *pFile = (FILE *) pTempFile;
|
||||
smcore.atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
|
||||
fprintf(pFile, "%s\n", buffer);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pTempFile)) == HandleError_None)
|
||||
{
|
||||
FileHandle_t pFile = (FileHandle_t) pTempFile;
|
||||
smcore.atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
|
||||
sprintf(buffer, "%s\n", buffer);
|
||||
smcore.filesystem->FPrint(pFile, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -573,18 +942,26 @@ static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
FSHelper fshelper;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return (fflush(pFile) == 0) ? 1 : 0;
|
||||
return fshelper.Flush(pFile) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
|
||||
@ -749,11 +1126,20 @@ static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
size_t read = 0;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
void *pFile = NULL;
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
@ -765,21 +1151,21 @@ static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
cell_t *data;
|
||||
pContext->LocalToPhysAddr(params[2], &data);
|
||||
|
||||
|
||||
if (params[4] == 4)
|
||||
{
|
||||
read = fread(data, sizeof(cell_t), params[3], pFile);
|
||||
read = fshelper.Read(data, sizeof(cell_t) * params[3], pFile);
|
||||
}
|
||||
else if (params[4] == 2)
|
||||
{
|
||||
uint16_t val;
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fread(&val, sizeof(uint16_t), 1, pFile) != 1)
|
||||
if (fshelper.Read(&val, sizeof(uint16_t), pFile) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
data[read++] = val;
|
||||
data[read += sizeof(uint16_t)] = val;
|
||||
}
|
||||
}
|
||||
else if (params[4] == 1)
|
||||
@ -787,20 +1173,20 @@ static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
|
||||
uint8_t val;
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fread(&val, sizeof(uint8_t), 1, pFile) != 1)
|
||||
if (fshelper.Read(&val, sizeof(uint8_t), pFile) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
data[read++] = val;
|
||||
data[read += sizeof(uint8_t)] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (read != (size_t)params[3] && ferror(pFile) != 0)
|
||||
if (read != ((size_t)params[3] * params[4]) && fshelper.HasError(pFile))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read;
|
||||
return read / params[4];
|
||||
}
|
||||
|
||||
static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
|
||||
@ -808,18 +1194,27 @@ static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
cell_t num_read = 0;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *buffer;
|
||||
pContext->LocalToString(params[2], &buffer);
|
||||
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr=handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (params[4] != -1)
|
||||
{
|
||||
if (size_t(params[4]) > size_t(params[3]))
|
||||
@ -829,9 +1224,9 @@ static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
|
||||
params[3]);
|
||||
}
|
||||
|
||||
num_read = (cell_t)fread(buffer, 1, params[4], pFile);
|
||||
num_read = (cell_t)fshelper.Read(buffer, params[4], pFile);
|
||||
|
||||
if (num_read != params[4] && ferror(pFile))
|
||||
if (num_read != params[4] && fshelper.HasError(pFile))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -846,9 +1241,9 @@ static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (fread(&val, sizeof(val), 1, pFile) != 1)
|
||||
if (fshelper.Read(&val, sizeof(val), pFile) != 1)
|
||||
{
|
||||
if (ferror(pFile))
|
||||
if (fshelper.HasError(pFile))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -877,10 +1272,18 @@ static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr=handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
@ -897,7 +1300,7 @@ static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (params[4] == 4)
|
||||
{
|
||||
if (fwrite(data, sizeof(cell_t), params[3], pFile) != (size_t)params[3])
|
||||
if (fshelper.Write(data, sizeof(cell_t) * params[3], pFile) != (sizeof(cell_t) * (size_t)params[3]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -906,7 +1309,7 @@ static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fwrite(&data[i], sizeof(int16_t), 1, pFile) != 1)
|
||||
if (fshelper.Write(&data[i], sizeof(int16_t), pFile) != sizeof(int16_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -916,7 +1319,7 @@ static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fwrite(&data[i], sizeof(int8_t), 1, pFile) != 1)
|
||||
if (fshelper.Write(&data[i], sizeof(int8_t), pFile) != sizeof(int8_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -931,10 +1334,18 @@ static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
void *pFile;
|
||||
FSHelper fshelper;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::STDIO);
|
||||
}
|
||||
else if ((herr=handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None)
|
||||
{
|
||||
fshelper.SetFSType(FSType::VALVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
@ -949,7 +1360,7 @@ static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params)
|
||||
len++;
|
||||
}
|
||||
|
||||
return (fwrite(buffer, sizeof(char), len, pFile) == len) ? 1 : 0;
|
||||
return (fshelper.Write(buffer, len, pFile) == len) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t sm_AddGameLogHook(IPluginContext *pContext, const cell_t *params)
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "MersenneTwister.h"
|
||||
#include <IPluginSys.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-float.h>
|
||||
|
||||
/****************************************
|
||||
* *
|
||||
|
@ -37,12 +37,21 @@
|
||||
#include <ITranslator.h>
|
||||
#include <sh_string.h>
|
||||
#include <sh_list.h>
|
||||
#include "GameConfigs.h"
|
||||
#include "CellArray.h"
|
||||
#include "AutoHandleRooter.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
using namespace SourceMod;
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _WIN32
|
||||
#define PRIu64 "I64u"
|
||||
#else
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const int kActivityNone = 0;
|
||||
static const int kActivityNonAdmins = 1; // Show admin activity to non-admins anonymously.
|
||||
static const int kActivityNonAdminsNames = 2; // If 1 is specified, admin names will be shown.
|
||||
@ -322,9 +331,17 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
|
||||
// Must match clients.inc
|
||||
enum class AuthIdType
|
||||
{
|
||||
Engine = 0,
|
||||
Steam2,
|
||||
Steam3,
|
||||
SteamId64,
|
||||
};
|
||||
|
||||
static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authType, cell_t local_addr, size_t bytes, bool validate)
|
||||
{
|
||||
int index = params[1];
|
||||
if ((index < 1) || (index > playerhelpers->GetMaxClients()))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Client index %d is invalid", index);
|
||||
@ -336,24 +353,113 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
|
||||
return pCtx->ThrowNativeError("Client %d is not connected", index);
|
||||
}
|
||||
|
||||
bool validate = true;
|
||||
if (params[0] > 3)
|
||||
{
|
||||
validate = !!params[4];
|
||||
}
|
||||
|
||||
const char *authstr = pPlayer->GetAuthString(validate);
|
||||
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
switch (authType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case AuthIdType::Engine:
|
||||
{
|
||||
const char *authstr = pPlayer->GetAuthString(validate);
|
||||
if (!authstr || authstr[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), authstr);
|
||||
pCtx->StringToLocal(local_addr, bytes, authstr);
|
||||
}
|
||||
break;
|
||||
case AuthIdType::Steam2:
|
||||
case AuthIdType::Steam3:
|
||||
{
|
||||
if (pPlayer->IsFakeClient())
|
||||
{
|
||||
pCtx->StringToLocal(local_addr, bytes, "BOT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t steamId = pPlayer->GetSteamId64(validate);
|
||||
if (steamId == 0)
|
||||
{
|
||||
if (gamehelpers->IsLANServer())
|
||||
{
|
||||
pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_LAN");
|
||||
return 1;
|
||||
}
|
||||
else if (!validate)
|
||||
{
|
||||
pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_PENDING");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char szAuth[64];
|
||||
unsigned int universe = steamId >> 56;
|
||||
unsigned int accountId = steamId & 0xFFFFFFFF;
|
||||
unsigned int instance = (steamId >> 32) & 0x000FFFFF;
|
||||
if (authType == AuthIdType::Steam2)
|
||||
{
|
||||
if (atoi(g_pGameConf->GetKeyValue("UseInvalidUniverseInSteam2IDs")) == 1)
|
||||
{
|
||||
universe = 0;
|
||||
}
|
||||
|
||||
snprintf(szAuth, sizeof(szAuth), "STEAM_%u:%u:%u", universe, accountId & 1, accountId >> 1);
|
||||
}
|
||||
else if (instance != 1)
|
||||
{
|
||||
snprintf(szAuth, sizeof(szAuth), "[U:%u:%u:%u]", universe, accountId, instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(szAuth, sizeof(szAuth), "[U:%u:%u]", universe, accountId);
|
||||
}
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, szAuth);
|
||||
}
|
||||
break;
|
||||
|
||||
case AuthIdType::SteamId64:
|
||||
{
|
||||
if (pPlayer->IsFakeClient() || gamehelpers->IsLANServer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t steamId = pPlayer->GetSteamId64(validate);
|
||||
if (steamId == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char szAuth[64];
|
||||
snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, szAuth);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
bool validate = true;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
validate = !!params[4];
|
||||
}
|
||||
|
||||
return SteamIdToLocal(pCtx, params[1], AuthIdType::Steam2, params[2], (size_t)params[3], validate);
|
||||
}
|
||||
|
||||
static cell_t sm_GetClientAuthId(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
return SteamIdToLocal(pCtx, params[1], (AuthIdType)params[2], params[3], (size_t)params[4], params[5] != 0);
|
||||
}
|
||||
|
||||
static cell_t sm_GetSteamAccountID(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
int index = params[1];
|
||||
@ -1540,6 +1646,7 @@ REGISTER_NATIVES(playernatives)
|
||||
{ "CanUserTarget", CanUserTarget },
|
||||
{ "ChangeClientTeam", ChangeClientTeam },
|
||||
{ "GetClientAuthString", sm_GetClientAuthStr },
|
||||
{ "GetClientAuthId", sm_GetClientAuthId },
|
||||
{ "GetSteamAccountID", sm_GetSteamAccountID },
|
||||
{ "GetClientCount", sm_GetClientCount },
|
||||
{ "GetClientInfo", sm_GetClientInfo },
|
||||
|
@ -147,6 +147,10 @@ public:
|
||||
{
|
||||
return filesystem->FindNext(handle);
|
||||
}
|
||||
bool FindIsDirectory(FileFindHandle_t handle)
|
||||
{
|
||||
return filesystem->FindIsDirectory(handle);
|
||||
}
|
||||
void FindClose(FileFindHandle_t handle)
|
||||
{
|
||||
filesystem->FindClose(handle);
|
||||
@ -175,6 +179,50 @@ public:
|
||||
{
|
||||
return filesystem->Size(pFileName, pPathID);
|
||||
}
|
||||
int Read(void* pOutput, int size, FileHandle_t file)
|
||||
{
|
||||
return filesystem->Read(pOutput, size, file);
|
||||
}
|
||||
int Write(void const* pInput, int size, FileHandle_t file)
|
||||
{
|
||||
return filesystem->Write(pInput, size, file);
|
||||
}
|
||||
void Seek(FileHandle_t file, int pos, int seekType)
|
||||
{
|
||||
filesystem->Seek(file, pos, (FileSystemSeek_t) seekType);
|
||||
}
|
||||
unsigned int Tell(FileHandle_t file)
|
||||
{
|
||||
return filesystem->Tell(file);
|
||||
}
|
||||
int FPrint(FileHandle_t file, const char *pData)
|
||||
{
|
||||
return filesystem->FPrintf(file, "%s", pData);
|
||||
}
|
||||
void Flush(FileHandle_t file)
|
||||
{
|
||||
filesystem->Flush(file);
|
||||
}
|
||||
bool IsOk(FileHandle_t file)
|
||||
{
|
||||
return filesystem->IsOk(file);
|
||||
}
|
||||
void RemoveFile(const char *pRelativePath, const char *pathID)
|
||||
{
|
||||
filesystem->RemoveFile(pRelativePath, pathID);
|
||||
}
|
||||
void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID)
|
||||
{
|
||||
filesystem->RenameFile(pOldPath, pNewPath, pathID);
|
||||
}
|
||||
bool IsDirectory(const char *pFileName, const char *pathID)
|
||||
{
|
||||
return filesystem->IsDirectory(pFileName, pathID);
|
||||
}
|
||||
void CreateDirHierarchy(const char *path, const char *pathID)
|
||||
{
|
||||
filesystem->CreateDirHierarchy(path, pathID);
|
||||
}
|
||||
};
|
||||
|
||||
static VFileSystem_Logic logic_filesystem;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "logic_bridge.h"
|
||||
#include "sourcemod.h"
|
||||
#include <am-utility.h>
|
||||
#include <am-float.h>
|
||||
|
||||
#define LADJUST 0x00000004 /* left adjustment */
|
||||
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
|
||||
|
@ -219,7 +219,7 @@ void ClientPrefs::DatabaseConnect()
|
||||
char error[256];
|
||||
int errCode = 0;
|
||||
|
||||
Database = Newborn<IDatabase>(Driver->Connect(DBInfo, true, error, sizeof(error)));
|
||||
Database = AdoptRef(Driver->Connect(DBInfo, true, error, sizeof(error)));
|
||||
|
||||
if (!Database)
|
||||
{
|
||||
|
@ -101,6 +101,9 @@ MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
|
||||
m_Info.driver = NULL;
|
||||
m_Info.maxTimeout = info->maxTimeout;
|
||||
m_Info.port = info->port;
|
||||
|
||||
// DBI, for historical reasons, guarantees an initial refcount of 1.
|
||||
AddRef();
|
||||
}
|
||||
|
||||
MyDatabase::~MyDatabase()
|
||||
|
@ -88,6 +88,10 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] =
|
||||
{"Reload", "DT_BaseCombatWeapon", false},
|
||||
{"ReloadPost", "DT_BaseCombatWeapon", false},
|
||||
{"GetMaxHealth", "", false},
|
||||
{"Blocked", "", false},
|
||||
{"BlockedPost", "", false},
|
||||
{"OnTakeDamageAlive", "DT_BaseCombatCharacter", false},
|
||||
{"OnTakeDamageAlivePost", "DT_BaseCombatCharacter", false},
|
||||
};
|
||||
|
||||
SDKHooks g_Interface;
|
||||
@ -166,6 +170,7 @@ SH_DECL_MANUALHOOK0(GetMaxHealth, 0, 0, 0, int);
|
||||
#endif
|
||||
SH_DECL_MANUALHOOK1_void(GroundEntChanged, 0, 0, 0, void *);
|
||||
SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &);
|
||||
SH_DECL_MANUALHOOK1(OnTakeDamageAlive, 0, 0, 0, int, CTakeDamageInfoHack &);
|
||||
SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0);
|
||||
SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0);
|
||||
SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool);
|
||||
@ -191,6 +196,7 @@ SH_DECL_MANUALHOOK1(Weapon_CanUse, 0, 0, 0, bool, CBaseCombatWeapon *);
|
||||
SH_DECL_MANUALHOOK3_void(Weapon_Drop, 0, 0, 0, CBaseCombatWeapon *, const Vector *, const Vector *);
|
||||
SH_DECL_MANUALHOOK1_void(Weapon_Equip, 0, 0, 0, CBaseCombatWeapon *);
|
||||
SH_DECL_MANUALHOOK2(Weapon_Switch, 0, 0, 0, bool, CBaseCombatWeapon *, int);
|
||||
SH_DECL_MANUALHOOK1_void(Blocked, 0, 0, 0, CBaseEntity *);
|
||||
|
||||
|
||||
/**
|
||||
@ -512,6 +518,7 @@ void SDKHooks::SetupHooks()
|
||||
CHECKOFFSET(FireBullets, false, true);
|
||||
CHECKOFFSET(GroundEntChanged, false, true);
|
||||
CHECKOFFSET(OnTakeDamage, true, true);
|
||||
CHECKOFFSET(OnTakeDamageAlive,true, true);
|
||||
CHECKOFFSET(PreThink, true, true);
|
||||
CHECKOFFSET(PostThink, true, true);
|
||||
CHECKOFFSET(Reload, true, true);
|
||||
@ -529,6 +536,7 @@ void SDKHooks::SetupHooks()
|
||||
CHECKOFFSET_W(Equip, true, true);
|
||||
CHECKOFFSET_W(Switch, true, true);
|
||||
CHECKOFFSET(VPhysicsUpdate, true, true);
|
||||
CHECKOFFSET(Blocked, true, true);
|
||||
|
||||
// this one is in a class all its own -_-
|
||||
offset = 0;
|
||||
@ -603,6 +611,12 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
|
||||
case SDKHook_OnTakeDamagePost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
|
||||
break;
|
||||
case SDKHook_OnTakeDamageAlive:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamageAlive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamageAlive), false);
|
||||
break;
|
||||
case SDKHook_OnTakeDamageAlivePost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamageAlive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamageAlivePost), true);
|
||||
break;
|
||||
case SDKHook_PreThink:
|
||||
hookid = SH_ADD_MANUALVPHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
|
||||
break;
|
||||
@ -699,6 +713,12 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
|
||||
case SDKHook_ShouldCollide:
|
||||
hookid = SH_ADD_MANUALVPHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
|
||||
break;
|
||||
case SDKHook_Blocked:
|
||||
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Blocked), false);
|
||||
break;
|
||||
case SDKHook_BlockedPost:
|
||||
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_BlockedPost), true);
|
||||
break;
|
||||
}
|
||||
|
||||
vhook.SetHookID(hookid);
|
||||
@ -989,12 +1009,12 @@ void SDKHooks::Hook_GroundEntChangedPost(void *pVar)
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType)
|
||||
{
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamage];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@ -1010,10 +1030,10 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
int weapon = info.GetWeapon();
|
||||
|
||||
Vector force = info.GetDamageForce();
|
||||
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
|
||||
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
|
||||
|
||||
Vector pos = info.GetDamagePosition();
|
||||
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
|
||||
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
|
||||
|
||||
cell_t res, ret = Pl_Continue;
|
||||
|
||||
@ -1029,23 +1049,23 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
callback->PushCellByRef(&damagetype);
|
||||
callback->PushCellByRef(&weapon);
|
||||
callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
|
||||
callback->PushCell(info.GetDamageCustom());
|
||||
callback->Execute(&res);
|
||||
|
||||
if(res >= ret)
|
||||
if (res >= ret)
|
||||
{
|
||||
ret = res;
|
||||
if(ret == Pl_Changed)
|
||||
if (ret == Pl_Changed)
|
||||
{
|
||||
CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
|
||||
if(!pEntAttacker)
|
||||
if (!pEntAttacker)
|
||||
{
|
||||
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
|
||||
if(!pEntInflictor)
|
||||
if (!pEntInflictor)
|
||||
{
|
||||
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
@ -1067,12 +1087,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret >= Pl_Handled)
|
||||
|
||||
if (ret >= Pl_Handled)
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, 1);
|
||||
|
||||
if(ret == Pl_Changed)
|
||||
RETURN_META_VALUE(MRES_HANDLED, 1);
|
||||
if (ret == Pl_Changed)
|
||||
RETURN_META_VALUE(MRES_HANDLED, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1080,12 +1100,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType)
|
||||
{
|
||||
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
|
||||
|
||||
CVTableHook vhook(pEntity);
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamagePost];
|
||||
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
|
||||
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
|
||||
{
|
||||
if (vhook != vtablehooklist[entry]->vtablehook)
|
||||
@ -1108,11 +1128,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
callback->PushCell(info.GetWeapon());
|
||||
|
||||
Vector force = info.GetDamageForce();
|
||||
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
|
||||
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
|
||||
callback->PushArray(damageForce, 3);
|
||||
|
||||
Vector pos = info.GetDamagePosition();
|
||||
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
|
||||
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
|
||||
callback->PushArray(damagePosition, 3);
|
||||
|
||||
callback->PushCell(info.GetDamageCustom());
|
||||
@ -1126,6 +1146,26 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamagePost);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamageAlive(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamageAlive);
|
||||
}
|
||||
|
||||
int SDKHooks::Hook_OnTakeDamageAlivePost(CTakeDamageInfoHack &info)
|
||||
{
|
||||
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamageAlivePost);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_PreThink()
|
||||
{
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);
|
||||
@ -1576,6 +1616,22 @@ void SDKHooks::Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics)
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdatePost);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_Blocked(CBaseEntity *pOther)
|
||||
{
|
||||
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_Blocked, pOther);
|
||||
|
||||
if(result >= Pl_Handled)
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void SDKHooks::Hook_BlockedPost(CBaseEntity *pOther)
|
||||
{
|
||||
Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon)
|
||||
{
|
||||
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon);
|
||||
|
@ -1,349 +1,361 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
#include <ISDKHooks.h>
|
||||
#include <IBinTools.h>
|
||||
#include <convar.h>
|
||||
#include <sh_list.h>
|
||||
#include <amtl/am-vector.h>
|
||||
#include <vtable_hook_helper.h>
|
||||
|
||||
#include <iplayerinfo.h>
|
||||
#include <shareddefs.h>
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <itoolentity.h>
|
||||
#endif
|
||||
|
||||
#include "takedamageinfohack.h"
|
||||
|
||||
#ifndef METAMOD_PLAPI_VERSION
|
||||
#define GetCGlobals pGlobals
|
||||
#define GetEngineFactory engineFactory
|
||||
#define GetServerFactory serverFactory
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
|
||||
#define GETMAXHEALTH_IS_VIRTUAL
|
||||
#endif
|
||||
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
|
||||
#define GAMEDESC_CAN_CHANGE
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
class CEntityKeyValues;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
|
||||
struct HookTypeData
|
||||
{
|
||||
const char *name;
|
||||
const char *dtReq;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
enum SDKHookType
|
||||
{
|
||||
SDKHook_EndTouch,
|
||||
SDKHook_FireBulletsPost,
|
||||
SDKHook_OnTakeDamage,
|
||||
SDKHook_OnTakeDamagePost,
|
||||
SDKHook_PreThink,
|
||||
SDKHook_PostThink,
|
||||
SDKHook_SetTransmit,
|
||||
SDKHook_Spawn,
|
||||
SDKHook_StartTouch,
|
||||
SDKHook_Think,
|
||||
SDKHook_Touch,
|
||||
SDKHook_TraceAttack,
|
||||
SDKHook_TraceAttackPost,
|
||||
SDKHook_WeaponCanSwitchTo,
|
||||
SDKHook_WeaponCanUse,
|
||||
SDKHook_WeaponDrop,
|
||||
SDKHook_WeaponEquip,
|
||||
SDKHook_WeaponSwitch,
|
||||
SDKHook_ShouldCollide,
|
||||
SDKHook_PreThinkPost,
|
||||
SDKHook_PostThinkPost,
|
||||
SDKHook_ThinkPost,
|
||||
SDKHook_EndTouchPost,
|
||||
SDKHook_GroundEntChangedPost,
|
||||
SDKHook_SpawnPost,
|
||||
SDKHook_StartTouchPost,
|
||||
SDKHook_TouchPost,
|
||||
SDKHook_VPhysicsUpdate,
|
||||
SDKHook_VPhysicsUpdatePost,
|
||||
SDKHook_WeaponCanSwitchToPost,
|
||||
SDKHook_WeaponCanUsePost,
|
||||
SDKHook_WeaponDropPost,
|
||||
SDKHook_WeaponEquipPost,
|
||||
SDKHook_WeaponSwitchPost,
|
||||
SDKHook_Use,
|
||||
SDKHook_UsePost,
|
||||
SDKHook_Reload,
|
||||
SDKHook_ReloadPost,
|
||||
SDKHook_GetMaxHealth,
|
||||
SDKHook_MAXHOOKS
|
||||
};
|
||||
|
||||
enum HookReturn
|
||||
{
|
||||
HookRet_Successful,
|
||||
HookRet_InvalidEntity,
|
||||
HookRet_InvalidHookType,
|
||||
HookRet_NotSupported,
|
||||
HookRet_BadEntForHookType,
|
||||
};
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS
|
||||
typedef void *(*ReticulateSplines)();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Classes
|
||||
*/
|
||||
|
||||
class IPhysicsObject;
|
||||
class CDmgAccumulator;
|
||||
typedef CBaseEntity CBaseCombatWeapon;
|
||||
|
||||
struct HookList
|
||||
{
|
||||
public:
|
||||
int entity;
|
||||
IPluginFunction *callback;
|
||||
};
|
||||
|
||||
class CVTableList
|
||||
{
|
||||
public:
|
||||
CVTableList() : vtablehook(NULL)
|
||||
{
|
||||
};
|
||||
|
||||
~CVTableList()
|
||||
{
|
||||
delete vtablehook;
|
||||
};
|
||||
public:
|
||||
CVTableHook *vtablehook;
|
||||
ke::Vector<HookList> hooks;
|
||||
};
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
#include <ISDKHooks.h>
|
||||
#include <IBinTools.h>
|
||||
#include <convar.h>
|
||||
#include <sh_list.h>
|
||||
#include <amtl/am-vector.h>
|
||||
#include <vtable_hook_helper.h>
|
||||
|
||||
#include <iplayerinfo.h>
|
||||
#include <shareddefs.h>
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
#include <itoolentity.h>
|
||||
#endif
|
||||
|
||||
#include "takedamageinfohack.h"
|
||||
|
||||
#ifndef METAMOD_PLAPI_VERSION
|
||||
#define GetCGlobals pGlobals
|
||||
#define GetEngineFactory engineFactory
|
||||
#define GetServerFactory serverFactory
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
|
||||
#define GETMAXHEALTH_IS_VIRTUAL
|
||||
#endif
|
||||
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
|
||||
#define GAMEDESC_CAN_CHANGE
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
class CEntityKeyValues;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
|
||||
struct HookTypeData
|
||||
{
|
||||
const char *name;
|
||||
const char *dtReq;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
enum SDKHookType
|
||||
{
|
||||
SDKHook_EndTouch,
|
||||
SDKHook_FireBulletsPost,
|
||||
SDKHook_OnTakeDamage,
|
||||
SDKHook_OnTakeDamagePost,
|
||||
SDKHook_PreThink,
|
||||
SDKHook_PostThink,
|
||||
SDKHook_SetTransmit,
|
||||
SDKHook_Spawn,
|
||||
SDKHook_StartTouch,
|
||||
SDKHook_Think,
|
||||
SDKHook_Touch,
|
||||
SDKHook_TraceAttack,
|
||||
SDKHook_TraceAttackPost,
|
||||
SDKHook_WeaponCanSwitchTo,
|
||||
SDKHook_WeaponCanUse,
|
||||
SDKHook_WeaponDrop,
|
||||
SDKHook_WeaponEquip,
|
||||
SDKHook_WeaponSwitch,
|
||||
SDKHook_ShouldCollide,
|
||||
SDKHook_PreThinkPost,
|
||||
SDKHook_PostThinkPost,
|
||||
SDKHook_ThinkPost,
|
||||
SDKHook_EndTouchPost,
|
||||
SDKHook_GroundEntChangedPost,
|
||||
SDKHook_SpawnPost,
|
||||
SDKHook_StartTouchPost,
|
||||
SDKHook_TouchPost,
|
||||
SDKHook_VPhysicsUpdate,
|
||||
SDKHook_VPhysicsUpdatePost,
|
||||
SDKHook_WeaponCanSwitchToPost,
|
||||
SDKHook_WeaponCanUsePost,
|
||||
SDKHook_WeaponDropPost,
|
||||
SDKHook_WeaponEquipPost,
|
||||
SDKHook_WeaponSwitchPost,
|
||||
SDKHook_Use,
|
||||
SDKHook_UsePost,
|
||||
SDKHook_Reload,
|
||||
SDKHook_ReloadPost,
|
||||
SDKHook_GetMaxHealth,
|
||||
SDKHook_Blocked,
|
||||
SDKHook_BlockedPost,
|
||||
SDKHook_OnTakeDamageAlive,
|
||||
SDKHook_OnTakeDamageAlivePost,
|
||||
SDKHook_MAXHOOKS
|
||||
};
|
||||
|
||||
enum HookReturn
|
||||
{
|
||||
HookRet_Successful,
|
||||
HookRet_InvalidEntity,
|
||||
HookRet_InvalidHookType,
|
||||
HookRet_NotSupported,
|
||||
HookRet_BadEntForHookType,
|
||||
};
|
||||
|
||||
#if SOURCE_ENGINE >= SE_CSS
|
||||
typedef void *(*ReticulateSplines)();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Classes
|
||||
*/
|
||||
|
||||
class IPhysicsObject;
|
||||
class CDmgAccumulator;
|
||||
typedef CBaseEntity CBaseCombatWeapon;
|
||||
|
||||
struct HookList
|
||||
{
|
||||
public:
|
||||
int entity;
|
||||
IPluginFunction *callback;
|
||||
};
|
||||
|
||||
class CVTableList
|
||||
{
|
||||
public:
|
||||
CVTableList() : vtablehook(NULL)
|
||||
{
|
||||
};
|
||||
|
||||
~CVTableList()
|
||||
{
|
||||
delete vtablehook;
|
||||
};
|
||||
public:
|
||||
CVTableHook *vtablehook;
|
||||
ke::Vector<HookList> hooks;
|
||||
};
|
||||
|
||||
class IEntityListener
|
||||
{
|
||||
public:
|
||||
virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
|
||||
virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
|
||||
virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
|
||||
};
|
||||
|
||||
class SDKHooks :
|
||||
public SDKExtension,
|
||||
public IConCommandBaseAccessor,
|
||||
public IPluginsListener,
|
||||
public IFeatureProvider,
|
||||
public IEntityListener,
|
||||
public IClientListener,
|
||||
public ISDKHooks
|
||||
{
|
||||
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);
|
||||
|
||||
/** Returns version string */
|
||||
virtual const char *GetExtensionVerString();
|
||||
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
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: // IPluginsListener
|
||||
virtual void OnPluginLoaded(IPlugin *plugin);
|
||||
virtual void OnPluginUnloaded(IPlugin *plugin);
|
||||
|
||||
public: // IConCommandBaseAccessor
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
|
||||
|
||||
public: // IFeatureProvider
|
||||
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
||||
|
||||
public: // IEntityListener
|
||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||
|
||||
public: // IClientListener
|
||||
virtual void OnClientPutInServer(int client);
|
||||
virtual void OnClientDisconnecting(int client);
|
||||
|
||||
public: // ISDKHooks
|
||||
virtual void AddEntityListener(ISMEntityListener *listener);
|
||||
virtual void RemoveEntityListener(ISMEntityListener *listener);
|
||||
|
||||
private:
|
||||
SourceHook::List<ISMEntityListener *> m_EntListeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
};
|
||||
|
||||
class SDKHooks :
|
||||
public SDKExtension,
|
||||
public IConCommandBaseAccessor,
|
||||
public IPluginsListener,
|
||||
public IFeatureProvider,
|
||||
public IEntityListener,
|
||||
public IClientListener,
|
||||
public ISDKHooks
|
||||
{
|
||||
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);
|
||||
|
||||
/** Returns version string */
|
||||
virtual const char *GetExtensionVerString();
|
||||
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
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: // IPluginsListener
|
||||
virtual void OnPluginLoaded(IPlugin *plugin);
|
||||
virtual void OnPluginUnloaded(IPlugin *plugin);
|
||||
|
||||
public: // IConCommandBaseAccessor
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
|
||||
|
||||
public: // IFeatureProvider
|
||||
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
||||
|
||||
public: // IEntityListener
|
||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||
|
||||
public: // IClientListener
|
||||
virtual void OnClientPutInServer(int client);
|
||||
virtual void OnClientDisconnecting(int client);
|
||||
|
||||
public: // ISDKHooks
|
||||
virtual void AddEntityListener(ISMEntityListener *listener);
|
||||
virtual void RemoveEntityListener(ISMEntityListener *listener);
|
||||
|
||||
private:
|
||||
SourceHook::List<ISMEntityListener *> m_EntListeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Functions
|
||||
*/
|
||||
cell_t Call(int entity, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
|
||||
void SetupHooks();
|
||||
|
||||
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
|
||||
/**
|
||||
* IServerGameDLL & IVEngineServer Hook Handlers
|
||||
*/
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
const char *Hook_GetGameDescription();
|
||||
#endif
|
||||
const char *Hook_GetMapEntitiesString();
|
||||
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
|
||||
|
||||
/**
|
||||
* CBaseEntity Hook Handlers
|
||||
*/
|
||||
void Hook_EndTouch(CBaseEntity *pOther);
|
||||
void Hook_EndTouchPost(CBaseEntity *pOther);
|
||||
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
|
||||
#ifdef GETMAXHEALTH_IS_VIRTUAL
|
||||
int Hook_GetMaxHealth();
|
||||
#endif
|
||||
void Hook_GroundEntChangedPost(void *pVar);
|
||||
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
|
||||
void Hook_PreThink();
|
||||
void Hook_PreThinkPost();
|
||||
void Hook_PostThink();
|
||||
void Hook_PostThinkPost();
|
||||
bool Hook_Reload();
|
||||
bool Hook_ReloadPost();
|
||||
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
|
||||
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void Hook_Spawn(CEntityKeyValues *kv);
|
||||
void Hook_SpawnPost(CEntityKeyValues *kv);
|
||||
#else
|
||||
void Hook_Spawn();
|
||||
void Hook_SpawnPost();
|
||||
#endif
|
||||
void Hook_StartTouch(CBaseEntity *pOther);
|
||||
void Hook_StartTouchPost(CBaseEntity *pOther);
|
||||
void Hook_Think();
|
||||
void Hook_ThinkPost();
|
||||
void Hook_Touch(CBaseEntity *pOther);
|
||||
void Hook_TouchPost(CBaseEntity *pOther);
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
#else
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
#endif
|
||||
void Hook_UpdateOnRemove();
|
||||
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
|
||||
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
|
||||
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
|
||||
private:
|
||||
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
|
||||
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
|
||||
void Unhook(CBaseEntity *pEntity);
|
||||
void Unhook(IPluginContext *pContext);
|
||||
};
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
|
||||
|
||||
extern ICvar *icvar;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
|
||||
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
|
||||
void SetupHooks();
|
||||
|
||||
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
|
||||
|
||||
/**
|
||||
* IServerGameDLL & IVEngineServer Hook Handlers
|
||||
*/
|
||||
#ifdef GAMEDESC_CAN_CHANGE
|
||||
const char *Hook_GetGameDescription();
|
||||
#endif
|
||||
const char *Hook_GetMapEntitiesString();
|
||||
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
|
||||
|
||||
/**
|
||||
* CBaseEntity Hook Handlers
|
||||
*/
|
||||
void Hook_EndTouch(CBaseEntity *pOther);
|
||||
void Hook_EndTouchPost(CBaseEntity *pOther);
|
||||
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
|
||||
#ifdef GETMAXHEALTH_IS_VIRTUAL
|
||||
int Hook_GetMaxHealth();
|
||||
#endif
|
||||
void Hook_GroundEntChangedPost(void *pVar);
|
||||
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamageAlive(CTakeDamageInfoHack &info);
|
||||
int Hook_OnTakeDamageAlivePost(CTakeDamageInfoHack &info);
|
||||
void Hook_PreThink();
|
||||
void Hook_PreThinkPost();
|
||||
void Hook_PostThink();
|
||||
void Hook_PostThinkPost();
|
||||
bool Hook_Reload();
|
||||
bool Hook_ReloadPost();
|
||||
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
|
||||
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void Hook_Spawn(CEntityKeyValues *kv);
|
||||
void Hook_SpawnPost(CEntityKeyValues *kv);
|
||||
#else
|
||||
void Hook_Spawn();
|
||||
void Hook_SpawnPost();
|
||||
#endif
|
||||
void Hook_StartTouch(CBaseEntity *pOther);
|
||||
void Hook_StartTouchPost(CBaseEntity *pOther);
|
||||
void Hook_Think();
|
||||
void Hook_ThinkPost();
|
||||
void Hook_Touch(CBaseEntity *pOther);
|
||||
void Hook_TouchPost(CBaseEntity *pOther);
|
||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
|
||||
#else
|
||||
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
|
||||
#endif
|
||||
void Hook_UpdateOnRemove();
|
||||
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
|
||||
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
|
||||
void Hook_Blocked(CBaseEntity *pOther);
|
||||
void Hook_BlockedPost(CBaseEntity *pOther);
|
||||
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
|
||||
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
|
||||
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
|
||||
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
|
||||
|
||||
private:
|
||||
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
|
||||
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
|
||||
void Unhook(CBaseEntity *pEntity);
|
||||
void Unhook(IPluginContext *pContext);
|
||||
|
||||
private:
|
||||
int HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType);
|
||||
int HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType);
|
||||
};
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
|
||||
|
||||
extern ICvar *icvar;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
extern IServerTools *servertools;
|
||||
#endif
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
@ -36,6 +36,8 @@
|
||||
SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
|
||||
m_sq3(sq3), m_Persistent(persistent)
|
||||
{
|
||||
// DBI, for historical reasons, guarantees an initial refcount of 1.
|
||||
AddRef();
|
||||
}
|
||||
|
||||
SqDatabase::~SqDatabase()
|
||||
|
@ -36,5 +36,10 @@
|
||||
"windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x6A"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,5 +53,10 @@
|
||||
"mac" "@gEntList"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,5 +42,10 @@
|
||||
"windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,11 @@
|
||||
"windows" "\x56\x8B\x74\x24\x08\x57\x56\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x84\xC0\x0F\x85\xC4\x00\x00\x00\x56\x8D"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,4 +58,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,5 +52,10 @@
|
||||
"mac" "@gEntList"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,5 +41,10 @@
|
||||
"windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
|
||||
}
|
||||
}
|
||||
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,4 +95,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"UseInvalidUniverseInSteam2IDs" "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "106"
|
||||
"linux" "107"
|
||||
"mac" "107"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "104"
|
||||
@ -34,6 +40,12 @@
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "291"
|
||||
"linux" "292"
|
||||
"mac" "292"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "351"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "105"
|
||||
"linux" "106"
|
||||
"mac" "106"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "103"
|
||||
@ -34,6 +40,12 @@
|
||||
"linux" "68"
|
||||
"mac" "68"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "292"
|
||||
"linux" "293"
|
||||
"mac" "293"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "364"
|
||||
|
@ -35,6 +35,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "331"
|
||||
@ -107,6 +113,12 @@
|
||||
"linux" "158"
|
||||
"mac" "158"
|
||||
}
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "265"
|
||||
@ -174,6 +186,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "331"
|
||||
@ -246,6 +264,12 @@
|
||||
"linux" "158"
|
||||
"mac" "158"
|
||||
}
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "265"
|
||||
@ -313,6 +337,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "331"
|
||||
@ -385,6 +415,12 @@
|
||||
"linux" "158"
|
||||
"mac" "158"
|
||||
}
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"Weapon_CanSwitchTo"
|
||||
{
|
||||
"windows" "265"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "106"
|
||||
"linux" "107"
|
||||
"mac" "107"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "104"
|
||||
@ -34,6 +40,12 @@
|
||||
"linux" "66"
|
||||
"mac" "66"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "288"
|
||||
"linux" "289"
|
||||
"mac" "289"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "357"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "99"
|
||||
"linux" "100"
|
||||
"mac" "100"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "97"
|
||||
@ -22,6 +28,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "333"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "100"
|
||||
@ -34,6 +40,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "271"
|
||||
"linux" "272"
|
||||
"mac" "272"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "331"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "102"
|
||||
"linux" "103"
|
||||
"mac" "103"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "100"
|
||||
@ -22,6 +28,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "273"
|
||||
"linux" "274"
|
||||
"mac" "274"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "333"
|
||||
|
@ -16,6 +16,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "110"
|
||||
"linux" "111"
|
||||
"mac" "111"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "108"
|
||||
@ -40,6 +46,12 @@
|
||||
"linux" "72"
|
||||
"mac" "72"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "291"
|
||||
"linux" "292"
|
||||
"mac" "292"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "355"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "103"
|
||||
"linux" "104"
|
||||
"mac" "104"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "101"
|
||||
@ -28,6 +34,12 @@
|
||||
"linux" "63"
|
||||
"mac" "63"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "273"
|
||||
"linux" "274"
|
||||
"mac" "274"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "345"
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Blocked"
|
||||
{
|
||||
"windows" "121"
|
||||
"linux" "122"
|
||||
"mac" "122"
|
||||
}
|
||||
"EndTouch"
|
||||
{
|
||||
"windows" "119"
|
||||
@ -34,6 +40,12 @@
|
||||
"linux" "73"
|
||||
"mac" "73"
|
||||
}
|
||||
"OnTakeDamage_Alive"
|
||||
{
|
||||
"windows" "303"
|
||||
"linux" "304"
|
||||
"mac" "304"
|
||||
}
|
||||
"PreThink"
|
||||
{
|
||||
"windows" "368"
|
||||
|
@ -70,7 +70,7 @@ public OnRebuildAdminCache(AdminCachePart:part)
|
||||
}
|
||||
}
|
||||
|
||||
ParseError(const String:format[], {Handle,String,Float,_}:...)
|
||||
ParseError(const String:format[], any:...)
|
||||
{
|
||||
decl String:buffer[512];
|
||||
|
||||
|
@ -45,6 +45,25 @@ enum NetFlow
|
||||
NetFlow_Both, /**< Both values added together */
|
||||
};
|
||||
|
||||
/**
|
||||
* Auth string types.
|
||||
*
|
||||
* Note that for the Steam2 and Steam3 types, the following ids are
|
||||
* also valid values:
|
||||
* "STEAM_ID_PENDING" - Authentication is pending.
|
||||
* "STEAM_ID_LAN" - Authentication is disabled because of being on a LAN server.
|
||||
* "BOT" - The client is a bot.
|
||||
*/
|
||||
enum AuthIdType
|
||||
{
|
||||
AuthId_Engine = 0, /**< The game-specific auth string as returned from the engine */
|
||||
|
||||
// The following are only available on games that support Steam authentication.
|
||||
AuthId_Steam2, /**< Steam2 rendered format, ex "STEAM_1:1:4153990" */
|
||||
AuthId_Steam3, /**< Steam3 rendered format, ex "[U:1:8307981]" */
|
||||
AuthId_SteamID64, /**< A SteamID64 (uint64) as a String, ex "76561197968573709" */
|
||||
};
|
||||
|
||||
/**
|
||||
* MAXPLAYERS is not the same as MaxClients.
|
||||
* MAXPLAYERS is a hardcoded value as an upper limit. MaxClients changes based on the server.
|
||||
@ -267,8 +286,24 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true);
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
#pragma deprecated Use GetClientAuthId
|
||||
native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true);
|
||||
|
||||
/**
|
||||
* Retrieves a client's authentication string (SteamID).
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param authType Auth id type and format to use.
|
||||
* @param auth Buffer to store the client's auth id.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @param validate Check backend validation status.
|
||||
* DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES,
|
||||
* You WILL KNOW if you need to use this, MOST WILL NOT.
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native bool:GetClientAuthId(client, AuthIdType:authType, String:auth[], maxlen, bool:validate=true);
|
||||
|
||||
/**
|
||||
* Returns the client's Steam account ID.
|
||||
*
|
||||
|
@ -669,7 +669,7 @@ native SetConVarBounds(Handle:convar, ConVarBounds:type, bool:set, Float:value=0
|
||||
*/
|
||||
native GetConVarName(Handle:convar, String:name[], maxlength);
|
||||
|
||||
funcenum ConVarQueryFinished
|
||||
union ConVarQueryFinished
|
||||
{
|
||||
/**
|
||||
* Called when a query to retrieve a client's console variable has finished.
|
||||
@ -683,7 +683,7 @@ funcenum ConVarQueryFinished
|
||||
* @param value Value that was passed when query was started.
|
||||
* @noreturn
|
||||
*/
|
||||
public(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[], any:value),
|
||||
function void (QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue, any value);
|
||||
|
||||
/**
|
||||
* Called when a query to retrieve a client's console variable has finished.
|
||||
@ -696,7 +696,7 @@ funcenum ConVarQueryFinished
|
||||
* @param convarValue Value of client convar that was queried if successful. This will be "" if it was not.
|
||||
* @noreturn
|
||||
*/
|
||||
public(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
|
||||
function void (QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,7 @@ enum EventHookMode
|
||||
/**
|
||||
* Hook function types for events.
|
||||
*/
|
||||
funcenum EventHook
|
||||
union EventHook
|
||||
{
|
||||
/**
|
||||
* Called when a game event is fired.
|
||||
@ -59,7 +59,7 @@ funcenum EventHook
|
||||
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||
* @return Ignored for post hooks. Plugin_Handled will block event if hooked as pre.
|
||||
*/
|
||||
Action:public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||
function Action (Handle event, const char[] name, bool dontBroadcast);
|
||||
/**
|
||||
* Called when a game event is fired.
|
||||
*
|
||||
@ -69,7 +69,7 @@ funcenum EventHook
|
||||
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||
* @noreturn
|
||||
*/
|
||||
public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||
function void (Handle event, const char[] name, bool dontBroadcast);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -108,9 +108,14 @@ native BuildPath(PathType:type, String:buffer[], maxlength, const String:fmt[],
|
||||
* @note OpenDirectory() supports the "file://" notation.
|
||||
*
|
||||
* @param path Path to open.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to find files existing in any of
|
||||
* the Valve search paths, rather than solely files
|
||||
* existing directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return A Handle to the directory, INVALID_HANDLE on open error.
|
||||
*/
|
||||
native Handle:OpenDirectory(const String:path[]);
|
||||
native Handle:OpenDirectory(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME");
|
||||
|
||||
/**
|
||||
* Reads the current directory entry as a local filename, then moves to the next file.
|
||||
@ -136,17 +141,27 @@ native bool:ReadDirEntry(Handle:dir, String:buffer[], maxlength, &FileType:type=
|
||||
*
|
||||
* @param file File to open.
|
||||
* @param mode Open mode.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to find files existing in valve
|
||||
* search paths, rather than solely files existing directly
|
||||
* in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return A Handle to the file, INVALID_HANDLE on open error.
|
||||
*/
|
||||
native Handle:OpenFile(const String:file[], const String:mode[]);
|
||||
native Handle:OpenFile(const String:file[], const String:mode[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME");
|
||||
|
||||
/**
|
||||
* Deletes a file.
|
||||
*
|
||||
* @param path Path of the file to delete.
|
||||
* @return True on success, false otherwise.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to delete files existing in the Valve
|
||||
* search path, rather than solely files existing directly
|
||||
* in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return True on success, false on failure or if file not immediately removed.
|
||||
*/
|
||||
native bool:DeleteFile(const String:path[]);
|
||||
native bool:DeleteFile(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="DEFAULT_WRITE_PATH");
|
||||
|
||||
/**
|
||||
* Reads a line from a text file.
|
||||
@ -304,28 +319,38 @@ native FilePosition(Handle:file);
|
||||
* @param path Path to the file.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to find files existing in any of
|
||||
* the GAME search paths, rather than solely files
|
||||
* the Valve search paths, rather than solely files
|
||||
* existing directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return True if the file exists, false otherwise.
|
||||
*/
|
||||
native bool:FileExists(const String:path[], bool:use_valve_fs=false);
|
||||
native bool:FileExists(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME");
|
||||
|
||||
/**
|
||||
* Renames a file.
|
||||
*
|
||||
* @param newpath New path to the file.
|
||||
* @param oldpath Path to the existing file.
|
||||
* @return True on success, false otherwise.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to rename files in the game's
|
||||
* Valve search paths, rather than directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return True on success or use_valve_fs specified, false otherwise.
|
||||
*/
|
||||
native bool:RenameFile(const String:newpath[], const String:oldpath[]);
|
||||
native bool:RenameFile(const String:newpath[], const String:oldpath[], bool:use_valve_fs=false, const String:valve_path_id[]="DEFAULT_WRITE_PATH");
|
||||
|
||||
/**
|
||||
* Checks if a directory exists.
|
||||
*
|
||||
* @param path Path to the directory.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to find files existing in any of
|
||||
* the Valve search paths, rather than solely files
|
||||
* existing directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return True if the directory exists, false otherwise.
|
||||
*/
|
||||
native bool:DirExists(const String:path[]);
|
||||
native bool:DirExists(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME");
|
||||
|
||||
/**
|
||||
* Get the file size in bytes.
|
||||
@ -333,18 +358,20 @@ native bool:DirExists(const String:path[]);
|
||||
* @param path Path to the file.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to find files existing in any of
|
||||
* the GAME search paths, rather than solely files
|
||||
* the Valve search paths, rather than solely files
|
||||
* existing directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for all search paths.
|
||||
* @return File size in bytes, -1 if file not found.
|
||||
*/
|
||||
native FileSize(const String:path[], bool:use_valve_fs=false);
|
||||
native FileSize(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME");
|
||||
|
||||
/**
|
||||
* Flushes a file's buffered output; any buffered output
|
||||
* is immediately written to the file.
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @return True on success, false on failure.
|
||||
* @return True on success or use_valve_fs specified with OpenFile,
|
||||
* otherwise false on failure.
|
||||
*/
|
||||
native FlushFile(Handle:file);
|
||||
|
||||
@ -373,8 +400,13 @@ native bool:RemoveDir(const String:path[]);
|
||||
* @param path Path to create.
|
||||
* @param mode Permissions (default is o=rx,g=rx,u=rwx). Note that folders must have
|
||||
* the execute bit set on Linux. On Windows, the mode is ignored.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to create folders in the game's
|
||||
* Valve search paths, rather than directly in the gamedir.
|
||||
* @param valve_path_id If use_valve_fs, a search path from gameinfo or NULL_STRING for default.
|
||||
* In this case, mode is ignored.
|
||||
*/
|
||||
native bool:CreateDirectory(const String:path[], mode);
|
||||
native bool:CreateDirectory(const String:path[], mode, bool:use_valve_fs=false, const String:valve_path_id[]="DEFAULT_WRITE_PATH");
|
||||
|
||||
/**
|
||||
* Changes a file or directories permissions.
|
||||
|
@ -117,10 +117,17 @@ enum SDKHookType
|
||||
SDKHook_Reload,
|
||||
SDKHook_ReloadPost,
|
||||
SDKHook_GetMaxHealth, /**< ep2v and later */
|
||||
SDKHook_Blocked,
|
||||
SDKHook_BlockedPost,
|
||||
SDKHook_OnTakeDamageAlive,
|
||||
SDKHook_OnTakeDamageAlivePost,
|
||||
};
|
||||
|
||||
/*
|
||||
Alphabetized for easy readability
|
||||
|
||||
SDKHook_Blocked,
|
||||
SDKHook_BlockedPost,
|
||||
|
||||
SDKHook_EndTouch,
|
||||
SDKHook_EndTouchPost,
|
||||
@ -134,6 +141,9 @@ enum SDKHookType
|
||||
SDKHook_OnTakeDamage,
|
||||
SDKHook_OnTakeDamagePost,
|
||||
|
||||
SDKHook_OnTakeDamageAlive,
|
||||
SDKHook_OnTakeDamageAlivePost,
|
||||
|
||||
SDKHook_PreThink,
|
||||
SDKHook_PreThinkPost,
|
||||
|
||||
@ -192,90 +202,93 @@ enum UseType
|
||||
Use_Toggle
|
||||
};
|
||||
|
||||
funcenum SDKHookCB
|
||||
union SDKHookCB
|
||||
{
|
||||
// PreThink/Post
|
||||
// PostThink/Post
|
||||
public(client),
|
||||
function void (int client);
|
||||
|
||||
// Spawn
|
||||
Action:public(entity),
|
||||
function Action (int entity);
|
||||
|
||||
// GroundEntChanged
|
||||
// SpawnPost
|
||||
// Think/Post
|
||||
// VPhysicsUpdate/Post
|
||||
public(entity),
|
||||
function void (int entity);
|
||||
|
||||
// EndTouch
|
||||
// StartTouch
|
||||
// Touch
|
||||
Action:public(entity, other),
|
||||
// Blocked
|
||||
function Action (int entity, int other);
|
||||
|
||||
// EndTouchPost
|
||||
// StartTouchPost
|
||||
// TouchPost
|
||||
public(entity, other),
|
||||
function void (int entity, int other);
|
||||
|
||||
// SetTransmit
|
||||
Action:public(entity, client),
|
||||
function Action (int entity, int client);
|
||||
|
||||
// WeaponCanSwitchTo
|
||||
// WeaponCanUse
|
||||
// WeaponDrop
|
||||
// WeaponEquip
|
||||
// WeaponSwitch
|
||||
Action:public(client, weapon),
|
||||
function Action (int client, int weapon);
|
||||
|
||||
// WeaponCanSwitchToPost
|
||||
// WeaponCanUsePost
|
||||
// WeaponDropPost
|
||||
// WeaponEquipPost
|
||||
// WeaponSwitchPost
|
||||
public(client, weapon),
|
||||
function void (int client, int weapon);
|
||||
|
||||
// GetMaxHealth (ep2v and later)
|
||||
Action:public(entity, &maxhealth),
|
||||
function Action (int entity, int &maxhealth);
|
||||
|
||||
// OnTakeDamage
|
||||
// OnTakeDamagAlive
|
||||
// Note: The weapon parameter is not used by all games and damage sources.
|
||||
// Note: Force application is dependent on game and damage type(s)
|
||||
// SDKHooks 1.0+
|
||||
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype),
|
||||
function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype);
|
||||
// SDKHooks 2.0+
|
||||
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3]),
|
||||
function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3]);
|
||||
// SDKHooks 2.1+ (can check for support at runtime using GetFeatureStatus on SDKHook_DmgCustomInOTD capability.
|
||||
// DON'T attempt to access 'damagecustom' var if feature status != available
|
||||
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon,
|
||||
Float:damageForce[3], Float:damagePosition[3], damagecustom),
|
||||
function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon,
|
||||
float damageForce[3], float damagePosition[3], int damagecustom);
|
||||
|
||||
// OnTakeDamagePost
|
||||
public(victim, attacker, inflictor, Float:damage, damagetype),
|
||||
public(victim, attacker, inflictor, Float:damage, damagetype, weapon, const Float:damageForce[3], const Float:damagePosition[3]),
|
||||
// OnTakeDamageAlivePost
|
||||
function void (int victim, int attacker, int inflictor, float damage, int damagetype);
|
||||
function void (int victim, int attacker, int inflictor, float damage, int damagetype, const float damageForce[3], const float damagePosition[3]);
|
||||
|
||||
// FireBulletsPost
|
||||
public(client, shots, const String:weaponname[]),
|
||||
function void (int client, int shots, const char[] weaponname);
|
||||
|
||||
// TraceAttack
|
||||
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup),
|
||||
function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &ammotype, int hitbox, int hitgroup);
|
||||
|
||||
// TraceAttackPost
|
||||
public(victim, attacker, inflictor, Float:damage, damagetype, ammotype, hitbox, hitgroup),
|
||||
function void (int victim, int attacker, int inflictor, float damage, int damagetype, int ammotype, int hitbox, int hitgroup);
|
||||
|
||||
// ShouldCollide
|
||||
bool:public(entity, collisiongroup, contentsmask, bool:originalResult),
|
||||
function bool (int entity, int collisiongroup, int contentsmask, bool originalResult);
|
||||
|
||||
// Use
|
||||
Action:public(entity, activator, caller, UseType:type, Float:value),
|
||||
function Action (int entity, int activator, int caller, UseType type, float value);
|
||||
|
||||
// UsePost
|
||||
public(entity, activator, caller, UseType:type, Float:value),
|
||||
function void (int entity, int activator, int caller, UseType type, float value);
|
||||
|
||||
// Reload
|
||||
Action:public(weapon),
|
||||
function Action (int weapon);
|
||||
|
||||
// Reload post
|
||||
public(weapon, bool:bSuccessful)
|
||||
function void (int weapon, bool bSuccessful);
|
||||
};
|
||||
|
||||
|
||||
|
@ -110,7 +110,7 @@ enum RayType
|
||||
RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */
|
||||
};
|
||||
|
||||
funcenum TraceEntityFilter
|
||||
union TraceEntityFilter
|
||||
{
|
||||
/**
|
||||
* Called on entity filtering.
|
||||
@ -119,7 +119,7 @@ funcenum TraceEntityFilter
|
||||
* @param contentsMask Contents Mask.
|
||||
* @return True to allow the current entity to be hit, otherwise false.
|
||||
*/
|
||||
bool:public(entity, contentsMask),
|
||||
function bool (int entity, int contentsMask);
|
||||
|
||||
/**
|
||||
* Called on entity filtering.
|
||||
@ -129,7 +129,7 @@ funcenum TraceEntityFilter
|
||||
* @param data Data value, if used.
|
||||
* @return True to allow the current entity to be hit, otherwise false.
|
||||
*/
|
||||
bool:public(entity, contentsMask, any:data),
|
||||
function bool (int entity, int contentsMask, any data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -371,4 +371,4 @@ native TR_GetPlaneNormal(Handle:hndl, Float:normal[3]);
|
||||
* @param pos Vector buffer to store data in.
|
||||
* @return True if outside world, otherwise false.
|
||||
*/
|
||||
native TR_PointOutsideWorld(Float:pos[3]);
|
||||
native TR_PointOutsideWorld(Float:pos[3]);
|
||||
|
@ -123,10 +123,10 @@ native SortCustom1D(array[], array_size, SortFunc1D:sortfunc, Handle:hndl=INVALI
|
||||
* 0 if first is equal to second
|
||||
* 1 if first should go after second
|
||||
*/
|
||||
funcenum SortFunc2D
|
||||
union SortFunc2D
|
||||
{
|
||||
public(elem1[], elem2[], const array[][], Handle:hndl),
|
||||
public(String:elem1[], String:elem2[], const String:array[][], Handle:hndl),
|
||||
function int (int[] elem1, int[] elem2, const int[][] array, Handle hndl);
|
||||
function int (char[] elem1, char[] elem2, const char[][] array, Handle hndl);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -153,6 +153,10 @@ enum TFCond
|
||||
TFCond_HalloweenTiny,
|
||||
TFCond_HalloweenInHell,
|
||||
TFCond_HalloweenGhostMode,
|
||||
|
||||
TFCond_DodgeChance = 79,
|
||||
TFCond_Parachute,
|
||||
TFCond_BlastJumping,
|
||||
};
|
||||
|
||||
const Float:TFCondDuration_Infinite = -1.0;
|
||||
|
@ -249,6 +249,7 @@ enum {
|
||||
TF_WEAPON_SPELLBOOK,
|
||||
TF_WEAPON_SPELLBOOK_PROJECTILE,
|
||||
TF_WEAPON_SNIPERRIFLE_CLASSIC,
|
||||
TF_WEAPON_PARACHUTE,
|
||||
};
|
||||
|
||||
// TF2 Weapon Loadout Slots
|
||||
|
@ -45,7 +45,7 @@
|
||||
/**
|
||||
* Any of the following prototypes will work for a timed function.
|
||||
*/
|
||||
funcenum Timer
|
||||
union Timer
|
||||
{
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
@ -55,7 +55,7 @@ funcenum Timer
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer, Handle:hndl),
|
||||
function Action(Handle timer, Handle hndl);
|
||||
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
@ -65,7 +65,7 @@ funcenum Timer
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer, any:data),
|
||||
function Action(Handle timer, any data);
|
||||
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
@ -74,7 +74,7 @@ funcenum Timer
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer),
|
||||
function Action(Handle timer);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include <IAdminSystem.h>
|
||||
|
||||
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
|
||||
#define SMINTERFACE_PLAYERMANAGER_VERSION 20
|
||||
#define SMINTERFACE_PLAYERMANAGER_VERSION 21
|
||||
|
||||
struct edict_t;
|
||||
class IPlayerInfo;
|
||||
@ -267,6 +267,15 @@ namespace SourceMod
|
||||
* @brief Removes admin access from the client.
|
||||
*/
|
||||
virtual void ClearAdmin() =0;
|
||||
|
||||
/**
|
||||
* @brief Returns the client's Steam ID as a uint64.
|
||||
*
|
||||
* @param validated Check backend validation status.
|
||||
*
|
||||
* @return Steam Id or 0 if not available.
|
||||
*/
|
||||
virtual uint64_t GetSteamId64(bool validated = true) =0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
99
public/amtl/am-fixedarray.h
Normal file
99
public/amtl/am-fixedarray.h
Normal file
@ -0,0 +1,99 @@
|
||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
||||
//
|
||||
// Copyright (C) 2013-2014, David Anderson and AlliedModders LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef _include_amtl_fixedarray_h_
|
||||
#define _include_amtl_fixedarray_h_
|
||||
|
||||
#include <am-utility.h>
|
||||
#include <am-allocator-policies.h>
|
||||
#include <am-moveable.h>
|
||||
|
||||
namespace ke {
|
||||
|
||||
template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
|
||||
class FixedArray : public AllocPolicy
|
||||
{
|
||||
public:
|
||||
FixedArray(size_t length, AllocPolicy = AllocPolicy()) {
|
||||
length_ = length;
|
||||
data_ = (T *)this->malloc(sizeof(T) * length_);
|
||||
if (!data_)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < length_; i++)
|
||||
new (&data_[i]) T();
|
||||
}
|
||||
~FixedArray() {
|
||||
for (size_t i = 0; i < length_; i++)
|
||||
data_[i].~T();
|
||||
this->free(data_);
|
||||
}
|
||||
|
||||
// This call may be skipped if the allocator policy is infallible.
|
||||
bool initialize() {
|
||||
return length_ == 0 || !!data_;
|
||||
}
|
||||
|
||||
size_t length() const {
|
||||
return length_;
|
||||
}
|
||||
T &operator [](size_t index) {
|
||||
return at(index);
|
||||
}
|
||||
const T &operator [](size_t index) const {
|
||||
return at(index);
|
||||
}
|
||||
T &at(size_t index) {
|
||||
assert(index < length());
|
||||
return data_[index];
|
||||
}
|
||||
const T &at(size_t index) const {
|
||||
assert(index < length());
|
||||
return data_[index];
|
||||
}
|
||||
void set(size_t index, const T &t) {
|
||||
assert(index < length());
|
||||
data_[index] = t;
|
||||
}
|
||||
void set(size_t index, ke::Moveable<T> t) {
|
||||
assert(index < length());
|
||||
data_[index] = t;
|
||||
}
|
||||
|
||||
private:
|
||||
FixedArray(const FixedArray &other) KE_DELETE;
|
||||
FixedArray &operator =(const FixedArray &other) KE_DELETE;
|
||||
|
||||
private:
|
||||
size_t length_;
|
||||
T *data_;
|
||||
};
|
||||
|
||||
} // namespace ke
|
||||
|
||||
#endif // _include_amtl_fixedarray_h_
|
50
public/amtl/am-float.h
Normal file
50
public/amtl/am-float.h
Normal file
@ -0,0 +1,50 @@
|
||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
||||
//
|
||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef _include_amtl_float_h_
|
||||
#define _include_amtl_float_h_
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
namespace ke {
|
||||
|
||||
static inline bool
|
||||
IsNaN(double v)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return !!_isnan(v);
|
||||
#else
|
||||
return isnan(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ke
|
||||
|
||||
#endif // _include_amtl_float_h_
|
@ -138,19 +138,24 @@ class HashMap : public AllocPolicy
|
||||
// The map must not have been mutated in between findForAdd() and add().
|
||||
// The Insert object is still valid after add() returns, however.
|
||||
bool add(Insert &i, const K &key, const V &value) {
|
||||
return table_.add(i, Entry(key, value));
|
||||
Entry entry(key, value);
|
||||
return table_.add(i, ke::Move(entry));
|
||||
}
|
||||
bool add(Insert &i, Moveable<K> key, const V &value) {
|
||||
return table_.add(i, Entry(key, value));
|
||||
Entry entry(key, value);
|
||||
return table_.add(i, ke::Move(entry));
|
||||
}
|
||||
bool add(Insert &i, const K &key, Moveable<V> value) {
|
||||
return table_.add(i, Entry(key, value));
|
||||
Entry entry(key, value);
|
||||
return table_.add(i, ke::Move(entry));
|
||||
}
|
||||
bool add(Insert &i, Moveable<K> key, Moveable<V> value) {
|
||||
return table_.add(i, Entry(key, value));
|
||||
Entry entry(key, value);
|
||||
return table_.add(i, ke::Move(entry));
|
||||
}
|
||||
bool add(Insert &i, Moveable<K> key) {
|
||||
return table_.add(i, Entry(key, V()));
|
||||
Entry entry(key, V());
|
||||
return table_.add(i, ke::Move(entry));
|
||||
}
|
||||
|
||||
// This can be used to avoid compiler constructed temporaries, since AMTL
|
||||
|
@ -35,12 +35,15 @@
|
||||
|
||||
namespace ke {
|
||||
|
||||
// See the comment above Refcounted<T> for more information. This class is
|
||||
// identical, except changing the reference count is guaranteed to be atomic
|
||||
// with respect to other threads changing the reference count.
|
||||
template <typename T>
|
||||
class RefcountedThreadsafe
|
||||
{
|
||||
public:
|
||||
RefcountedThreadsafe()
|
||||
: refcount_(1)
|
||||
: refcount_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -37,18 +37,35 @@ namespace ke {
|
||||
|
||||
template <typename T> class Ref;
|
||||
|
||||
// Holds a refcounted T without addrefing it. This is similar to PassRef<>
|
||||
// below, but is intended only for freshly allocated objects which start
|
||||
// with reference count 1, and we don't want to add an extra ref just by
|
||||
// assigning to PassRef<> or Ref<>.
|
||||
// Objects in AMTL inheriting from Refcounted will have an initial refcount
|
||||
// of 0. However, in some systems (such as COM), the initial refcount is 1,
|
||||
// or functions may return raw pointers that have been AddRef'd. In these
|
||||
// cases it would be a mistake to use Ref<> or PassRef<>, since the object
|
||||
// would leak an extra reference.
|
||||
//
|
||||
// This container holds a refcounted object without addrefing it. This is
|
||||
// intended only for interacting with functions which return an object that
|
||||
// has been manually AddRef'd. Note that this will perform a Release(), so
|
||||
// so it is necessary to assign it to retain the object.
|
||||
template <typename T>
|
||||
class Newborn
|
||||
class AlreadyRefed
|
||||
{
|
||||
public:
|
||||
Newborn(T *t)
|
||||
AlreadyRefed(T *t)
|
||||
: thing_(t)
|
||||
{
|
||||
}
|
||||
AlreadyRefed(const AlreadyRefed<T> &other)
|
||||
: thing_(other.thing_)
|
||||
{
|
||||
// If copy elision for some reason doesn't happen (for example, when
|
||||
// returning from AdoptRef), just null out the source ref.
|
||||
other.thing_ = NULL;
|
||||
}
|
||||
~AlreadyRefed() {
|
||||
if (thing_)
|
||||
thing_->Release();
|
||||
}
|
||||
|
||||
T *release() const {
|
||||
return ReturnAndVoid(thing_);
|
||||
@ -59,10 +76,10 @@ class Newborn
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static inline Newborn<T>
|
||||
NoAddRef(T *t)
|
||||
static inline AlreadyRefed<T>
|
||||
AdoptRef(T *t)
|
||||
{
|
||||
return Newborn<T>(t);
|
||||
return AlreadyRefed<T>(t);
|
||||
}
|
||||
|
||||
// When returning a value, we'd rather not be needlessly changing the refcount,
|
||||
@ -81,7 +98,14 @@ class PassRef
|
||||
{
|
||||
}
|
||||
|
||||
PassRef(const Newborn<T *> &other)
|
||||
PassRef(const AlreadyRefed<T *> &other)
|
||||
: thing_(other.release())
|
||||
{
|
||||
// Don't addref, newborn means already addref'd.
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
PassRef(const AlreadyRefed<S *> &other)
|
||||
: thing_(other.release())
|
||||
{
|
||||
// Don't addref, newborn means already addref'd.
|
||||
@ -134,7 +158,7 @@ class PassRef
|
||||
private:
|
||||
// Disallowed operators.
|
||||
PassRef &operator =(T *other);
|
||||
PassRef &operator =(Newborn<T> &other);
|
||||
PassRef &operator =(AlreadyRefed<T> &other);
|
||||
|
||||
void AddRef() {
|
||||
if (thing_)
|
||||
@ -149,13 +173,18 @@ class PassRef
|
||||
mutable T *thing_;
|
||||
};
|
||||
|
||||
// Classes which are refcounted should inherit from this.
|
||||
// Classes which are refcounted should inherit from this. Note that reference
|
||||
// counts start at 0 in AMTL, rather than 1. This avoids the complexity of
|
||||
// having to adopt the initial ref upon allocation. However, this also means
|
||||
// invoking Release() on a newly allocated object is illegal. Newborn objects
|
||||
// must either be assigned to a Ref or PassRef (NOT an AdoptRef/AlreadyRefed),
|
||||
// or must be deleted using |delete|.
|
||||
template <typename T>
|
||||
class Refcounted
|
||||
{
|
||||
public:
|
||||
Refcounted()
|
||||
: refcount_(1)
|
||||
: refcount_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -217,7 +246,12 @@ class Ref
|
||||
: thing_(other.release())
|
||||
{
|
||||
}
|
||||
Ref(const Newborn<T> &other)
|
||||
Ref(const AlreadyRefed<T> &other)
|
||||
: thing_(other.release())
|
||||
{
|
||||
}
|
||||
template <typename S>
|
||||
Ref(const AlreadyRefed<S> &other)
|
||||
: thing_(other.release())
|
||||
{
|
||||
}
|
||||
@ -255,7 +289,7 @@ class Ref
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
Ref &operator =(const Newborn<S> &other) {
|
||||
Ref &operator =(const AlreadyRefed<S> &other) {
|
||||
Release();
|
||||
thing_ = other.release();
|
||||
return *this;
|
||||
|
@ -56,7 +56,7 @@ class AString
|
||||
if (other.length_)
|
||||
set(other.chars_, other.length_);
|
||||
else
|
||||
length_ = 0;
|
||||
length_ = 0;
|
||||
}
|
||||
AString(Moveable<AString> other)
|
||||
: chars_(other->chars_.take()),
|
||||
@ -117,6 +117,8 @@ class AString
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kInvalidLength = (size_t)-1;
|
||||
|
||||
void set(const char *str, size_t length) {
|
||||
chars_ = new char[length + 1];
|
||||
length_ = length;
|
||||
|
175
public/amtl/am-threadlocal.h
Normal file
175
public/amtl/am-threadlocal.h
Normal file
@ -0,0 +1,175 @@
|
||||
// vim: set sts=2 ts=8 sw=2 tw=99 et:
|
||||
//
|
||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef _include_amtl_thread_local_h_
|
||||
#define _include_amtl_thread_local_h_
|
||||
|
||||
#include <am-thread-utils.h>
|
||||
|
||||
namespace ke {
|
||||
|
||||
// Stores a per-thread value. In single-threaded mode (KE_SINGLE_THREADED),
|
||||
// this is a no-op container wrapper.
|
||||
//
|
||||
// T must be castable to uintptr_t.
|
||||
//
|
||||
// When assigning to a ThreadLocal<T>, the assigment will automatically attempt
|
||||
// to allocate thread-local storage from the operating system. If it fails, it
|
||||
// will abort the program. If this is undesirable, you may call allocate()
|
||||
// up-front and handle the error case manually.
|
||||
//
|
||||
// The number of thread local slots available to processes is limited (on
|
||||
// Linux, it is generally 1024). It is best to use ThreadLocal sparingly to
|
||||
// play nicely with other libraries.
|
||||
//
|
||||
// ThreadLocal will free the underlying thread-local storage slot in its
|
||||
// destructor, but it is not an AutoPtr. It does not delete pointers. Since
|
||||
// one thread's value is only observable from that thread, make sure to free
|
||||
// the contained resource (if necessary) before the thread exits.
|
||||
template <typename T>
|
||||
class ThreadLocal
|
||||
{
|
||||
public:
|
||||
void operator =(const T &other) {
|
||||
set(other);
|
||||
}
|
||||
|
||||
T operator *() const {
|
||||
return get();
|
||||
}
|
||||
T operator ->() const {
|
||||
return get();
|
||||
}
|
||||
bool operator !() const {
|
||||
return !get();
|
||||
}
|
||||
bool operator ==(const T &other) const {
|
||||
return get() == other;
|
||||
}
|
||||
bool operator !=(const T &other) const {
|
||||
return get() != other;
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadLocal(const ThreadLocal &other) KE_DELETE;
|
||||
ThreadLocal &operator =(const ThreadLocal &other) KE_DELETE;
|
||||
|
||||
#if !defined(KE_SINGLE_THREADED)
|
||||
private:
|
||||
int allocated_;
|
||||
|
||||
public:
|
||||
ThreadLocal() {
|
||||
allocated_ = 0;
|
||||
}
|
||||
|
||||
T get() const {
|
||||
if (!allocated_)
|
||||
return T();
|
||||
return internalGet();
|
||||
}
|
||||
void set(const T &t) {
|
||||
if (!allocated_ && !allocate()) {
|
||||
fprintf(stderr, "could not allocate thread-local storage\n");
|
||||
abort();
|
||||
}
|
||||
internalSet(t);
|
||||
}
|
||||
|
||||
# if defined(_MSC_VER)
|
||||
~ThreadLocal() {
|
||||
if (allocated_)
|
||||
TlsFree(key_);
|
||||
}
|
||||
|
||||
private:
|
||||
T internalGet() const {
|
||||
return reinterpret_cast<T>(TlsGetValue(key_));
|
||||
}
|
||||
void internalSet(const T &t) {
|
||||
TlsSetValue(key_, reinterpret_cast<LPVOID>(t));
|
||||
}
|
||||
bool allocate() {
|
||||
if (InterlockedCompareExchange(&allocated_, 1, 0) == 1)
|
||||
return true;
|
||||
key_ = TlsAlloc();
|
||||
return key_ != TLS_OUT_OF_INDEXES;
|
||||
}
|
||||
|
||||
DWORD key_;
|
||||
|
||||
# else
|
||||
public:
|
||||
~ThreadLocal() {
|
||||
if (allocated_)
|
||||
pthread_key_delete(key_);
|
||||
}
|
||||
|
||||
bool allocate() {
|
||||
if (!__sync_bool_compare_and_swap(&allocated_, 0, 1))
|
||||
return true;
|
||||
return pthread_key_create(&key_, NULL) == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
T internalGet() const {
|
||||
return (T)reinterpret_cast<uintptr_t>(pthread_getspecific(key_));
|
||||
}
|
||||
void internalSet(const T &t) {
|
||||
pthread_setspecific(key_, reinterpret_cast<void *>(t));
|
||||
}
|
||||
|
||||
pthread_key_t key_;
|
||||
# endif // !_MSC_VER
|
||||
|
||||
#else // KE_SINGLE_THREADED
|
||||
public:
|
||||
ThreadLocal() {
|
||||
t_ = T();
|
||||
}
|
||||
|
||||
bool allocate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
T get() const {
|
||||
return t_;
|
||||
}
|
||||
void set(const T &t) {
|
||||
t_ = t;
|
||||
}
|
||||
|
||||
private:
|
||||
T t_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ke
|
||||
|
||||
#endif // _include_amtl_thread_local_h_
|
@ -34,8 +34,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#if defined(_MSC_VER)
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
@ -89,7 +87,7 @@ class AutoPtr
|
||||
: t_(NULL)
|
||||
{
|
||||
}
|
||||
AutoPtr(T *t)
|
||||
explicit AutoPtr(T *t)
|
||||
: t_(t)
|
||||
{
|
||||
}
|
||||
@ -220,16 +218,6 @@ FindRightmostBit(size_t number)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsNaN(double v)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return !!_isnan(v);
|
||||
#else
|
||||
return isnan(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsPowerOfTwo(size_t value)
|
||||
{
|
||||
@ -358,10 +346,46 @@ class SaveAndSet
|
||||
T old_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class StackLinked
|
||||
{
|
||||
public:
|
||||
StackLinked<T>(T **prevp)
|
||||
: prevp_(prevp),
|
||||
prev_(*prevp)
|
||||
{
|
||||
*prevp_ = static_cast<T *>(this);
|
||||
}
|
||||
virtual ~StackLinked() {
|
||||
assert(*prevp_ == this);
|
||||
*prevp_ = prev_;
|
||||
}
|
||||
|
||||
private:
|
||||
T **prevp_;
|
||||
T *prev_;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define KE_CXX11
|
||||
#endif
|
||||
|
||||
#if defined(KE_CXX11)
|
||||
# define KE_DELETE = delete
|
||||
# define KE_OVERRIDE override
|
||||
#else
|
||||
# define KE_DELETE
|
||||
# define KE_OVERRIDE
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define KE_SIZET_FMT "%Iu"
|
||||
# define KE_I64_FMT "%I64d"
|
||||
# define KE_U64_FMT "%I64u"
|
||||
#elif defined(__GNUC__)
|
||||
# define KE_SIZET_FMT "%zu"
|
||||
# define KE_I64_FMT "%lld"
|
||||
# define KE_U64_FMT "%llu"
|
||||
#else
|
||||
# error "Implement format specifier string"
|
||||
#endif
|
||||
|
@ -74,7 +74,7 @@ static const char *prefix[3]={ "error", "fatal error", "warning" };
|
||||
if (number!=0) {
|
||||
int idx;
|
||||
|
||||
if (number < 160)
|
||||
if (number < 160 || (number >= 200 && sc_warnings_are_errors))
|
||||
idx = 0;
|
||||
else if (number < 200)
|
||||
idx = 1;
|
||||
|
@ -432,6 +432,7 @@ enum TokenKind {
|
||||
tTAGOF,
|
||||
tTHEN,
|
||||
tTYPEDEF,
|
||||
tUNION,
|
||||
tVOID,
|
||||
tWHILE,
|
||||
/* compiler directives */
|
||||
@ -904,6 +905,7 @@ extern int pc_tag_nullfunc_t; /* the null function type */
|
||||
extern int pc_anytag; /* global any tag */
|
||||
extern int glbstringread; /* last global string read */
|
||||
extern int sc_require_newdecls; /* only newdecls are allowed */
|
||||
extern bool sc_warnings_are_errors;
|
||||
|
||||
extern constvalue sc_automaton_tab; /* automaton table */
|
||||
extern constvalue sc_state_tab; /* state table */
|
||||
|
@ -144,6 +144,7 @@ static void dolabel(void);
|
||||
static void doreturn(void);
|
||||
static void dofuncenum(int listmode);
|
||||
static void dotypedef();
|
||||
static void dounion();
|
||||
static void domethodmap(LayoutSpec spec);
|
||||
static void dobreak(void);
|
||||
static void docont(void);
|
||||
@ -914,6 +915,9 @@ static void parseoptions(int argc,char **argv,char *oname,char *ename,char *pnam
|
||||
case 'e':
|
||||
strlcpy(ename,option_value(ptr),_MAX_PATH); /* set name of error file */
|
||||
break;
|
||||
case 'E':
|
||||
sc_warnings_are_errors = true;
|
||||
break;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined _Windows
|
||||
case 'H':
|
||||
hwndFinish=(HWND)atoi(option_value(ptr));
|
||||
@ -1282,6 +1286,7 @@ static void about(void)
|
||||
pc_printf(" -t<num> TAB indent size (in character positions, default=%d)\n",sc_tabsize);
|
||||
pc_printf(" -v<num> verbosity level; 0=quiet, 1=normal, 2=verbose (default=%d)\n",verbosity);
|
||||
pc_printf(" -w<num> disable a specific warning by its number\n");
|
||||
pc_printf(" -E treat warnings as errors\n");
|
||||
pc_printf(" -X<num> abstract machine size limit in bytes\n");
|
||||
pc_printf(" -XD<num> abstract machine data/stack size limit in bytes\n");
|
||||
pc_printf(" -\\ use '\\' for escape characters\n");
|
||||
@ -1506,6 +1511,9 @@ static void parse(void)
|
||||
case tTYPEDEF:
|
||||
dotypedef();
|
||||
break;
|
||||
case tUNION:
|
||||
dounion();
|
||||
break;
|
||||
case tSTRUCT:
|
||||
declstruct();
|
||||
break;
|
||||
@ -2689,8 +2697,11 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
|
||||
} while (matchtoken(',')); /* do */
|
||||
needtoken('}');
|
||||
} else {
|
||||
init(ident,&ctag,errorfound);
|
||||
matchtag(tag,ctag,TRUE);
|
||||
if (!lexpeek('}'))
|
||||
{
|
||||
init(ident,&ctag,errorfound);
|
||||
matchtag(tag,ctag,TRUE);
|
||||
}
|
||||
} /* if */
|
||||
/* fill up the literal queue with a series */
|
||||
if (ellips) {
|
||||
@ -3192,6 +3203,8 @@ static int parse_old_decl(declinfo_t *decl, int flags)
|
||||
}
|
||||
needtoken(':');
|
||||
}
|
||||
if (type->numtags > 1)
|
||||
error(158);
|
||||
}
|
||||
|
||||
if (type->numtags == 0) {
|
||||
@ -4214,6 +4227,27 @@ static void dotypedef()
|
||||
functags_add(def, &type);
|
||||
}
|
||||
|
||||
// Unsafe union - only supports function types. This is a transition hack for SP2.
|
||||
static void dounion()
|
||||
{
|
||||
token_ident_t ident;
|
||||
if (!needsymbol(&ident))
|
||||
return;
|
||||
|
||||
int prev_tag = pc_findtag(ident.name);
|
||||
if (prev_tag != -1 && !(prev_tag & FUNCTAG))
|
||||
error(94);
|
||||
|
||||
funcenum_t *def = funcenums_add(ident.name);
|
||||
needtoken('{');
|
||||
while (!matchtoken('}')) {
|
||||
functag_t type;
|
||||
parse_function_type(&type);
|
||||
functags_add(def, &type);
|
||||
}
|
||||
|
||||
require_newline(TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dofuncenum - declare function enumerations
|
||||
|
@ -1963,6 +1963,7 @@ const char *sc_tokens[] = {
|
||||
"return",
|
||||
"sizeof", "sleep", "static", "stock", "struct", "switch",
|
||||
"tagof", "*then", "typedef",
|
||||
"union",
|
||||
"void",
|
||||
"while",
|
||||
"#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput",
|
||||
|
@ -201,6 +201,7 @@ static const char *errmsg[] = {
|
||||
/*155*/ "expected newline, but found '%s'\n",
|
||||
/*156*/ "the 'any' type is not allowed in new-style natives\n",
|
||||
/*157*/ "'%s' is a reserved keyword\n",
|
||||
/*158*/ "multi-tags are no longer supported\n",
|
||||
#else
|
||||
"\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012",
|
||||
"\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012",
|
||||
|
@ -1,3 +1,4 @@
|
||||
// vim: set ts=8 sts=2 sw=2 tw=99 et:
|
||||
/* Pawn compiler - Error message system
|
||||
* In fact a very simple system, using only 'panic mode'.
|
||||
*
|
||||
@ -81,6 +82,8 @@ static short lastfile;
|
||||
int errline = sErrLine;
|
||||
sErrLine = -1;
|
||||
|
||||
bool is_warning = (number >= 200 && !sc_warnings_are_errors);
|
||||
|
||||
/* errflag is reset on each semicolon.
|
||||
* In a two-pass compiler, an error should not be reported twice. Therefore
|
||||
* the error reporting is enabled only in the second pass (and only when
|
||||
@ -113,8 +116,13 @@ static short lastfile;
|
||||
errnum++; /* a fatal error also counts as an error */
|
||||
} else {
|
||||
msg=warnmsg[number-200];
|
||||
pre=prefix[2];
|
||||
warnnum++;
|
||||
if (sc_warnings_are_errors) {
|
||||
pre=prefix[0];
|
||||
errnum++;
|
||||
} else {
|
||||
pre=prefix[2];
|
||||
warnnum++;
|
||||
}
|
||||
} /* if */
|
||||
|
||||
assert(errstart<=fline);
|
||||
@ -164,7 +172,7 @@ static short lastfile;
|
||||
errorcount=0;
|
||||
lastline=fline;
|
||||
lastfile=fcurrent;
|
||||
if (number<200)
|
||||
if (!is_warning)
|
||||
errorcount++;
|
||||
if (errorcount>=3)
|
||||
error(167); /* too many error/warning messages on one line */
|
||||
|
@ -94,6 +94,7 @@ int pc_optimize=sOPTIMIZE_NOMACRO; /* (peephole) optimization level */
|
||||
int pc_memflags=0; /* special flags for the stack/heap usage */
|
||||
int sc_showincludes=0; /* show include files */
|
||||
int sc_require_newdecls=0; /* Require new-style declarations */
|
||||
bool sc_warnings_are_errors=false;
|
||||
|
||||
constvalue sc_automaton_tab = { NULL, "", 0, 0}; /* automaton table */
|
||||
constvalue sc_state_tab = { NULL, "", 0, 0}; /* state table */
|
||||
|
20
sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp
Normal file
20
sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
new String:oldArray[][] =
|
||||
{
|
||||
"string",
|
||||
"string2",
|
||||
};
|
||||
|
||||
char newArray[][] =
|
||||
{
|
||||
"another string",
|
||||
"more strings",
|
||||
};
|
||||
|
||||
native Print( const String:string[] );
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
Print( oldArray[ 0 ] );
|
||||
Print( newArray[ 0 ] );
|
||||
}
|
Loading…
Reference in New Issue
Block a user