From c11635328595ae9fe33fdac7150bcca2c41cd34d Mon Sep 17 00:00:00 2001 From: Ruben Gonzalez Date: Thu, 31 Jul 2014 20:56:07 -0400 Subject: [PATCH 01/42] WiP addition of support for ValveFS to many more filesystem natives. --- core/logic/intercom.h | 7 +- core/logic/smn_filesystem.cpp | 306 ++++++++++++++++++++++++---------- core/logic_bridge.cpp | 20 +++ 3 files changed, 246 insertions(+), 87 deletions(-) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 5d86853d..ed098435 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -52,7 +52,7 @@ using namespace SourceHook; * Add 1 to the RHS of this expression to bump the intercom file * This is to prevent mismatching core/logic binaries */ -#define SM_LOGIC_MAGIC (0x0F47C0DE - 28) +#define SM_LOGIC_MAGIC (0x0F47C0DE - 29) #if defined SM_LOGIC class IVEngineServer @@ -90,6 +90,11 @@ 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 void Seek(FileHandle_t file, int post, int seekType) = 0; + virtual unsigned int Tell(FileHandle_t file) = 0; + virtual int WriteFileLine(FileHandle_t file, const char *pLine) = 0; + virtual void Flush(FileHandle_t file) = 0; }; namespace SourceMod diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 26575acf..bf166291 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -40,6 +40,7 @@ #include "common_logic.h" HandleType_t g_FileType; +HandleType_t g_ValveFileType; HandleType_t g_DirType; IChangeableForward *g_pLogHook = NULL; @@ -55,6 +56,7 @@ 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_pLogHook = forwardsys->CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String); pluginsys->AddPluginsListener(this); @@ -65,8 +67,10 @@ public: forwardsys->ReleaseForward(g_pLogHook); handlesys->RemoveType(g_DirType, g_pCoreIdent); handlesys->RemoveType(g_FileType, g_pCoreIdent); + handlesys->RemoveType(g_ValveFileType, g_pCoreIdent); g_DirType = 0; g_FileType = 0; + g_ValveFileType = 0; } virtual void OnHandleDestroy(HandleType_t type, void *object) { @@ -80,6 +84,11 @@ public: IDirectory *pDir = (IDirectory *)object; libsys->CloseDirectory(pDir); } + else if (type == g_ValveFileType) + { + FileHandle_t fp = (FileHandle_t) object; + smcore.filesystem->Close(fp); + } } virtual void AddLogHook(IPluginFunction *pFunc) { @@ -191,16 +200,29 @@ 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); + Handle_t handle = 0; - FILE *pFile = fopen(realpath, mode); - if (!pFile) + if (params[0] <= 2 || !params[3]) { - 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 = handlesys->CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); + } + } + else + { + FileHandle_t pFile = smcore.filesystem->Open(name, mode); // Should we allow pathID? + if (pFile) + { + handle = handlesys->CreateHandle(g_ValveFileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); + } } - return handlesys->CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); + return handle; } static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params) @@ -224,18 +246,12 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - FILE *pFile; int err; + 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 *buf; if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE) { @@ -243,9 +259,25 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) return 0; } - if (fgets(buf, params[3], pFile) == NULL) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) { - return 0; + FILE *pFile = (FILE *) pTempFile; + if (fgets(buf, params[3], pFile) == NULL) + { + return 0; + } + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + if (smcore.filesystem->ReadLine(buf, params[3], pFile) == NULL) + { + return 0; + } + } + else + { + return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } return 1; @@ -256,18 +288,28 @@ static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - FILE *pFile; + void *pTempFile; + cell_t ret; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FILE *pFile = (FILE *) pTempFile; + ret = feof(pFile) ? 1 : 0; + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + ret = smcore.filesystem->EndOfFile(pFile) ? 1 : 0; + } + else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return (feof(pFile)) ? 1 : 0; + return ret; } static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params) @@ -275,18 +317,25 @@ static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FILE *pFile = (FILE *) pTempFile; + fseek(pFile, params[2], params[3]); + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + smcore.filesystem->Seek(pFile, params[2], params[3]); + } + else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - - fseek(pFile, params[2], params[3]); return 1; } @@ -296,18 +345,28 @@ static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - FILE *pFile; + void *pTempFile; + cell_t ret; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FILE *pFile = (FILE *) pTempFile; + ret = ftell(pFile); + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + ret = smcore.filesystem->Tell(pFile); + } + else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return ftell(pFile); + return ret; } static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params) @@ -501,19 +560,14 @@ static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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); @@ -522,8 +576,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, (void **) &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, (void **) &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->WriteFileLine(pFile, buffer); + } + else + { + return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); + } return 1; } @@ -533,18 +602,28 @@ static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - FILE *pFile; + void *pTempFile; + cell_t ret = 1; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=handlesys->ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FILE *pFile = (FILE *) pTempFile; + ret = (fflush(pFile) == 0) ? 1 : 0; + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + smcore.filesystem->Flush(pFile);// This doesnt have a return assume 1? + } + else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return (fflush(pFile) == 0) ? 1 : 0; + return ret; } static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params) @@ -709,57 +788,112 @@ static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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 *pTempFile = NULL; + + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FILE *pFile = (FILE *) pTempFile; + + if (params[4] != 1 && params[4] != 2 && params[4] != 4) + { + return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); + } + + cell_t *data; + pContext->LocalToPhysAddr(params[2], &data); + + if (params[4] == 4) + { + read = fread(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) + { + break; + } + data[read++] = val; + } + } + else if (params[4] == 1) + { + uint8_t val; + for (cell_t i = 0; i < params[3]; i++) + { + if (fread(&val, sizeof(uint8_t), 1, pFile) != 1) + { + break; + } + data[read++] = val; + } + } + + if (read != (size_t) params[3] && ferror(pFile) != 0) + { + return -1; + } + } + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + { + FileHandle_t pFile = (FileHandle_t) pTempFile; + + if (params[4] != 1 && params[4] != 2 && params[4] != 4) + { + return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); + } + + cell_t *data; + pContext->LocalToPhysAddr(params[2], &data); + + if (params[4] == 4) + { + read = 1; + if (smcore.filesystem->Read(data, sizeof(cell_t), pFile) != sizeof(cell_t)) + { + read = 0; + } + } + else if (params[4] == 2) + { + uint16_t val; + for (cell_t i = 0; i < params[3]; i++) + { + if (smcore.filesystem->Read(&val, sizeof(uint16_t), pFile) != sizeof(uint16_t)) + { + break; + } + data[read++] = val; + } + } + else if (params[4] == 1) + { + uint8_t val; + for (cell_t i = 0; i < params[3]; i++) + { + if (smcore.filesystem->Read(&val, sizeof(uint8_t), pFile) != sizeof(uint8_t)) + { + break; + } + data[read++] = val; + } + } + + if (read != (size_t) params[3]) + { + return -1; + } + } + + else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - if (params[4] != 1 && params[4] != 2 && params[4] != 4) - { - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); - } - - cell_t *data; - pContext->LocalToPhysAddr(params[2], &data); - - if (params[4] == 4) - { - read = fread(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) - { - break; - } - data[read++] = val; - } - } - else if (params[4] == 1) - { - uint8_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (fread(&val, sizeof(uint8_t), 1, pFile) != 1) - { - break; - } - data[read++] = val; - } - } - - if (read != (size_t)params[3] && ferror(pFile) != 0) - { - return -1; - } - return read; } diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 057f660c..e1cb0b4d 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -174,6 +174,26 @@ public: { return filesystem->Size(pFileName, pPathID); } + int Read(void* pOutput, int size, FileHandle_t file) + { + return filesystem->Read(pOutput, 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 WriteFileLine(FileHandle_t file, const char *pLine) + { + return filesystem->FPrintf(file, pLine); + } + void Flush(FileHandle_t file) + { + filesystem->Flush(file); + } }; static VFileSystem_Logic logic_filesystem; From 5e7e7ce551f09213186b8446ad63d2c3bc8b6f12 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 1 Aug 2014 06:09:09 -0700 Subject: [PATCH 02/42] Improved FPrint(f) passthrough --- core/logic/intercom.h | 2 +- core/logic/smn_filesystem.cpp | 2 +- core/logic_bridge.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index ed098435..09f52b2f 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -93,7 +93,7 @@ public: virtual int Read(void* pOutput, 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 WriteFileLine(FileHandle_t file, const char *pLine) = 0; + virtual int FPrint(FileHandle_t file, const char *pData) = 0; virtual void Flush(FileHandle_t file) = 0; }; diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index bf166291..18693cb8 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -587,7 +587,7 @@ static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params) FileHandle_t pFile = (FileHandle_t) pTempFile; smcore.atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg); sprintf(buffer, "%s\n", buffer); - smcore.filesystem->WriteFileLine(pFile, buffer); + smcore.filesystem->FPrint(pFile, buffer); } else { diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index e1cb0b4d..751ba6ad 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -186,9 +186,9 @@ public: { return filesystem->Tell(file); } - int WriteFileLine(FileHandle_t file, const char *pLine) + int FPrint(FileHandle_t file, const char *pData) { - return filesystem->FPrintf(file, pLine); + return filesystem->FPrintf(file, "%s", pData); } void Flush(FileHandle_t file) { From 573aea20fb204f03fb6f52a377f5c3f00a3c1872 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 1 Aug 2014 12:38:51 -0700 Subject: [PATCH 03/42] More progress: Abstracted many fs funcs with helper class. Removed much duplicated code. Fixed ReadFile assuming FS errors for ValveFS. Added ValveFS support for ReadFileString, WriteFile, WriteFileString, DeleteFile. Added missing param in doc for OpenFile. --- core/logic/intercom.h | 3 + core/logic/smn_filesystem.cpp | 452 ++++++++++++++++++++-------------- core/logic_bridge.cpp | 12 + plugins/include/files.inc | 12 +- 4 files changed, 296 insertions(+), 183 deletions(-) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 09f52b2f..3df0a5b4 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -91,10 +91,13 @@ public: 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; }; namespace SourceMod diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 18693cb8..7e1536a1 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -44,6 +44,111 @@ HandleType_t g_ValveFileType; HandleType_t g_DirType; 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) + { + if (_fstype == FSType::VALVE) + return smcore.filesystem->Open(filename, mode); + 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) + { + if (_fstype == FSType::VALVE) + return smcore.filesystem->RemoveFile(pFilePath), 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; +}; + class FileNatives : public SMGlobalClass, public IHandleTypeDispatch, @@ -201,25 +306,29 @@ static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params) } Handle_t handle = 0; - + HandleType_t handleType; + FSHelper fshelper; + const char *openpath; if (params[0] <= 2 || !params[3]) { + handleType = g_FileType; + fshelper.SetFSType(FSType::STDIO); + char realpath[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); - - FILE *pFile = fopen(realpath, mode); - if (pFile) - { - handle = handlesys->CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); - } + openpath = realpath; } else { - FileHandle_t pFile = smcore.filesystem->Open(name, mode); // Should we allow pathID? - if (pFile) - { - handle = handlesys->CreateHandle(g_ValveFileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); - } + handleType = g_ValveFileType; + fshelper.SetFSType(FSType::VALVE); + openpath = name; + } + + void *pFile = fshelper.Open(openpath, mode); + if (pFile) + { + handle = handlesys->CreateHandle(handleType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); } return handle; @@ -235,10 +344,22 @@ 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; + 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 + { + fshelper.SetFSType(FSType::VALVE); + filepath = name; + } - return (unlink(realpath)) ? 0 : 1; + return fshelper.Remove(filepath) ? 1 : 0; } static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) @@ -248,7 +369,7 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) HandleSecurity sec; int err; - void *pTempFile; + void *pFile; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; @@ -259,28 +380,22 @@ static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) return 0; } - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + FSHelper fshelper; + + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - if (fgets(buf, params[3], pFile) == NULL) - { - return 0; - } + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - if (smcore.filesystem->ReadLine(buf, params[3], pFile) == NULL) - { - return 0; - } + 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) @@ -288,28 +403,26 @@ static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - void *pTempFile; - cell_t ret; + void *pFile; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + FSHelper fshelper; + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - ret = feof(pFile) ? 1 : 0; + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - ret = smcore.filesystem->EndOfFile(pFile) ? 1 : 0; + fshelper.SetFSType(FSType::VALVE); } else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return ret; + return fshelper.EndOfFile(pFile) ? 1 : 0; } static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params) @@ -317,25 +430,26 @@ static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - void *pTempFile; + void *pFile; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + FSHelper fshelper; + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - fseek(pFile, params[2], params[3]); + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - smcore.filesystem->Seek(pFile, params[2], params[3]); + fshelper.SetFSType(FSType::VALVE); } else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } + + fshelper.Seek(pFile, params[2], params[3]); return 1; } @@ -345,28 +459,27 @@ static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - void *pTempFile; - cell_t ret; + void *pFile; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + FSHelper fshelper; + + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - ret = ftell(pFile); + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - ret = smcore.filesystem->Tell(pFile); + fshelper.SetFSType(FSType::VALVE); } else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return ret; + return (cell_t)fshelper.Tell(pFile); } static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params) @@ -576,13 +689,13 @@ static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params) char buffer[2048]; int arg = 3; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + 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, (void **) &pTempFile)) == HandleError_None) + 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); @@ -602,28 +715,26 @@ static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(params[1]); HandleError herr; HandleSecurity sec; - void *pTempFile; - cell_t ret = 1; + void *pFile; sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + FSHelper fshelper; + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - ret = (fflush(pFile) == 0) ? 1 : 0; + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - smcore.filesystem->Flush(pFile);// This doesnt have a return assume 1? + fshelper.SetFSType(FSType::VALVE); } else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return ret; + return fshelper.Flush(pFile) ? 1 : 0; } static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params) @@ -790,111 +901,65 @@ static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params) HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); size_t read = 0; - void *pTempFile = NULL; + void *pFile = NULL; + FSHelper fshelper; - if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, (void **) &pTempFile)) == HandleError_None) + if ((herr = handlesys->ReadHandle(hndl, g_FileType, &sec, &pFile)) == HandleError_None) { - FILE *pFile = (FILE *) pTempFile; - - if (params[4] != 1 && params[4] != 2 && params[4] != 4) - { - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); - } - - cell_t *data; - pContext->LocalToPhysAddr(params[2], &data); - - if (params[4] == 4) - { - read = fread(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) - { - break; - } - data[read++] = val; - } - } - else if (params[4] == 1) - { - uint8_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (fread(&val, sizeof(uint8_t), 1, pFile) != 1) - { - break; - } - data[read++] = val; - } - } - - if (read != (size_t) params[3] && ferror(pFile) != 0) - { - return -1; - } + fshelper.SetFSType(FSType::STDIO); } - else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, (void **) &pTempFile)) == HandleError_None) + else if ((herr = handlesys->ReadHandle(hndl, g_ValveFileType, &sec, &pFile)) == HandleError_None) { - FileHandle_t pFile = (FileHandle_t) pTempFile; - - if (params[4] != 1 && params[4] != 2 && params[4] != 4) - { - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); - } - - cell_t *data; - pContext->LocalToPhysAddr(params[2], &data); - - if (params[4] == 4) - { - read = 1; - if (smcore.filesystem->Read(data, sizeof(cell_t), pFile) != sizeof(cell_t)) - { - read = 0; - } - } - else if (params[4] == 2) - { - uint16_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (smcore.filesystem->Read(&val, sizeof(uint16_t), pFile) != sizeof(uint16_t)) - { - break; - } - data[read++] = val; - } - } - else if (params[4] == 1) - { - uint8_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (smcore.filesystem->Read(&val, sizeof(uint8_t), pFile) != sizeof(uint8_t)) - { - break; - } - data[read++] = val; - } - } - - if (read != (size_t) params[3]) - { - return -1; - } + fshelper.SetFSType(FSType::VALVE); } - else { return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); } - return read; + if (params[4] != 1 && params[4] != 2 && params[4] != 4) + { + return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); + } + + cell_t *data; + pContext->LocalToPhysAddr(params[2], &data); + + if (params[4] == 4) + { + 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 (fshelper.Read(&val, sizeof(uint16_t), pFile) != 1) + { + break; + } + data[read += sizeof(uint16_t)] = val; + } + } + else if (params[4] == 1) + { + uint8_t val; + for (cell_t i = 0; i < params[3]; i++) + { + if (fshelper.Read(&val, sizeof(uint8_t), pFile) != 1) + { + break; + } + data[read += sizeof(uint8_t)] = val; + } + } + + if (read != ((size_t)params[3] * params[4]) && fshelper.HasError(pFile)) + { + return -1; + } + + return read / params[4]; } static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params) @@ -902,18 +967,27 @@ static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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])) @@ -923,9 +997,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; } @@ -940,9 +1014,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; } @@ -971,10 +1045,18 @@ static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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); } @@ -991,7 +1073,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; } @@ -1000,7 +1082,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; } @@ -1010,7 +1092,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; } @@ -1025,10 +1107,18 @@ static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params) Handle_t hndl = static_cast(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); } @@ -1043,7 +1133,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) diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 751ba6ad..3603dd85 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -178,6 +178,10 @@ public: { 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); @@ -194,6 +198,14 @@ public: { filesystem->Flush(file); } + bool IsOk(FileHandle_t file) + { + return filesystem->IsOk(file); + } + void RemoveFile(const char *pRelativePath, const char *pathID) + { + filesystem->RemoveFile(pRelativePath, pathID); + } }; static VFileSystem_Logic logic_filesystem; diff --git a/plugins/include/files.inc b/plugins/include/files.inc index 4da32671..5986b184 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -136,17 +136,25 @@ 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 any of + * the GAME search paths, rather than solely files + * existing directly in the gamedir. * @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); /** * Deletes a file. * * @param path Path of the file to delete. + * @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 + * existing directly in the gamedir. * @return True on success, false otherwise. */ -native bool:DeleteFile(const String:path[]); +native bool:DeleteFile(const String:path[], bool:use_valve_fs=false); /** * Reads a line from a text file. From 601aac440ec20ae545b1554217565825d21b69ec Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Fri, 1 Aug 2014 05:23:19 -0500 Subject: [PATCH 04/42] Implement SDKHook_Blocked and SDKHook_BlockedPost. --- extensions/sdkhooks/extension.cpp | 30 +++++++++++++++++++++++++ extensions/sdkhooks/extension.h | 4 ++++ gamedata/sdkhooks.games/engine.ep2v.txt | 18 +++++++++++++++ plugins/include/sdkhooks.inc | 6 +++++ 4 files changed, 58 insertions(+) diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index 646776c7..921a1738 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -88,6 +88,8 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] = {"Reload", "DT_BaseCombatWeapon", false}, {"ReloadPost", "DT_BaseCombatWeapon", false}, {"GetMaxHealth", "", false}, + {"Blocked", "", false}, + {"BlockedPost", "", false}, }; SDKHooks g_Interface; @@ -191,6 +193,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 *); /** @@ -529,6 +532,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; @@ -699,6 +703,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); @@ -1576,6 +1586,26 @@ 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) +{ + cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther); + + if(result >= Pl_Handled) + RETURN_META(MRES_SUPERCEDE); + + RETURN_META(MRES_IGNORED); +} + bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon) { cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon); diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h index 5c88ff9c..20380fbf 100644 --- a/extensions/sdkhooks/extension.h +++ b/extensions/sdkhooks/extension.h @@ -88,6 +88,8 @@ enum SDKHookType SDKHook_Reload, SDKHook_ReloadPost, SDKHook_GetMaxHealth, + SDKHook_Blocked, + SDKHook_BlockedPost, SDKHook_MAXHOOKS }; @@ -319,6 +321,8 @@ public: 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); diff --git a/gamedata/sdkhooks.games/engine.ep2v.txt b/gamedata/sdkhooks.games/engine.ep2v.txt index fa71bd24..0054473e 100644 --- a/gamedata/sdkhooks.games/engine.ep2v.txt +++ b/gamedata/sdkhooks.games/engine.ep2v.txt @@ -107,6 +107,12 @@ "linux" "158" "mac" "158" } + "Blocked" + { + "windows" "102" + "linux" "103" + "mac" "103" + } "Weapon_CanSwitchTo" { "windows" "265" @@ -246,6 +252,12 @@ "linux" "158" "mac" "158" } + "Blocked" + { + "windows" "102" + "linux" "103" + "mac" "103" + } "Weapon_CanSwitchTo" { "windows" "265" @@ -385,6 +397,12 @@ "linux" "158" "mac" "158" } + "Blocked" + { + "windows" "102" + "linux" "103" + "mac" "103" + } "Weapon_CanSwitchTo" { "windows" "265" diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index 2b255044..0f64456d 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -117,10 +117,15 @@ enum SDKHookType SDKHook_Reload, SDKHook_ReloadPost, SDKHook_GetMaxHealth, /**< ep2v and later */ + SDKHook_Blocked, + SDKHook_BlockedPost, }; /* Alphabetized for easy readability + + SDKHook_Blocked, + SDKHook_BlockedPost, SDKHook_EndTouch, SDKHook_EndTouchPost, @@ -210,6 +215,7 @@ funcenum SDKHookCB // EndTouch // StartTouch // Touch + // Blocked Action:public(entity, other), // EndTouchPost From f2b19e6c8795369a54768b8b9552e249c4efab61 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sun, 3 Aug 2014 09:10:02 -0400 Subject: [PATCH 05/42] Add more accurate return value for DeleteFile when using Valve FS. --- core/logic/smn_filesystem.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 7e1536a1..e2f2add4 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -125,9 +125,21 @@ public: inline bool Remove(const char *pFilePath) { if (_fstype == FSType::VALVE) - return smcore.filesystem->RemoveFile(pFilePath), true; + { + if (!smcore.filesystem->FileExists(pFilePath)) + return false; + + smcore.filesystem->RemoveFile(pFilePath); + + if (smcore.filesystem->FileExists(pFilePath)) + return false; + + return true; + } else + { return unlink(pFilePath) == 0; + } } inline bool EndOfFile(void *pFile) From 4e5b1a58cef2166249e4e44369bce7e33d52bf52 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 6 Aug 2014 13:15:24 -0700 Subject: [PATCH 06/42] Add ValveFS support to more filesystem functions: OpenDirectory (CloseHandle on directory) ReadDirEntry DirExists CreateDirectory RenameFile --- core/logic/intercom.h | 5 + core/logic/smn_filesystem.cpp | 202 ++++++++++++++++++++++++++-------- core/logic_bridge.cpp | 20 ++++ plugins/include/files.inc | 30 +++-- 4 files changed, 205 insertions(+), 52 deletions(-) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 3df0a5b4..16b96f43 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -82,7 +82,9 @@ class IFileSystem_Logic { public: virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0; + virtual const char *FindFirst(const char *pWildCard, 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; @@ -98,6 +100,9 @@ public: 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 diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index e2f2add4..71147762 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -42,6 +42,7 @@ HandleType_t g_FileType; HandleType_t g_ValveFileType; HandleType_t g_DirType; +HandleType_t g_ValveDirType; IChangeableForward *g_pLogHook = NULL; enum class FSType @@ -161,6 +162,13 @@ private: FSType _fstype; }; +struct ValveDirectory +{ + FileFindHandle_t hndl; + char szFirstPath[PLATFORM_MAX_PATH]; + bool bHandledFirstPath; +}; + class FileNatives : public SMGlobalClass, public IHandleTypeDispatch, @@ -175,6 +183,7 @@ public: 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); } @@ -185,9 +194,11 @@ public: 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) { @@ -206,6 +217,12 @@ public: 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) { @@ -238,23 +255,48 @@ 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] <= 1 || !params[2]) { - return 0; + char wildcardedPath[PLATFORM_MAX_PATH]; + snprintf(wildcardedPath, sizeof(wildcardedPath), "%s*", path); + ValveDirectory *valveDir = new ValveDirectory; + const char *pFirst = smcore.filesystem->FindFirst(wildcardedPath, &valveDir->hndl); + if (pFirst) + { + valveDir->bHandledFirstPath = false; + strncpy(valveDir->szFirstPath, pFirst, sizeof(ValveDirectory::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(params[1]); - IDirectory *pDir; + void *pTempDir; HandleError herr; HandleSecurity sec; int err; @@ -262,44 +304,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) @@ -550,6 +638,12 @@ static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params) pContext->ThrowNativeErrorEx(err, NULL); return 0; } + + if (params[0] >= 3 && params[3] == 1) + { + smcore.filesystem->RenameFile(oldpath, newpath); + return 1; + } char new_realpath[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath); @@ -572,6 +666,11 @@ static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params) pContext->ThrowNativeErrorEx(err, NULL); return 0; } + + if (params[0] >= 2 && params[2] == 1) + { + return smcore.filesystem->IsDirectory(name) ? 1 : 0; + } char realpath[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); @@ -652,9 +751,22 @@ static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params) 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) + { + if (smcore.filesystem->IsDirectory(name)) + return 0; + + smcore.filesystem->CreateDirHierarchy(name); + + if (smcore.filesystem->IsDirectory(name)) + return 1; + + return 0; + } + + char realpath[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); #if defined PLATFORM_WINDOWS diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 3603dd85..7ddf8a62 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -142,10 +142,18 @@ public: { return filesystem->FindFirstEx(pWildCard, pPathID, pHandle); } + const char *FindFirst(const char *pWildCard, FileFindHandle_t *pHandle) + { + return filesystem->FindFirst(pWildCard, pHandle); + } const char *FindNext(FileFindHandle_t handle) { return filesystem->FindNext(handle); } + bool FindIsDirectory(FileFindHandle_t handle) + { + return filesystem->FindIsDirectory(handle); + } void FindClose(FileFindHandle_t handle) { filesystem->FindClose(handle); @@ -206,6 +214,18 @@ public: { 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; diff --git a/plugins/include/files.inc b/plugins/include/files.inc index 5986b184..742ac3ce 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -108,9 +108,13 @@ 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 GAME search paths, rather than solely files + * existing directly in the gamedir. * @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); /** * Reads the current directory entry as a local filename, then moves to the next file. @@ -149,8 +153,8 @@ native Handle:OpenFile(const String:file[], const String:mode[], bool:use_valve_ * * @param path Path of the file to delete. * @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 + * This can be used to delete files existing in the game's + * DEFAULT_WRITE_PATH search path, rather than solely files * existing directly in the gamedir. * @return True on success, false otherwise. */ @@ -323,17 +327,24 @@ native bool:FileExists(const String:path[], bool:use_valve_fs=false); * * @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 + * DEFAULT_WRITE_PATH search path, rather than directly in the gamedir. + * @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); /** * 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 GAME search paths, rather than solely files + * existing directly in the gamedir. * @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); /** * Get the file size in bytes. @@ -352,7 +363,8 @@ native FileSize(const String:path[], bool:use_valve_fs=false); * 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); @@ -381,6 +393,10 @@ 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 + * DEFAULT_WRITE_PATH search path, rather than directly in the gamedir. + * In this case, mode is ignored. */ native bool:CreateDirectory(const String:path[], mode); From 5716927cbf5812d6541d1587106aca1a844d4006 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 20 Aug 2014 21:37:47 -0400 Subject: [PATCH 07/42] Fix compile error on with MSVC. --- core/logic/smn_filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 71147762..4d270d9d 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -267,7 +267,7 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params) if (pFirst) { valveDir->bHandledFirstPath = false; - strncpy(valveDir->szFirstPath, pFirst, sizeof(ValveDirectory::szFirstPath)); + strncpy(valveDir->szFirstPath, pFirst, sizeof(valveDir->szFirstPath)); } else { From c70543839f9ff1f6a2819890ec62bdcbc9280b98 Mon Sep 17 00:00:00 2001 From: FlaminSarge Date: Thu, 21 Aug 2014 23:14:14 -0700 Subject: [PATCH 08/42] Update TF2 enums for Love & War --- plugins/include/tf2.inc | 4 ++++ plugins/include/tf2_stocks.inc | 1 + 2 files changed, 5 insertions(+) diff --git a/plugins/include/tf2.inc b/plugins/include/tf2.inc index a1e9a9d9..7e079be4 100644 --- a/plugins/include/tf2.inc +++ b/plugins/include/tf2.inc @@ -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; diff --git a/plugins/include/tf2_stocks.inc b/plugins/include/tf2_stocks.inc index e0f250f6..43f69e24 100644 --- a/plugins/include/tf2_stocks.inc +++ b/plugins/include/tf2_stocks.inc @@ -249,6 +249,7 @@ enum { TF_WEAPON_SPELLBOOK, TF_WEAPON_SPELLBOOK_PROJECTILE, TF_WEAPON_SNIPERRIFLE_CLASSIC, + TF_WEAPON_PARACHUTE, }; // TF2 Weapon Loadout Slots From e1158889e55c321752c01602b469a96fa9e8f0af Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 05:56:23 -0700 Subject: [PATCH 09/42] Fix backwards use_valve_fs logic for OpenDirectory --- core/logic/smn_filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 4d270d9d..17ee986c 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -258,7 +258,7 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params) Handle_t handle = 0; - if (params[0] <= 1 || !params[2]) + if (params[0] >= 2 && params[2]) { char wildcardedPath[PLATFORM_MAX_PATH]; snprintf(wildcardedPath, sizeof(wildcardedPath), "%s*", path); From b95e7ff1451c05e02978558b3ec387ad275c9ade Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 05:59:41 -0700 Subject: [PATCH 10/42] Add missing use_valve_fs param to CreateDirectory native def --- plugins/include/files.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/include/files.inc b/plugins/include/files.inc index 742ac3ce..81dee0db 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -398,7 +398,7 @@ native bool:RemoveDir(const String:path[]); * DEFAULT_WRITE_PATH search path, rather than directly in the gamedir. * 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); /** * Returns a file timestamp as a unix timestamp. From 73115f7afa92e2cb1b6ded8e5ac6c7362cade46f Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 06:00:43 -0700 Subject: [PATCH 11/42] Add support for specifying gameinfo search path when using valveFS in file natives --- core/logic/intercom.h | 1 - core/logic/smn_filesystem.cpp | 97 +++++++++++++++++++++++++++++------ core/logic_bridge.cpp | 4 -- plugins/include/files.inc | 46 ++++++++++------- 4 files changed, 107 insertions(+), 41 deletions(-) diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 16b96f43..929a59a3 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -82,7 +82,6 @@ class IFileSystem_Logic { public: virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0; - virtual const char *FindFirst(const char *pWildCard, 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; diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 17ee986c..cd1c4e21 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -59,10 +59,10 @@ public: _fstype = fstype; } public: - inline void *Open(const char *filename, const char *mode) + inline void *Open(const char *filename, const char *mode, const char *pathID) { if (_fstype == FSType::VALVE) - return smcore.filesystem->Open(filename, mode); + return smcore.filesystem->Open(filename, mode, pathID); else return fopen(filename, mode); } @@ -123,16 +123,16 @@ public: fclose((FILE *)pFile); } - inline bool Remove(const char *pFilePath) + inline bool Remove(const char *pFilePath, const char *pathID) { if (_fstype == FSType::VALVE) { - if (!smcore.filesystem->FileExists(pFilePath)) + if (!smcore.filesystem->FileExists(pFilePath, pathID)) return false; - smcore.filesystem->RemoveFile(pFilePath); + smcore.filesystem->RemoveFile(pFilePath, pathID); - if (smcore.filesystem->FileExists(pFilePath)) + if (smcore.filesystem->FileExists(pFilePath, pathID)) return false; return true; @@ -263,7 +263,15 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params) char wildcardedPath[PLATFORM_MAX_PATH]; snprintf(wildcardedPath, sizeof(wildcardedPath), "%s*", path); ValveDirectory *valveDir = new ValveDirectory; - const char *pFirst = smcore.filesystem->FindFirst(wildcardedPath, &valveDir->hndl); + + 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; @@ -409,6 +417,7 @@ static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params) HandleType_t handleType; FSHelper fshelper; const char *openpath; + char *pathID; if (params[0] <= 2 || !params[3]) { handleType = g_FileType; @@ -420,12 +429,18 @@ static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params) } 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; } - void *pFile = fshelper.Open(openpath, mode); + void *pFile = fshelper.Open(openpath, mode, pathID); if (pFile) { handle = handlesys->CreateHandle(handleType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); @@ -446,6 +461,7 @@ static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params) FSHelper fshelper; const char *filepath; + char *pathID; if (params[0] < 2 || !params[2]) { fshelper.SetFSType(FSType::STDIO); @@ -455,11 +471,17 @@ static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params) } else { + if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE) + { + pContext->ThrowNativeErrorEx(err, NULL); + return 0; + } + fshelper.SetFSType(FSType::VALVE); filepath = name; } - return fshelper.Remove(filepath) ? 1 : 0; + return fshelper.Remove(filepath, pathID) ? 1 : 0; } static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) @@ -594,7 +616,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]; @@ -641,7 +673,14 @@ static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params) if (params[0] >= 3 && params[3] == 1) { - smcore.filesystem->RenameFile(oldpath, newpath); + 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; } @@ -669,7 +708,14 @@ static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params) if (params[0] >= 2 && params[2] == 1) { - return smcore.filesystem->IsDirectory(name) ? 1 : 0; + 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]; @@ -711,9 +757,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 { @@ -755,12 +811,19 @@ static cell_t sm_CreateDirectory(IPluginContext *pContext, const cell_t *params) if (params[0] >= 3 && params[3] == 1) { - if (smcore.filesystem->IsDirectory(name)) + 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); + smcore.filesystem->CreateDirHierarchy(name, pathID); - if (smcore.filesystem->IsDirectory(name)) + if (smcore.filesystem->IsDirectory(name, pathID)) return 1; return 0; diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 7ddf8a62..f7d0babe 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -142,10 +142,6 @@ public: { return filesystem->FindFirstEx(pWildCard, pPathID, pHandle); } - const char *FindFirst(const char *pWildCard, FileFindHandle_t *pHandle) - { - return filesystem->FindFirst(pWildCard, pHandle); - } const char *FindNext(FileFindHandle_t handle) { return filesystem->FindNext(handle); diff --git a/plugins/include/files.inc b/plugins/include/files.inc index 81dee0db..f44e47c5 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -110,11 +110,12 @@ native BuildPath(PathType:type, String:buffer[], maxlength, const String:fmt[], * @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 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 A Handle to the directory, INVALID_HANDLE on open error. */ -native Handle:OpenDirectory(const String:path[], bool:use_valve_fs=false); +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. @@ -141,24 +142,26 @@ 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 any of - * the GAME search paths, rather than solely files - * existing directly in the gamedir. + * 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[], bool:use_valve_fs=false); +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. * @param use_valve_fs If true, the Valve file system will be used instead. - * This can be used to delete files existing in the game's - * DEFAULT_WRITE_PATH search path, rather than solely files - * existing directly in the gamedir. + * 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 otherwise. */ -native bool:DeleteFile(const String:path[], bool:use_valve_fs=false); +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. @@ -316,11 +319,12 @@ 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. @@ -329,10 +333,11 @@ native bool:FileExists(const String:path[], bool:use_valve_fs=false); * @param oldpath Path to the existing file. * @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 - * DEFAULT_WRITE_PATH search path, rather than directly in the gamedir. + * 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[], bool:use_valve_fs=false); +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. @@ -340,11 +345,12 @@ native bool:RenameFile(const String:newpath[], const String:oldpath[], bool:use_ * @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 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 directory exists, false otherwise. */ -native bool:DirExists(const String:path[], bool:use_valve_fs=false); +native bool:DirExists(const String:path[], bool:use_valve_fs=false, const String:valve_path_id="GAME"); /** * Get the file size in bytes. @@ -352,11 +358,12 @@ native bool:DirExists(const String:path[], bool:use_valve_fs=false); * @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 @@ -395,7 +402,8 @@ native bool:RemoveDir(const String:path[]); * 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 - * DEFAULT_WRITE_PATH search path, rather than directly in the gamedir. + * 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, bool:use_valve_fs=false); From 8d60fecb96eecf65bd4ba99082280c358379cc99 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 06:30:25 -0700 Subject: [PATCH 12/42] Fix syntax errors in files.inc --- plugins/include/files.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/include/files.inc b/plugins/include/files.inc index f44e47c5..36adea6b 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -161,7 +161,7 @@ native Handle:OpenFile(const String:file[], const String:mode[], bool:use_valve_ * @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 otherwise. */ -native bool:DeleteFile(const String:path[], bool:use_valve_fs=false, const String:valve_path_id="DEFAULT_WRITE_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. @@ -324,7 +324,7 @@ native FilePosition(Handle:file); * @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, const String:valve_path_id="GAME"); +native bool:FileExists(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME"); /** * Renames a file. @@ -337,7 +337,7 @@ native bool:FileExists(const String:path[], bool:use_valve_fs=false, const Strin * @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[], bool:use_valve_fs=false, const String:valve_path_id="DEFAULT_WRITE_PATH"); +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. @@ -350,7 +350,7 @@ native bool:RenameFile(const String:newpath[], const String:oldpath[], bool:use_ * @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[], bool:use_valve_fs=false, const String:valve_path_id="GAME"); +native bool:DirExists(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="GAME"); /** * Get the file size in bytes. @@ -363,7 +363,7 @@ native bool:DirExists(const String:path[], bool:use_valve_fs=false, const String * @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, const String:valve_path_id="GAME"); +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 @@ -406,7 +406,7 @@ native bool:RemoveDir(const String:path[]); * @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, bool:use_valve_fs=false); +native bool:CreateDirectory(const String:path[], mode, bool:use_valve_fs=false, const String:valve_path_id="DEFAULT_WRITE_PATH"); /** * Returns a file timestamp as a unix timestamp. From 9d6fea857b0909dae0818261cb1746af42380d05 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 06:55:45 -0700 Subject: [PATCH 13/42] Fix another syntax error in files.inc --- plugins/include/files.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/include/files.inc b/plugins/include/files.inc index 36adea6b..beee0fc3 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -406,7 +406,7 @@ native bool:RemoveDir(const String:path[]); * @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, bool:use_valve_fs=false, const String:valve_path_id="DEFAULT_WRITE_PATH"); +native bool:CreateDirectory(const String:path[], mode, bool:use_valve_fs=false, const String:valve_path_id[]="DEFAULT_WRITE_PATH"); /** * Returns a file timestamp as a unix timestamp. From 51d32bca77dbf3c3bd062746ea6264d117ebc6c6 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 22 Aug 2014 07:21:12 -0700 Subject: [PATCH 14/42] Clarify return value commit on RemoveFile --- plugins/include/files.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/include/files.inc b/plugins/include/files.inc index beee0fc3..34e772f2 100644 --- a/plugins/include/files.inc +++ b/plugins/include/files.inc @@ -159,7 +159,7 @@ native Handle:OpenFile(const String:file[], const String:mode[], bool:use_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 otherwise. + * @return True on success, false on failure or if file not immediately removed. */ native bool:DeleteFile(const String:path[], bool:use_valve_fs=false, const String:valve_path_id[]="DEFAULT_WRITE_PATH"); From 9267d0c803a8707c44e8ee067275a488db3ecf2f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 22 Aug 2014 22:50:25 -0700 Subject: [PATCH 15/42] Eliminate Newborn/NoAddRef (bug 5907, r=ds). --- core/ConCmdManager.cpp | 2 +- core/logic/GameConfigs.cpp | 1 + core/logic/ShareSys.cpp | 4 +- core/logic/smn_adt_trie.cpp | 5 +-- extensions/clientprefs/extension.cpp | 2 +- public/amtl/am-refcounting-threadsafe.h | 5 ++- public/amtl/am-refcounting.h | 57 ++++++++++++++++++------- 7 files changed, 53 insertions(+), 23 deletions(-) diff --git a/core/ConCmdManager.cpp b/core/ConCmdManager.cpp index 80d3f703..e93c6cc3 100644 --- a/core/ConCmdManager.cpp +++ b/core/ConCmdManager.cpp @@ -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 cmdgroup = i->value; diff --git a/core/logic/GameConfigs.cpp b/core/logic/GameConfigs.cpp index 12067853..8c122425 100644 --- a/core/logic/GameConfigs.cpp +++ b/core/logic/GameConfigs.cpp @@ -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; diff --git a/core/logic/ShareSys.cpp b/core/logic/ShareSys.cpp index 77769662..ddde22a5 100644 --- a/core/logic/ShareSys.cpp +++ b/core/logic/ShareSys.cpp @@ -375,7 +375,7 @@ PassRef ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nat if (i.found()) return NULL; - Ref entry = Newborn(new Native(pOwner, ntv)); + Ref entry = new Native(pOwner, ntv); m_NtvCache.insert(ntv->name, entry); return entry; } @@ -415,7 +415,7 @@ PassRef ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *n CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext()); - entry = Newborn(new Native(owner, fake.take())); + entry = new Native(owner, fake.take()); m_NtvCache.insert(name, entry); return entry; diff --git a/core/logic/smn_adt_trie.cpp b/core/logic/smn_adt_trie.cpp index ab70f8cc..989df0f4 100644 --- a/core/logic/smn_adt_trie.cpp +++ b/core/logic/smn_adt_trie.cpp @@ -163,7 +163,7 @@ private: cell_t data_; }; -struct CellTrie : public ke::Refcounted +struct CellTrie { StringHashMap 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; diff --git a/extensions/clientprefs/extension.cpp b/extensions/clientprefs/extension.cpp index 96a3173b..7ff5eee2 100644 --- a/extensions/clientprefs/extension.cpp +++ b/extensions/clientprefs/extension.cpp @@ -219,7 +219,7 @@ void ClientPrefs::DatabaseConnect() char error[256]; int errCode = 0; - Database = Newborn(Driver->Connect(DBInfo, true, error, sizeof(error))); + Database = AdoptRef(Driver->Connect(DBInfo, true, error, sizeof(error))); if (!Database) { diff --git a/public/amtl/am-refcounting-threadsafe.h b/public/amtl/am-refcounting-threadsafe.h index a37b39d4..785ba62b 100644 --- a/public/amtl/am-refcounting-threadsafe.h +++ b/public/amtl/am-refcounting-threadsafe.h @@ -35,12 +35,15 @@ namespace ke { +// See the comment above Refcounted 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 class RefcountedThreadsafe { public: RefcountedThreadsafe() - : refcount_(1) + : refcount_(0) { } diff --git a/public/amtl/am-refcounting.h b/public/amtl/am-refcounting.h index 71a6f554..028d6df5 100644 --- a/public/amtl/am-refcounting.h +++ b/public/amtl/am-refcounting.h @@ -37,18 +37,28 @@ namespace ke { template 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 -class Newborn +class AlreadyRefed { public: - Newborn(T *t) + AlreadyRefed(T *t) : thing_(t) { } + ~AlreadyRefed() { + if (thing_) + thing_->Release(); + } T *release() const { return ReturnAndVoid(thing_); @@ -59,10 +69,10 @@ class Newborn }; template -static inline Newborn -NoAddRef(T *t) +static inline AlreadyRefed +AdoptRef(T *t) { - return Newborn(t); + return AlreadyRefed(t); } // When returning a value, we'd rather not be needlessly changing the refcount, @@ -81,7 +91,14 @@ class PassRef { } - PassRef(const Newborn &other) + PassRef(const AlreadyRefed &other) + : thing_(other.release()) + { + // Don't addref, newborn means already addref'd. + } + + template + PassRef(const AlreadyRefed &other) : thing_(other.release()) { // Don't addref, newborn means already addref'd. @@ -134,7 +151,7 @@ class PassRef private: // Disallowed operators. PassRef &operator =(T *other); - PassRef &operator =(Newborn &other); + PassRef &operator =(AlreadyRefed &other); void AddRef() { if (thing_) @@ -149,13 +166,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 class Refcounted { public: Refcounted() - : refcount_(1) + : refcount_(0) { } @@ -217,7 +239,12 @@ class Ref : thing_(other.release()) { } - Ref(const Newborn &other) + Ref(const AlreadyRefed &other) + : thing_(other.release()) + { + } + template + Ref(const AlreadyRefed &other) : thing_(other.release()) { } @@ -255,7 +282,7 @@ class Ref } template - Ref &operator =(const Newborn &other) { + Ref &operator =(const AlreadyRefed &other) { Release(); thing_ = other.release(); return *this; From 74908098f40d844a565dc728c6c738bd1cedff2b Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Sat, 23 Aug 2014 18:11:03 -0500 Subject: [PATCH 16/42] Allow trailing commas in string array declarations. (bug 6239) --- sourcepawn/compiler/sc1.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index 4baca471..80fdad7b 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -2720,8 +2720,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) { From 302dc1cb8aad10d155c09c543a36ee9235ee7d58 Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Tue, 26 Aug 2014 14:58:58 -0500 Subject: [PATCH 17/42] Add test. --- .../tests/ok-trailing-comma-in-literal.sp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp diff --git a/sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp b/sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp new file mode 100644 index 00000000..e1876f6d --- /dev/null +++ b/sourcepawn/compiler/tests/ok-trailing-comma-in-literal.sp @@ -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 ] ); +} From a1b7c32b295c71083f46aab9997f4b127cd6f441 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 28 Aug 2014 14:02:08 -0700 Subject: [PATCH 18/42] Add a "union" keyword to replace funcenum. --- plugins/include/console.inc | 6 ++-- plugins/include/events.inc | 6 ++-- plugins/include/sdkhooks.inc | 48 +++++++++++++++--------------- plugins/include/sdktools_trace.inc | 8 ++--- plugins/include/sorting.inc | 6 ++-- plugins/include/timers.inc | 8 ++--- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc1.cpp | 25 ++++++++++++++++ sourcepawn/compiler/sc2.cpp | 1 + 9 files changed, 68 insertions(+), 41 deletions(-) diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 6323102e..91c03222 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -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); }; /** diff --git a/plugins/include/events.inc b/plugins/include/events.inc index be3f2d46..771d1578 100644 --- a/plugins/include/events.inc +++ b/plugins/include/events.inc @@ -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); }; /** diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index 2b255044..a58f59a4 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -192,90 +192,90 @@ 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), + 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 // 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[3] damageForce, float[3] damagePosition); // 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[3] damageForce, float[3] damagePosition, 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]), + 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[3] damageForce, const float[3] damagePosition); // 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); }; diff --git a/plugins/include/sdktools_trace.inc b/plugins/include/sdktools_trace.inc index 27de9201..ce493547 100644 --- a/plugins/include/sdktools_trace.inc +++ b/plugins/include/sdktools_trace.inc @@ -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]); \ No newline at end of file +native TR_PointOutsideWorld(Float:pos[3]); diff --git a/plugins/include/sorting.inc b/plugins/include/sorting.inc index 161aff00..e60bcd6e 100644 --- a/plugins/include/sorting.inc +++ b/plugins/include/sorting.inc @@ -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); }; /** diff --git a/plugins/include/timers.inc b/plugins/include/timers.inc index d0a9ed09..8da9696b 100644 --- a/plugins/include/timers.inc +++ b/plugins/include/timers.inc @@ -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); }; /** diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index aaab83c3..42020bca 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -432,6 +432,7 @@ enum TokenKind { tTAGOF, tTHEN, tTYPEDEF, + tUNION, tVOID, tWHILE, /* compiler directives */ diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index 4baca471..ecd002f2 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -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); @@ -1535,6 +1536,9 @@ static void parse(void) case tTYPEDEF: dotypedef(); break; + case tUNION: + dounion(); + break; case tSTRUCT: declstruct(); break; @@ -4247,6 +4251,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 diff --git a/sourcepawn/compiler/sc2.cpp b/sourcepawn/compiler/sc2.cpp index b03d6929..7b5f25cd 100644 --- a/sourcepawn/compiler/sc2.cpp +++ b/sourcepawn/compiler/sc2.cpp @@ -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", From b81c44cf49d13f66b172dd02f285854416d99768 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 29 Aug 2014 09:53:43 -0700 Subject: [PATCH 19/42] Update for hl2sdk-dota changes --- core/EventManager.cpp | 2 +- core/EventManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/EventManager.cpp b/core/EventManager.cpp index 308dbf9c..89d4da25 100644 --- a/core/EventManager.cpp +++ b/core/EventManager.cpp @@ -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; diff --git a/core/EventManager.h b/core/EventManager.h index 005b938f..12d2e7d4 100644 --- a/core/EventManager.h +++ b/core/EventManager.h @@ -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: From e9e35979a4e24c72c1eb08f8620d2ff40eee1bf6 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Mon, 1 Sep 2014 11:25:55 -0400 Subject: [PATCH 20/42] Update core AMBuild script for hl2sdk-csgo and hl2sdk-dota protobuf changes. --- core/AMBuilder | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/AMBuilder b/core/AMBuilder index d9f62d83..b8f466be 100644 --- a/core/AMBuilder +++ b/core/AMBuilder @@ -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'), From cae1d0dec1b398e979ee7c0d3bbd35d238424355 Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Tue, 2 Sep 2014 13:01:18 -0500 Subject: [PATCH 21/42] Don't override hook result in BlockedPost. --- extensions/sdkhooks/extension.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index 921a1738..e3624817 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -1598,11 +1598,7 @@ void SDKHooks::Hook_Blocked(CBaseEntity *pOther) void SDKHooks::Hook_BlockedPost(CBaseEntity *pOther) { - cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther); - - if(result >= Pl_Handled) - RETURN_META(MRES_SUPERCEDE); - + Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther); RETURN_META(MRES_IGNORED); } From 8c89b72fbc8b31c0794562683df69ea72c3cadc2 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 2 Sep 2014 14:40:39 -0700 Subject: [PATCH 22/42] Expose explicit client auth string formats --- core/PlayerManager.cpp | 38 +++++--- core/PlayerManager.h | 6 +- core/logic/smn_players.cpp | 117 ++++++++++++++++++++++-- gamedata/core.games/engine.bgt.txt | 5 + gamedata/core.games/engine.css.txt | 5 + gamedata/core.games/engine.darkm.txt | 5 + gamedata/core.games/engine.ep1.txt | 5 + gamedata/core.games/engine.ep2.txt | 8 ++ gamedata/core.games/engine.ep2valve.txt | 5 + gamedata/core.games/engine.eye.txt | 5 + gamedata/core.games/engine.sdk2013.txt | 8 ++ plugins/include/clients.inc | 16 +++- public/IPlayerHelpers.h | 11 ++- 13 files changed, 210 insertions(+), 24 deletions(-) diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 587db7e5..4bdecd8a 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -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() diff --git a/core/PlayerManager.h b/core/PlayerManager.h index 9bb58f0b..ad98090c 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -43,6 +43,8 @@ #include #include "ConVarManager.h" +#include + 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 diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index 47288f0a..7b27c0a1 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -37,12 +37,21 @@ #include #include #include +#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,6 +331,15 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params) return 1; } +// Must match clients.inc +enum class AuthStringType +{ + Engine, + Steam2, + Steam3, + SteamID64, +}; + static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) { int index = params[1]; @@ -337,19 +355,100 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) } bool validate = true; - if (params[0] > 3) + if (params[0] >= 4) { validate = !!params[4]; - } - - const char *authstr = pPlayer->GetAuthString(validate); - - if (!authstr || authstr[0] == '\0') - { - return 0; } + + AuthStringType authType = AuthStringType::Engine; + if (params[0] >= 5) + { + authType = (AuthStringType)params[5]; + } - pCtx->StringToLocal(params[2], static_cast(params[3]), authstr); + switch (authType) + { + case AuthStringType::Engine: + { + const char *authstr = pPlayer->GetAuthString(validate); + if (!authstr || authstr[0] == '\0') + { + return 0; + } + + pCtx->StringToLocal(params[2], static_cast(params[3]), authstr); + } + break; + case AuthStringType::Steam2: + case AuthStringType::Steam3: + { + if (pPlayer->IsFakeClient()) + { + pCtx->StringToLocal(params[2], static_cast(params[3]), "BOT"); + return 1; + } + + uint64_t steamId = pPlayer->GetSteamID64(validate); + if (steamId == 0) + { + if (gamehelpers->IsLANServer()) + { + pCtx->StringToLocal(params[2], static_cast(params[3]), "STEAM_ID_LAN"); + } + else + { + pCtx->StringToLocal(params[2], static_cast(params[3]), "STEAM_ID_PENDING"); + } + + return 1; + } + + char szAuth[64]; + unsigned int universe = steamId >> 56; + unsigned int accountId = steamId & 0xFFFFFFFF; + unsigned int instance = (steamId >> 32) & 0x000FFFFF; + if (authType == AuthStringType::Steam2) + { + if (atoi(g_pGameConf->GetKeyValue("UseInvalidUniverseInSteam2IDs")) == 1) + { + universe = 0; + } + + snprintf(szAuth, sizeof(szAuth), "STEAM_%u:%u:%u", universe, accountId % 2, 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(params[2], static_cast(params[3]), szAuth); + } + break; + + case AuthStringType::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(params[2], static_cast(params[3]), szAuth); + } + break; + } return 1; } diff --git a/gamedata/core.games/engine.bgt.txt b/gamedata/core.games/engine.bgt.txt index 674993e8..c4502dbb 100644 --- a/gamedata/core.games/engine.bgt.txt +++ b/gamedata/core.games/engine.bgt.txt @@ -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" + } } } diff --git a/gamedata/core.games/engine.css.txt b/gamedata/core.games/engine.css.txt index cf08b2b0..2ec1cc75 100644 --- a/gamedata/core.games/engine.css.txt +++ b/gamedata/core.games/engine.css.txt @@ -53,5 +53,10 @@ "mac" "@gEntList" } } + + "Keys" + { + "UseInvalidUniverseInSteam2IDs" "1" + } } } diff --git a/gamedata/core.games/engine.darkm.txt b/gamedata/core.games/engine.darkm.txt index d84d54b3..f458d257 100644 --- a/gamedata/core.games/engine.darkm.txt +++ b/gamedata/core.games/engine.darkm.txt @@ -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" + } } } diff --git a/gamedata/core.games/engine.ep1.txt b/gamedata/core.games/engine.ep1.txt index de669556..932f92ca 100644 --- a/gamedata/core.games/engine.ep1.txt +++ b/gamedata/core.games/engine.ep1.txt @@ -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" + } } } diff --git a/gamedata/core.games/engine.ep2.txt b/gamedata/core.games/engine.ep2.txt index ba0a3460..d1a4f5bd 100644 --- a/gamedata/core.games/engine.ep2.txt +++ b/gamedata/core.games/engine.ep2.txt @@ -58,4 +58,12 @@ } } } + + "#default" + { + "Keys" + { + "UseInvalidUniverseInSteam2IDs" "1" + } + } } diff --git a/gamedata/core.games/engine.ep2valve.txt b/gamedata/core.games/engine.ep2valve.txt index 55eef306..0dc63e82 100644 --- a/gamedata/core.games/engine.ep2valve.txt +++ b/gamedata/core.games/engine.ep2valve.txt @@ -52,5 +52,10 @@ "mac" "@gEntList" } } + + "Keys" + { + "UseInvalidUniverseInSteam2IDs" "1" + } } } diff --git a/gamedata/core.games/engine.eye.txt b/gamedata/core.games/engine.eye.txt index f99e691d..045f65aa 100644 --- a/gamedata/core.games/engine.eye.txt +++ b/gamedata/core.games/engine.eye.txt @@ -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" + } } } diff --git a/gamedata/core.games/engine.sdk2013.txt b/gamedata/core.games/engine.sdk2013.txt index 498fb367..4912944c 100644 --- a/gamedata/core.games/engine.sdk2013.txt +++ b/gamedata/core.games/engine.sdk2013.txt @@ -95,4 +95,12 @@ } } } + + "#default" + { + "Keys" + { + "UseInvalidUniverseInSteam2IDs" "1" + } + } } diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 174ca0ad..913d26a3 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -45,6 +45,19 @@ enum NetFlow NetFlow_Both, /**< Both values added together */ }; +/** + * Auth string types. + */ +enum AuthStringType +{ + AuthString_Engine, /**< The game-specific auth string as returned from the engine */ + + // The following are only available on games that support Steam authentication. + AuthString_Steam2, /**< Steam2 rendered format, ex "STEAM_1:1:4153990" */ + AuthString_Steam3, /**< Steam3 rendered format, ex "[U:1:8307981]" */ + AuthString_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. @@ -264,10 +277,11 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true); * @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. + * @param authType Auth string type and format to use. * @return True on success, false otherwise. * @error If the client is not connected or the index is invalid. */ -native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true); +native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true, AuthStringType:authType=AuthString_Engine); /** * Returns the client's Steam account ID. diff --git a/public/IPlayerHelpers.h b/public/IPlayerHelpers.h index 8b1d9cd2..72e007e4 100644 --- a/public/IPlayerHelpers.h +++ b/public/IPlayerHelpers.h @@ -41,7 +41,7 @@ #include #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; }; /** From e3b87a5ca4b358da7108c38fbdef1823f45fa953 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 2 Sep 2014 17:38:25 -0700 Subject: [PATCH 23/42] Spin new logic into GetClientAuthString2... and mark GetClientAuthString as deprecated, using 1.6.x GetClientAuthString behavior --- core/logic/smn_players.cpp | 44 ++++++++++++++++++++----------------- plugins/include/clients.inc | 19 ++++++++++++++-- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index 7b27c0a1..ba42ecae 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -340,9 +340,8 @@ enum class AuthStringType SteamID64, }; -static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) +static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType 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); @@ -354,18 +353,6 @@ 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] >= 4) - { - validate = !!params[4]; - } - - AuthStringType authType = AuthStringType::Engine; - if (params[0] >= 5) - { - authType = (AuthStringType)params[5]; - } - switch (authType) { case AuthStringType::Engine: @@ -376,7 +363,7 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) return 0; } - pCtx->StringToLocal(params[2], static_cast(params[3]), authstr); + pCtx->StringToLocal(local_addr, bytes, authstr); } break; case AuthStringType::Steam2: @@ -384,7 +371,7 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) { if (pPlayer->IsFakeClient()) { - pCtx->StringToLocal(params[2], static_cast(params[3]), "BOT"); + pCtx->StringToLocal(local_addr, bytes, "BOT"); return 1; } @@ -393,11 +380,11 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) { if (gamehelpers->IsLANServer()) { - pCtx->StringToLocal(params[2], static_cast(params[3]), "STEAM_ID_LAN"); + pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_LAN"); } else { - pCtx->StringToLocal(params[2], static_cast(params[3]), "STEAM_ID_PENDING"); + pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_PENDING"); } return 1; @@ -425,7 +412,7 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) snprintf(szAuth, sizeof(szAuth), "[U:%u:%u]", universe, accountId); } - pCtx->StringToLocal(params[2], static_cast(params[3]), szAuth); + pCtx->StringToLocal(local_addr, bytes, szAuth); } break; @@ -445,7 +432,7 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) char szAuth[64]; snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId); - pCtx->StringToLocal(params[2], static_cast(params[3]), szAuth); + pCtx->StringToLocal(local_addr, bytes, szAuth); } break; } @@ -453,6 +440,22 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) 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], AuthStringType::Steam2, params[2], (size_t)params[3], validate); +} + +static cell_t sm_GetClientAuthStr2(IPluginContext *pCtx, const cell_t *params) +{ + return SteamIDToLocal(pCtx, params[1], (AuthStringType)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]; @@ -1639,6 +1642,7 @@ REGISTER_NATIVES(playernatives) { "CanUserTarget", CanUserTarget }, { "ChangeClientTeam", ChangeClientTeam }, { "GetClientAuthString", sm_GetClientAuthStr }, + { "GetClientAuthString2", sm_GetClientAuthStr2 }, { "GetSteamAccountID", sm_GetSteamAccountID }, { "GetClientCount", sm_GetClientCount }, { "GetClientInfo", sm_GetClientInfo }, diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 913d26a3..ef4aa7fa 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -277,11 +277,26 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true); * @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. - * @param authType Auth string type and format to use. * @return True on success, false otherwise. * @error If the client is not connected or the index is invalid. */ -native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true, AuthStringType:authType=AuthString_Engine); +#pragma deprecated Use GetClientAuthString2 +native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true); + +/** + * Retrieves a client's authentication string (SteamID). + * + * @param client Player index. + * @param authType Auth string type and format to use. + * @param auth Buffer to store the client's auth string. + * @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:GetClientAuthString2(client, AuthStringType:authType, String:auth[], maxlen, bool:validate=true); /** * Returns the client's Steam account ID. From eafd6626ec1cb3d395e84c7974ea045dd2a52d0c Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 2 Sep 2014 17:44:11 -0700 Subject: [PATCH 24/42] Fix true return when validation wanted and steam id pending --- core/logic/smn_players.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index ba42ecae..196b5539 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -381,13 +381,17 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut if (gamehelpers->IsLANServer()) { pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_LAN"); + return 1; } - else + else if (!validate) { pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_PENDING"); + return 1; + } + else + { + return 0; } - - return 1; } char szAuth[64]; From d0c701793c3cd7279c1104c4ea8656620e9081b6 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 2 Sep 2014 17:47:33 -0700 Subject: [PATCH 25/42] Document possibly-unexpected yet valid auth strings --- plugins/include/clients.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index ef4aa7fa..4de44ef9 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -47,6 +47,12 @@ enum NetFlow /** * 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 AuthStringType { From e11fec9ba1cd24e1bf252ea00452af3d12590f9e Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Tue, 2 Sep 2014 18:11:36 -0700 Subject: [PATCH 26/42] Rename GetClientAuthString2 to GetClientAuthId --- core/logic/smn_players.cpp | 4 ++-- plugins/include/clients.inc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index 196b5539..7a4bf35c 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -455,7 +455,7 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) return SteamIDToLocal(pCtx, params[1], AuthStringType::Steam2, params[2], (size_t)params[3], validate); } -static cell_t sm_GetClientAuthStr2(IPluginContext *pCtx, const cell_t *params) +static cell_t sm_GetClientAuthId(IPluginContext *pCtx, const cell_t *params) { return SteamIDToLocal(pCtx, params[1], (AuthStringType)params[2], params[3], (size_t)params[4], params[5] != 0); } @@ -1646,7 +1646,7 @@ REGISTER_NATIVES(playernatives) { "CanUserTarget", CanUserTarget }, { "ChangeClientTeam", ChangeClientTeam }, { "GetClientAuthString", sm_GetClientAuthStr }, - { "GetClientAuthString2", sm_GetClientAuthStr2 }, + { "GetClientAuthId", sm_GetClientAuthId }, { "GetSteamAccountID", sm_GetSteamAccountID }, { "GetClientCount", sm_GetClientCount }, { "GetClientInfo", sm_GetClientInfo }, diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 4de44ef9..600bf3fe 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -286,7 +286,7 @@ 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 GetClientAuthString2 +#pragma deprecated Use GetClientAuthId native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true); /** @@ -302,7 +302,7 @@ native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=tru * @return True on success, false otherwise. * @error If the client is not connected or the index is invalid. */ -native bool:GetClientAuthString2(client, AuthStringType:authType, String:auth[], maxlen, bool:validate=true); +native bool:GetClientAuthId(client, AuthStringType:authType, String:auth[], maxlen, bool:validate=true); /** * Returns the client's Steam account ID. From 3fba1d2817883f53a9f12784e3be2bc0b456ab74 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 3 Sep 2014 10:50:11 -0700 Subject: [PATCH 27/42] Fix some nits --- core/logic/smn_players.cpp | 4 ++-- plugins/include/clients.inc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index 7a4bf35c..e4eb7eac 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -334,7 +334,7 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params) // Must match clients.inc enum class AuthStringType { - Engine, + Engine = 0, Steam2, Steam3, SteamID64, @@ -405,7 +405,7 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut universe = 0; } - snprintf(szAuth, sizeof(szAuth), "STEAM_%u:%u:%u", universe, accountId % 2, accountId >> 1); + snprintf(szAuth, sizeof(szAuth), "STEAM_%u:%u:%u", universe, accountId & 1, accountId >> 1); } else if (instance != 1) { diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 600bf3fe..61045683 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -56,7 +56,7 @@ enum NetFlow */ enum AuthStringType { - AuthString_Engine, /**< The game-specific auth string as returned from the engine */ + AuthString_Engine = 0, /**< The game-specific auth string as returned from the engine */ // The following are only available on games that support Steam authentication. AuthString_Steam2, /**< Steam2 rendered format, ex "STEAM_1:1:4153990" */ From 01d1c0c806ce9c42b38d10058edb39eb051a2854 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 11:04:25 -0700 Subject: [PATCH 28/42] Add a flag for warnings-as-errors. --- sourcepawn/compiler/libpawnc.cpp | 2 +- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc1.cpp | 4 ++++ sourcepawn/compiler/sc5.cpp | 14 +++++++++++--- sourcepawn/compiler/scvars.cpp | 1 + 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/sourcepawn/compiler/libpawnc.cpp b/sourcepawn/compiler/libpawnc.cpp index f99086d9..31e7c30c 100644 --- a/sourcepawn/compiler/libpawnc.cpp +++ b/sourcepawn/compiler/libpawnc.cpp @@ -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; diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 42020bca..79c7a4f9 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -912,6 +912,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 */ diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index d2d88c20..86fe6936 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -944,6 +944,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)); @@ -1312,6 +1315,7 @@ static void about(void) pc_printf(" -t TAB indent size (in character positions, default=%d)\n",sc_tabsize); pc_printf(" -v verbosity level; 0=quiet, 1=normal, 2=verbose (default=%d)\n",verbosity); pc_printf(" -w disable a specific warning by its number\n"); + pc_printf(" -E treat warnings as errors\n"); pc_printf(" -X abstract machine size limit in bytes\n"); pc_printf(" -XD abstract machine data/stack size limit in bytes\n"); pc_printf(" -\\ use '\\' for escape characters\n"); diff --git a/sourcepawn/compiler/sc5.cpp b/sourcepawn/compiler/sc5.cpp index 64d2a649..e161ed1a 100644 --- a/sourcepawn/compiler/sc5.cpp +++ b/sourcepawn/compiler/sc5.cpp @@ -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 */ diff --git a/sourcepawn/compiler/scvars.cpp b/sourcepawn/compiler/scvars.cpp index 0f030923..3f1a5131 100644 --- a/sourcepawn/compiler/scvars.cpp +++ b/sourcepawn/compiler/scvars.cpp @@ -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 */ From be55587d70898665fa2528296e05299edc37204d Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 3 Sep 2014 17:45:34 -0400 Subject: [PATCH 29/42] Add OnTakeDamage_Alive hook support to SDKHooks (bug=6249). --- extensions/sdkhooks/extension.cpp | 64 ++- extensions/sdkhooks/extension.h | 698 +++++++++++++++--------------- plugins/include/sdkhooks.inc | 7 + 3 files changed, 407 insertions(+), 362 deletions(-) diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index e3624817..94d6009f 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -90,6 +90,8 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] = {"GetMaxHealth", "", false}, {"Blocked", "", false}, {"BlockedPost", "", false}, + {"OnTakeDamageAlive", "DT_BaseCombatCharacter", false}, + {"OnTakeDamageAlivePost", "DT_BaseCombatCharacter", false}, }; SDKHooks g_Interface; @@ -168,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); @@ -515,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); @@ -607,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; @@ -999,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 &vtablehooklist = g_HookList[SDKHook_OnTakeDamage]; + ke::Vector &vtablehooklist = g_HookList[hookType]; for (size_t entry = 0; entry < vtablehooklist.length(); ++entry) { if (vhook != vtablehooklist[entry]->vtablehook) @@ -1020,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; @@ -1039,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); @@ -1077,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; } @@ -1090,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 &vtablehooklist = g_HookList[SDKHook_OnTakeDamagePost]; + ke::Vector &vtablehooklist = g_HookList[hookType]; for (size_t entry = 0; entry < vtablehooklist.length(); ++entry) { if (vhook != vtablehooklist[entry]->vtablehook) @@ -1118,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()); @@ -1136,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); diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h index 20380fbf..50f2116b 100644 --- a/extensions/sdkhooks/extension.h +++ b/extensions/sdkhooks/extension.h @@ -1,353 +1,361 @@ -#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ -#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ - -#include "smsdk_ext.h" -#include -#include -#include -#include -#include -#include - -#include -#include - -#if SOURCE_ENGINE >= SE_ORANGEBOX -#include -#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, +#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ + +#include "smsdk_ext.h" +#include +#include +#include +#include +#include +#include + +#include +#include + +#if SOURCE_ENGINE >= SE_ORANGEBOX +#include +#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_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 hooks; -}; - + 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 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 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 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); - 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); -}; - -extern CGlobalVars *gpGlobals; -extern ke::Vector 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 g_HookList[SDKHook_MAXHOOKS]; + +extern ICvar *icvar; + +#if SOURCE_ENGINE >= SE_ORANGEBOX +extern IServerTools *servertools; +#endif + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index ad8670e1..f3129892 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -119,6 +119,8 @@ enum SDKHookType SDKHook_GetMaxHealth, /**< ep2v and later */ SDKHook_Blocked, SDKHook_BlockedPost, + SDKHook_OnTakeDamageAlive, + SDKHook_OnTakeDamageAlivePost, }; /* @@ -139,6 +141,9 @@ enum SDKHookType SDKHook_OnTakeDamage, SDKHook_OnTakeDamagePost, + SDKHook_OnTakeDamageAlive, + SDKHook_OnTakeDamageAlivePost, + SDKHook_PreThink, SDKHook_PreThinkPost, @@ -244,6 +249,7 @@ union SDKHookCB 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+ @@ -256,6 +262,7 @@ union SDKHookCB float[3] damageForce, float[3] damagePosition, int damagecustom); // OnTakeDamagePost + // 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[3] damageForce, const float[3] damagePosition); From 7f3656215bb0cecf8d0a5830c063e2644ce29e46 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 3 Sep 2014 15:13:30 -0700 Subject: [PATCH 30/42] Consistency Fixes (ID->Id, AuthString->AuthId) --- core/PlayerManager.cpp | 18 +++++++++--------- core/PlayerManager.h | 6 +++--- core/logic/smn_players.cpp | 24 ++++++++++++------------ plugins/include/clients.inc | 16 ++++++++-------- public/IPlayerHelpers.h | 4 ++-- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 4bdecd8a..c9600edf 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -1914,7 +1914,7 @@ CPlayer::CPlayer() m_bIsSourceTV = false; m_bIsReplay = false; m_Serial.value = -1; - m_SteamID = k_steamIDNil; + 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_SteamID = k_steamIDNil; + m_SteamId = k_steamIDNil; #if SOURCE_ENGINE == SE_CSGO m_LanguageCookie = InvalidQueryCvarCookie; #endif @@ -2033,7 +2033,7 @@ const char *CPlayer::GetAuthString(bool validated) return m_AuthID.c_str(); } -const CSteamID &CPlayer::GetSteamID(bool validated) +const CSteamID &CPlayer::GetSteamId(bool validated) { if (IsFakeClient() || (validated && !IsAuthStringValidated())) { @@ -2041,9 +2041,9 @@ const CSteamID &CPlayer::GetSteamID(bool validated) return invalidId; } - if (m_SteamID.IsValid()) + if (m_SteamId.IsValid()) { - return m_SteamID; + return m_SteamId; } #if SOURCE_ENGINE < SE_ORANGEBOX @@ -2051,7 +2051,7 @@ const CSteamID &CPlayer::GetSteamID(bool validated) /* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */ if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_') { - m_SteamID = CSteamID(atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1), + m_SteamId = CSteamID(atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1), k_unSteamUserDesktopInstance, k_EUniversePublic, k_EAccountTypeIndividual); } #else @@ -2064,17 +2064,17 @@ const CSteamID &CPlayer::GetSteamID(bool validated) if (steamId) { - m_SteamID = (*steamId); + m_SteamId = (*steamId); } #endif - return m_SteamID; + return m_SteamId; } unsigned int CPlayer::GetSteamAccountID(bool validated) { if (!IsFakeClient() && (!validated || IsAuthStringValidated())) { - const CSteamID &id = GetSteamID(); + const CSteamID &id = GetSteamId(); if (id.IsValid()) return id.GetAccountID(); } diff --git a/core/PlayerManager.h b/core/PlayerManager.h index ad98090c..cfd57cc0 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -73,8 +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(); } + const CSteamID &GetSteamId(bool validated = true); + uint64_t GetSteamId64(bool validated = true) { return GetSteamId(validated).ConvertToUint64(); } edict_t *GetEdict(); bool IsInGame(); bool WasCountedAsInGame(); @@ -134,7 +134,7 @@ private: bool m_bIsSourceTV; bool m_bIsReplay; serial_t m_Serial; - CSteamID m_SteamID; + CSteamID m_SteamId; #if SOURCE_ENGINE == SE_CSGO QueryCvarCookie_t m_LanguageCookie; #endif diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index e4eb7eac..34b24798 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -332,15 +332,15 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params) } // Must match clients.inc -enum class AuthStringType +enum class AuthIdType { Engine = 0, Steam2, Steam3, - SteamID64, + SteamId64, }; -static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType authType, cell_t local_addr, size_t bytes, bool validate) +static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authType, cell_t local_addr, size_t bytes, bool validate) { if ((index < 1) || (index > playerhelpers->GetMaxClients())) { @@ -355,7 +355,7 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut switch (authType) { - case AuthStringType::Engine: + case AuthIdType::Engine: { const char *authstr = pPlayer->GetAuthString(validate); if (!authstr || authstr[0] == '\0') @@ -366,8 +366,8 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut pCtx->StringToLocal(local_addr, bytes, authstr); } break; - case AuthStringType::Steam2: - case AuthStringType::Steam3: + case AuthIdType::Steam2: + case AuthIdType::Steam3: { if (pPlayer->IsFakeClient()) { @@ -375,7 +375,7 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut return 1; } - uint64_t steamId = pPlayer->GetSteamID64(validate); + uint64_t steamId = pPlayer->GetSteamId64(validate); if (steamId == 0) { if (gamehelpers->IsLANServer()) @@ -398,7 +398,7 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut unsigned int universe = steamId >> 56; unsigned int accountId = steamId & 0xFFFFFFFF; unsigned int instance = (steamId >> 32) & 0x000FFFFF; - if (authType == AuthStringType::Steam2) + if (authType == AuthIdType::Steam2) { if (atoi(g_pGameConf->GetKeyValue("UseInvalidUniverseInSteam2IDs")) == 1) { @@ -420,14 +420,14 @@ static cell_t SteamIDToLocal(IPluginContext *pCtx, int index, AuthStringType aut } break; - case AuthStringType::SteamID64: + case AuthIdType::SteamId64: { if (pPlayer->IsFakeClient() || gamehelpers->IsLANServer()) { return 0; } - uint64_t steamId = pPlayer->GetSteamID64(validate); + uint64_t steamId = pPlayer->GetSteamId64(validate); if (steamId == 0) { return 0; @@ -452,12 +452,12 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) validate = !!params[4]; } - return SteamIDToLocal(pCtx, params[1], AuthStringType::Steam2, params[2], (size_t)params[3], validate); + 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], (AuthStringType)params[2], params[3], (size_t)params[4], params[5] != 0); + 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) diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 61045683..b30a3040 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -54,14 +54,14 @@ enum NetFlow * "STEAM_ID_LAN" - Authentication is disabled because of being on a LAN server. * "BOT" - The client is a bot. */ -enum AuthStringType +enum AuthIdType { - AuthString_Engine = 0, /**< The game-specific auth string as returned from the engine */ + AuthId_Engine = 0, /**< The game-specific auth string as returned from the engine */ // The following are only available on games that support Steam authentication. - AuthString_Steam2, /**< Steam2 rendered format, ex "STEAM_1:1:4153990" */ - AuthString_Steam3, /**< Steam3 rendered format, ex "[U:1:8307981]" */ - AuthString_SteamID64, /**< A SteamID64 (uint64) as a String, ex "76561197968573709" */ + 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" */ }; /** @@ -293,8 +293,8 @@ native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=tru * Retrieves a client's authentication string (SteamID). * * @param client Player index. - * @param authType Auth string type and format to use. - * @param auth Buffer to store the client's auth string. + * @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, @@ -302,7 +302,7 @@ native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=tru * @return True on success, false otherwise. * @error If the client is not connected or the index is invalid. */ -native bool:GetClientAuthId(client, AuthStringType:authType, String:auth[], maxlen, bool:validate=true); +native bool:GetClientAuthId(client, AuthIdType:authType, String:auth[], maxlen, bool:validate=true); /** * Returns the client's Steam account ID. diff --git a/public/IPlayerHelpers.h b/public/IPlayerHelpers.h index 72e007e4..35a174a7 100644 --- a/public/IPlayerHelpers.h +++ b/public/IPlayerHelpers.h @@ -273,9 +273,9 @@ namespace SourceMod * * @param validated Check backend validation status. * - * @return Steam ID or 0 if not available. + * @return Steam Id or 0 if not available. */ - virtual uint64_t GetSteamID64(bool validated = true) =0; + virtual uint64_t GetSteamId64(bool validated = true) =0; }; /** From b2b82f4a862522c434bc1cb24d233ea36d478246 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 3 Sep 2014 18:49:14 -0400 Subject: [PATCH 31/42] Add gamedata for SDKHooks Blocked and OnTakeDamage_Alive for many games. --- gamedata/sdkhooks.games/engine.blade.txt | 12 ++++++++++++ gamedata/sdkhooks.games/engine.csgo.txt | 12 ++++++++++++ gamedata/sdkhooks.games/engine.ep2v.txt | 18 ++++++++++++++++++ gamedata/sdkhooks.games/engine.insurgency.txt | 12 ++++++++++++ gamedata/sdkhooks.games/engine.l4d.txt | 12 ++++++++++++ gamedata/sdkhooks.games/game.cstrike.txt | 12 ++++++++++++ gamedata/sdkhooks.games/game.fof.txt | 12 ++++++++++++ gamedata/sdkhooks.games/game.l4d2.txt | 12 ++++++++++++ gamedata/sdkhooks.games/game.nmrih.txt | 12 ++++++++++++ gamedata/sdkhooks.games/game.nucleardawn.txt | 12 ++++++++++++ 10 files changed, 126 insertions(+) diff --git a/gamedata/sdkhooks.games/engine.blade.txt b/gamedata/sdkhooks.games/engine.blade.txt index 1973cf49..50e1e831 100644 --- a/gamedata/sdkhooks.games/engine.blade.txt +++ b/gamedata/sdkhooks.games/engine.blade.txt @@ -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" diff --git a/gamedata/sdkhooks.games/engine.csgo.txt b/gamedata/sdkhooks.games/engine.csgo.txt index 31ad5852..54f0fca3 100644 --- a/gamedata/sdkhooks.games/engine.csgo.txt +++ b/gamedata/sdkhooks.games/engine.csgo.txt @@ -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" diff --git a/gamedata/sdkhooks.games/engine.ep2v.txt b/gamedata/sdkhooks.games/engine.ep2v.txt index 0054473e..7c0be283 100644 --- a/gamedata/sdkhooks.games/engine.ep2v.txt +++ b/gamedata/sdkhooks.games/engine.ep2v.txt @@ -35,6 +35,12 @@ "linux" "63" "mac" "63" } + "OnTakeDamage_Alive" + { + "windows" "271" + "linux" "272" + "mac" "272" + } "PreThink" { "windows" "331" @@ -180,6 +186,12 @@ "linux" "63" "mac" "63" } + "OnTakeDamage_Alive" + { + "windows" "271" + "linux" "272" + "mac" "272" + } "PreThink" { "windows" "331" @@ -325,6 +337,12 @@ "linux" "63" "mac" "63" } + "OnTakeDamage_Alive" + { + "windows" "271" + "linux" "272" + "mac" "272" + } "PreThink" { "windows" "331" diff --git a/gamedata/sdkhooks.games/engine.insurgency.txt b/gamedata/sdkhooks.games/engine.insurgency.txt index 1f67f9d3..92008cea 100644 --- a/gamedata/sdkhooks.games/engine.insurgency.txt +++ b/gamedata/sdkhooks.games/engine.insurgency.txt @@ -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" diff --git a/gamedata/sdkhooks.games/engine.l4d.txt b/gamedata/sdkhooks.games/engine.l4d.txt index 97f6da37..abe3ea9d 100644 --- a/gamedata/sdkhooks.games/engine.l4d.txt +++ b/gamedata/sdkhooks.games/engine.l4d.txt @@ -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" diff --git a/gamedata/sdkhooks.games/game.cstrike.txt b/gamedata/sdkhooks.games/game.cstrike.txt index 93f386f0..06707425 100644 --- a/gamedata/sdkhooks.games/game.cstrike.txt +++ b/gamedata/sdkhooks.games/game.cstrike.txt @@ -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" diff --git a/gamedata/sdkhooks.games/game.fof.txt b/gamedata/sdkhooks.games/game.fof.txt index be2cf534..b98682f5 100644 --- a/gamedata/sdkhooks.games/game.fof.txt +++ b/gamedata/sdkhooks.games/game.fof.txt @@ -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" diff --git a/gamedata/sdkhooks.games/game.l4d2.txt b/gamedata/sdkhooks.games/game.l4d2.txt index 46395471..e64604eb 100644 --- a/gamedata/sdkhooks.games/game.l4d2.txt +++ b/gamedata/sdkhooks.games/game.l4d2.txt @@ -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" diff --git a/gamedata/sdkhooks.games/game.nmrih.txt b/gamedata/sdkhooks.games/game.nmrih.txt index 4eedd98b..e2e98198 100644 --- a/gamedata/sdkhooks.games/game.nmrih.txt +++ b/gamedata/sdkhooks.games/game.nmrih.txt @@ -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" diff --git a/gamedata/sdkhooks.games/game.nucleardawn.txt b/gamedata/sdkhooks.games/game.nucleardawn.txt index a5432dd0..b95980b8 100644 --- a/gamedata/sdkhooks.games/game.nucleardawn.txt +++ b/gamedata/sdkhooks.games/game.nucleardawn.txt @@ -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" From 448c55c0f22b58d1faa05629a87c1479403429a8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:11:17 -0700 Subject: [PATCH 32/42] Fix DBI after AMTL changes. --- extensions/mysql/mysql/MyDatabase.cpp | 3 +++ extensions/sqlite/driver/SqDatabase.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/extensions/mysql/mysql/MyDatabase.cpp b/extensions/mysql/mysql/MyDatabase.cpp index 74825bfb..84f34537 100644 --- a/extensions/mysql/mysql/MyDatabase.cpp +++ b/extensions/mysql/mysql/MyDatabase.cpp @@ -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() diff --git a/extensions/sqlite/driver/SqDatabase.cpp b/extensions/sqlite/driver/SqDatabase.cpp index 91811aa5..e0f13e80 100644 --- a/extensions/sqlite/driver/SqDatabase.cpp +++ b/extensions/sqlite/driver/SqDatabase.cpp @@ -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() From e608057304d2e4dec1a616a3af78d3755cc79119 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:31:06 -0700 Subject: [PATCH 33/42] Sync a change from AMTL. --- public/amtl/am-refcounting.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/public/amtl/am-refcounting.h b/public/amtl/am-refcounting.h index 028d6df5..ea869464 100644 --- a/public/amtl/am-refcounting.h +++ b/public/amtl/am-refcounting.h @@ -55,6 +55,13 @@ class AlreadyRefed : thing_(t) { } + AlreadyRefed(const AlreadyRefed &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(); From 105cd27d191982959fde9e1d622db6a74864b9b6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:40:03 -0700 Subject: [PATCH 34/42] Sync am-utility.h from upstream. --- public/amtl/am-utility.h | 57 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/public/amtl/am-utility.h b/public/amtl/am-utility.h index 474c0052..579d932c 100644 --- a/public/amtl/am-utility.h +++ b/public/amtl/am-utility.h @@ -89,7 +89,7 @@ class AutoPtr : t_(NULL) { } - AutoPtr(T *t) + explicit AutoPtr(T *t) : t_(t) { } @@ -339,10 +339,65 @@ class StorageBuffer }; }; +template +class SaveAndSet +{ + public: + SaveAndSet(T *location, const T &value) + : location_(location), + old_(*location) + { + *location_ = value; + } + ~SaveAndSet() { + *location_ = old_; + } + + private: + T *location_; + T old_; +}; + +template +class StackLinked +{ + public: + StackLinked(T **prevp) + : prevp_(prevp), + prev_(*prevp) + { + *prevp_ = static_cast(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 From 6068d341c83f0829697ed1b2ba393cbf6bd13417 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:44:51 -0700 Subject: [PATCH 35/42] Sync am-hashmap. --- public/amtl/am-hashmap.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/public/amtl/am-hashmap.h b/public/amtl/am-hashmap.h index 9a2d1ee6..7d5c3839 100644 --- a/public/amtl/am-hashmap.h +++ b/public/amtl/am-hashmap.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 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 value) { - return table_.add(i, Entry(key, value)); + Entry entry(key, value); + return table_.add(i, ke::Move(entry)); } bool add(Insert &i, Moveable key, Moveable value) { - return table_.add(i, Entry(key, value)); + Entry entry(key, value); + return table_.add(i, ke::Move(entry)); } bool add(Insert &i, Moveable 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 From e6e90fb8b837bef8a7141d1d61cb42d1e2774cc5 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:45:44 -0700 Subject: [PATCH 36/42] Sync am-string. --- public/amtl/am-string.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/amtl/am-string.h b/public/amtl/am-string.h index 074339fa..4e62bde2 100644 --- a/public/amtl/am-string.h +++ b/public/amtl/am-string.h @@ -56,7 +56,7 @@ class AString if (other.length_) set(other.chars_, other.length_); else - length_ = 0; + length_ = 0; } AString(Moveable 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; From 8686957dee9404f18ac620fff313a3a423cc82c6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 21:48:48 -0700 Subject: [PATCH 37/42] Final sync of AMTL. --- public/amtl/am-fixedarray.h | 99 ++++++++++++++++++++ public/amtl/am-threadlocal.h | 175 +++++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 public/amtl/am-fixedarray.h create mode 100644 public/amtl/am-threadlocal.h diff --git a/public/amtl/am-fixedarray.h b/public/amtl/am-fixedarray.h new file mode 100644 index 00000000..4681651d --- /dev/null +++ b/public/amtl/am-fixedarray.h @@ -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 +#include +#include + +namespace ke { + +template +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) { + 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_ diff --git a/public/amtl/am-threadlocal.h b/public/amtl/am-threadlocal.h new file mode 100644 index 00000000..df4c023c --- /dev/null +++ b/public/amtl/am-threadlocal.h @@ -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 + +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, 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 +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(TlsGetValue(key_)); + } + void internalSet(const T &t) { + TlsSetValue(key_, reinterpret_cast(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(pthread_getspecific(key_)); + } + void internalSet(const T &t) { + pthread_setspecific(key_, reinterpret_cast(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_ From a00adaf9fbd77fcf277ef356237fe45b266cba68 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 22:05:10 -0700 Subject: [PATCH 38/42] Sync with AMTL one last time. --- core/sm_stringutil.cpp | 1 + public/amtl/am-float.h | 50 ++++++++++++++++++++++++++++++++++++++++ public/amtl/am-utility.h | 12 ---------- 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 public/amtl/am-float.h diff --git a/core/sm_stringutil.cpp b/core/sm_stringutil.cpp index 86ada852..6babf358 100644 --- a/core/sm_stringutil.cpp +++ b/core/sm_stringutil.cpp @@ -39,6 +39,7 @@ #include "logic_bridge.h" #include "sourcemod.h" #include +#include #define LADJUST 0x00000004 /* left adjustment */ #define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */ diff --git a/public/amtl/am-float.h b/public/amtl/am-float.h new file mode 100644 index 00000000..e53f25a0 --- /dev/null +++ b/public/amtl/am-float.h @@ -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 +#include + +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_ diff --git a/public/amtl/am-utility.h b/public/amtl/am-utility.h index 579d932c..1e31e067 100644 --- a/public/amtl/am-utility.h +++ b/public/amtl/am-utility.h @@ -34,8 +34,6 @@ #include #include #include -#include -#include #if defined(_MSC_VER) # include #endif @@ -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) { From a1dc1101f762044e05e4d5bf8402c9e956525d3b Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 3 Sep 2014 22:33:05 -0700 Subject: [PATCH 39/42] Fix build. --- core/logic/smn_float.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/logic/smn_float.cpp b/core/logic/smn_float.cpp index 73c95f8e..784de670 100644 --- a/core/logic/smn_float.cpp +++ b/core/logic/smn_float.cpp @@ -36,6 +36,7 @@ #include "MersenneTwister.h" #include #include +#include /**************************************** * * From 37638ba6fd1e24416cfcdda01611ba8c94d2bcef Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 24 Aug 2014 18:59:51 -0700 Subject: [PATCH 40/42] Remove support for multiple tags on an argument. --- plugins/admin-flatfile/admin-flatfile.sp | 2 +- sourcepawn/compiler/sc1.cpp | 2 ++ sourcepawn/compiler/sc5-in.scp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/admin-flatfile/admin-flatfile.sp b/plugins/admin-flatfile/admin-flatfile.sp index 250ebb24..12f06711 100644 --- a/plugins/admin-flatfile/admin-flatfile.sp +++ b/plugins/admin-flatfile/admin-flatfile.sp @@ -70,7 +70,7 @@ public OnRebuildAdminCache(AdminCachePart:part) } } -ParseError(const String:format[], {Handle,String,Float,_}:...) +ParseError(const String:format[], any:...) { decl String:buffer[512]; diff --git a/sourcepawn/compiler/sc1.cpp b/sourcepawn/compiler/sc1.cpp index 86fe6936..998b3b29 100644 --- a/sourcepawn/compiler/sc1.cpp +++ b/sourcepawn/compiler/sc1.cpp @@ -3235,6 +3235,8 @@ static int parse_old_decl(declinfo_t *decl, int flags) } needtoken(':'); } + if (type->numtags > 1) + error(158); } if (type->numtags == 0) { diff --git a/sourcepawn/compiler/sc5-in.scp b/sourcepawn/compiler/sc5-in.scp index 0478abb2..f7ec5a24 100644 --- a/sourcepawn/compiler/sc5-in.scp +++ b/sourcepawn/compiler/sc5-in.scp @@ -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", From 7fff73ad64fed47d8dbb6607a15f094dbbf5b59c Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 5 Sep 2014 08:18:04 -0400 Subject: [PATCH 41/42] Fix syntax error in sdkhooks.inc. --- plugins/include/sdkhooks.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index f3129892..9eea0ba4 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -253,7 +253,7 @@ union SDKHookCB // 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+ - function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype), + function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype); // SDKHooks 2.0+ function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float[3] damageForce, float[3] damagePosition); // SDKHooks 2.1+ (can check for support at runtime using GetFeatureStatus on SDKHook_DmgCustomInOTD capability. From 07acec6550b0acee2ea6fb3f6416447d3403a752 Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Sat, 6 Sep 2014 20:19:55 -0500 Subject: [PATCH 42/42] Fix sdkhooks.inc compile error --- plugins/include/sdkhooks.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index 9eea0ba4..65756e06 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -255,16 +255,16 @@ union SDKHookCB // SDKHooks 1.0+ function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype); // SDKHooks 2.0+ - function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float[3] damageForce, float[3] damagePosition); + 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 function Action (int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, - float[3] damageForce, float[3] damagePosition, int damagecustom); + float damageForce[3], float damagePosition[3], int damagecustom); // OnTakeDamagePost // 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[3] damageForce, const float[3] damagePosition); + function void (int victim, int attacker, int inflictor, float damage, int damagetype, const float damageForce[3], const float damagePosition[3]); // FireBulletsPost function void (int client, int shots, const char[] weaponname);