From 9e4c02b58765692e6d14c945787fabb802dc8403 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Fri, 8 Jan 2016 20:09:39 +0600 Subject: [PATCH] Cleanup. Fix 'Bad file data' --- engine/consistency.h | 49 +++++++++++++++ engine/rehlds_api.h | 20 +++++- engine/rehlds_interfaces.h | 8 +++ src/cmdexec.cpp | 4 +- src/dllapi.cpp | 2 +- src/meta_api.cpp | 2 +- src/precompiled.h | 2 + src/resource.cpp | 121 +++++++++++++++++++++---------------- src/resource.h | 6 +- 9 files changed, 154 insertions(+), 60 deletions(-) create mode 100644 engine/consistency.h diff --git a/engine/consistency.h b/engine/consistency.h new file mode 100644 index 0000000..a89a0d0 --- /dev/null +++ b/engine/consistency.h @@ -0,0 +1,49 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#ifndef CONSISTENCY_H +#define CONSISTENCY_H +#ifdef _WIN32 +#pragma once +#endif + +#define MAX_CONSISTENCY_LIST 512 + +/* <7508> ../engine/consistency.h:9 */ +typedef struct consistency_s +{ + char * filename; + int issound; + int orig_index; + int value; + int check_type; + float mins[3]; + float maxs[3]; +} consistency_t; + +#endif // CONSISTENCY_H \ No newline at end of file diff --git a/engine/rehlds_api.h b/engine/rehlds_api.h index 238ca36..ee8ac26 100644 --- a/engine/rehlds_api.h +++ b/engine/rehlds_api.h @@ -35,7 +35,7 @@ #include "model.h" #define REHLDS_API_VERSION_MAJOR 2 -#define REHLDS_API_VERSION_MINOR 2 +#define REHLDS_API_VERSION_MINOR 5 //Steam_NotifyClientConnect hook typedef IHookChain IRehldsHook_Steam_NotifyClientConnect; @@ -153,6 +153,14 @@ typedef IVoidHookChainRegistry IRehldsHookRegis typedef IVoidHookChain IRehldsHook_SV_ActivateServer; typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_ActivateServer; +//SV_WriteVoiceCodec hook +typedef IVoidHookChain IRehldsHook_SV_WriteVoiceCodec; +typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_WriteVoiceCodec; + +//Steam_GSGetSteamID hook +typedef IHookChain IRehldsHook_Steam_GSGetSteamID; +typedef IHookChainRegistry IRehldsHookRegistry_Steam_GSGetSteamID; + class IRehldsHookchains { public: virtual ~IRehldsHookchains() { } @@ -186,6 +194,8 @@ public: virtual IRehldsHookRegistry_SV_CheckConsistencyResponse* SV_CheckConsistencyResponse() = 0; virtual IRehldsHookRegistry_SV_DropClient* SV_DropClient() = 0; virtual IRehldsHookRegistry_SV_ActivateServer* SV_ActivateServer() = 0; + virtual IRehldsHookRegistry_SV_WriteVoiceCodec* SV_WriteVoiceCodec() = 0; + virtual IRehldsHookRegistry_Steam_GSGetSteamID* Steam_GSGetSteamID() = 0; }; struct RehldsFuncs_t { @@ -222,6 +232,14 @@ struct RehldsFuncs_t { cvar_t*(*GetCvarVars)(); int (*SV_GetChallenge)(const netadr_t& adr); void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index); + int(*MSG_ReadShort)(void); + int(*MSG_ReadBuf)(int iSize, void *pbuf); + void(*MSG_WriteBuf)(sizebuf_t *sb, int iSize, void *buf); + void(*MSG_WriteByte)(sizebuf_t *sb, int c); + void(*MSG_WriteShort)(sizebuf_t *sb, int c); + void(*MSG_WriteString)(sizebuf_t *sb, const char *s); + void*(*GetPluginApi)(const char *name); + void(*RegisterPluginApi)(const char *name, void *impl); }; class IRehldsApi { diff --git a/engine/rehlds_interfaces.h b/engine/rehlds_interfaces.h index 501be86..0a47112 100644 --- a/engine/rehlds_interfaces.h +++ b/engine/rehlds_interfaces.h @@ -67,6 +67,10 @@ public: virtual bool IsConnected() = 0; virtual void SetConnected(bool connected) = 0; + virtual uint32 GetVoiceStream(int stream_id) = 0; + virtual void SetLastVoiceTime(double time) = 0; + virtual double GetLastVoiceTime() = 0; + virtual bool GetLoopback() = 0; // this must be the last virtual function in class #ifdef REHLDS_SELF @@ -117,4 +121,8 @@ public: virtual int GetConsistencyNum() = 0; virtual int GetResourcesNum() = 0; virtual int GetDecalNameNum() = 0; + + virtual double GetTime() = 0; + virtual void SetResourcesNum(int num) = 0; + virtual struct resource_s *GetResource(int index) = 0; }; diff --git a/src/cmdexec.cpp b/src/cmdexec.cpp index 3b516e9..b21c27d 100644 --- a/src/cmdexec.cpp +++ b/src/cmdexec.cpp @@ -37,8 +37,6 @@ void StringReplace(char *src, const char *strold, const char *strnew) } } -extern uint32 swap_endian(uint32 value); - char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32 responseHash) { int len; @@ -57,7 +55,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32 // replace key values StringReplace(string, "[file_name]", pResource->GetFileName()); StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", responseHash)); - StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", swap_endian(responseHash))); + StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", _byteswap_ulong(responseHash))); // replace of templates for identification StringReplace(string, "[userid]", UTIL_VarArgs("#%u", g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict()))); diff --git a/src/dllapi.cpp b/src/dllapi.cpp index 133e299..8be2e91 100644 --- a/src/dllapi.cpp +++ b/src/dllapi.cpp @@ -27,7 +27,7 @@ static DLL_FUNCTIONS gFunctionTable = NULL, // pfnResetGlobalState NULL, // pfnClientConnect - NULL, // pfnClientDisconnect + NULL, // pfnClientDisconnect NULL, // pfnClientKill NULL, // pfnClientPutInServer NULL, // pfnClientCommand diff --git a/src/meta_api.cpp b/src/meta_api.cpp index 1ab1260..523f72e 100644 --- a/src/meta_api.cpp +++ b/src/meta_api.cpp @@ -4,7 +4,7 @@ plugin_info_t Plugin_info = { META_INTERFACE_VERSION, "Rechecker", - "1.2", + "1.3", __DATE__, "s1lent", "http://www.dedicated-server.ru/", diff --git a/src/precompiled.h b/src/precompiled.h index ce88f90..88204a3 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -14,6 +14,7 @@ #include #include #include // strrchr +#include // std::sort #include // time, localtime etc #include @@ -24,6 +25,7 @@ #include "rehlds_api.h" #include "engine_rehlds.h" +#include "consistency.h" #include "main.h" //#include "task.h" diff --git a/src/resource.cpp b/src/resource.cpp index a59b83f..bc1cc0b 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -9,7 +9,7 @@ cvar_t *pcv_rch_log = NULL; void CResourceFile::CreateResourceList() { int nConsistency = g_RehldsServerData->GetConsistencyNum(); - m_DecalsNum = g_RehldsServerData->GetDecalNameNum(); + /*m_DecalsNum = g_RehldsServerData->GetDecalNameNum();*/ for (auto iter = m_resourceList.cbegin(), end = m_resourceList.cend(); iter != end; ++iter) { @@ -26,14 +26,52 @@ void CResourceFile::CreateResourceList() break; } + // check limit consistency + if (nConsistency >= MAX_CONSISTENCY_LIST) + { + UTIL_Printf(__FUNCTION__ ": can't add consistency \"%s\" on line %d; exceeded the limit of consistency max '%d'\n", pRes->GetFileName(), pRes->GetLine(), MAX_CONSISTENCY_LIST); + break; + } + Log(__FUNCTION__ " -> file: (%s), cmdexc: (%s), hash: (%x)", pRes->GetFileName(), pRes->GetCmdExec(), pRes->GetFileHash()); - SV_AddResource(t_decal, pRes->GetFileName(), 0, RES_CHECKFILE, m_DecalsNum++); + SV_AddResource(t_decal, pRes->GetFileName(), 0, RES_CHECKFILE, 4095/*m_DecalsNum++*/); nConsistency++; } } - m_DecalsNum = g_RehldsServerData->GetDecalNameNum(); + /*m_DecalsNum = g_RehldsServerData->GetDecalNameNum();*/ g_RehldsServerData->SetConsistencyNum(nConsistency); + + // sort + std::vector sortList; + + for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); ++i) + { + resource_t *r = g_RehldsServerData->GetResource(i); + sortList.push_back(new resource_t(*r)); + } + + // Start a first resource list + g_RehldsServerData->SetResourcesNum(0); + + class SortFiles + { + public: + bool operator()(const resource_t *a, const resource_t *b) const + { + return (a->ucFlags & RES_CHECKFILE) != 0; + } + }; + + // sort by flag RES_CHECKFILE + std::sort(sortList.begin(), sortList.end(), SortFiles()); + + for (auto iter = sortList.cbegin(), end = sortList.cend(); iter != end; ++iter) + { + // Add new resource in the own order + resource_t *r = (*iter); + SV_AddResource(r->type, r->szFileName, r->nDownloadSize, r->ucFlags, r->nIndex); + } } void CResourceFile::Clear(IGameClient *pClient) @@ -43,7 +81,7 @@ void CResourceFile::Clear(IGameClient *pClient) auto iter = m_responseList.begin(); while (iter != m_responseList.end()) { - ResponseBuffer *pFiles = (*iter); + CResponseBuffer *pFiles = (*iter); if (pFiles->GetGameClient() != pClient) { @@ -61,10 +99,11 @@ void CResourceFile::Clear(IGameClient *pClient) } m_PrevHash = 0; - m_DecalsNum = 0; + /*m_DecalsNum = 0;*/ // clear resources m_resourceList.clear(); + m_responseList.clear(); ClearStringsCache(); } @@ -159,16 +198,6 @@ void CResourceFile::Init() pcv_rch_log = g_engfuncs.pfnCVarGetPointer(cv_rch_log.name); } -uint32 __declspec(naked) swap_endian(uint32 value) -{ - __asm - { - mov eax, dword ptr[esp + 4] - bswap eax - ret - } -} - inline uint8 hexbyte(uint8 *hex) { return ((hex[0] > '9' ? toupper(hex[0]) - 'A' + 10 : hex[0] - '0') << 4) @@ -300,12 +329,16 @@ void CResourceFile::LoadResources() { flag = FLAG_TYPE_HASH_ANY; } + else if (_stricmp((const char *)pbuf, "MISSING") == 0) + { + flag = FLAG_TYPE_MISSING; + } else { for (int i = 0; i < sizeof(pbuf) / 2; i++) hash[i] = hexbyte(&pbuf[i * 2]); - flag = (*(uint32 *)&hash[0] != 0x00000000) ? FLAG_TYPE_EXISTS : FLAG_TYPE_MISSING; + flag = FLAG_TYPE_EXISTS; } break; } @@ -357,40 +390,39 @@ void CResourceFile::LoadResources() } } + #define LOG_PRINT_FAILED(str, argv)\ + UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; " str, argv);\ + continue; + if (argc >= MAX_PARSE_ARGUMENT) { char pchar; if (strlen(filename) <= 0) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; path to filename is empty on line %d\n", cline); - continue; + LOG_PRINT_FAILED("path to filename is empty on line %d\n", cline); } else if (!IsFileHasExtension(filename)) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; filename has no extension on line %d\n", cline); - continue; + LOG_PRINT_FAILED("filename has no extension on line %d\n", cline); } else if (!IsValidFilename(filename, pchar)) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; filename has invalid character '%c' on line %d\n", pchar, cline); - continue; + LOG_PRINT_FAILED("filename has invalid character '%c' on line %d\n", (pchar, cline)); } else if (flag == FLAG_TYPE_NONE) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing hash failed on line %d\n", cline); - continue; + LOG_PRINT_FAILED("parsing hash failed on line %d\n", cline); } else if (strlen(cmdBufExec) <= 0 && (flag != FLAG_TYPE_IGNORE && !bBreak)) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing command line is empty on line %d\n", cline); - continue; + LOG_PRINT_FAILED("parsing command line is empty on line %d\n", cline); } AddElement(filename, cmdBufExec, flag, *(uint32 *)&hash[0], cline, bBreak); } else if (pToken != NULL || argc > ARG_TYPE_FILE_NAME) { - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing not enough arguments on line %d (got '%d', expected '%d')\n", cline, argc, MAX_PARSE_ARGUMENT); + LOG_PRINT_FAILED("parsing not enough arguments on line %d (got '%d', expected '%d')\n", (cline, argc, MAX_PARSE_ARGUMENT)); } } @@ -470,7 +502,7 @@ void CResourceFile::AddElement(char *filename, char *cmdExec, flag_type_resource for (auto iter = m_resourceList.cbegin(), end = m_resourceList.cend(); iter != end; ++iter) { CResourceBuffer *pRes = (*iter); - + if (_stricmp(pRes->GetFileName(), filename) == 0) { // resource name already registered @@ -484,7 +516,7 @@ void CResourceFile::AddElement(char *filename, char *cmdExec, flag_type_resource void CResourceFile::AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash) { - m_responseList.push_back(new ResponseBuffer(pSenderClient, filename, hash)); + m_responseList.push_back(new CResponseBuffer(pSenderClient, filename, hash)); } bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource_t *resource, uint32 hash) @@ -492,12 +524,10 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource bool bHandled = false; flag_type_resources typeFind; std::vector tempResourceList; - const char *hashFoundFile; - const char *prevHashFoundFile; if (resource->type != t_decal - || resource->nIndex < m_DecalsNum) // if by some miracle the decals will have the flag RES_CHECKFILE - // to be sure not bypass the decals + || resource->nIndex != 4095/*< m_DecalsNum*/) // if by some miracle the decals will have the flag RES_CHECKFILE + // to be sure not bypass the decals { AddFileResponse(pSenderClient, resource->szFileName, hash); m_PrevHash = hash; @@ -562,22 +592,12 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource if (typeFind != FLAG_TYPE_NONE) { - if (hash != 0x0) - { - // push exec cmd - Exec.AddElement(pSenderClient, pRes, hash); - } + // push exec cmd + Exec.AddElement(pSenderClient, pRes, hash); - hashFoundFile = FindFilenameOfHash(hash); - prevHashFoundFile = FindFilenameOfHash(m_PrevHash); - - if (prevHashFoundFile == NULL) - prevHashFoundFile = "null"; - - if (hashFoundFile == NULL) - hashFoundFile = "null"; - - Log(" -> file: (%s), exphash: (%x), got: (%x), typeFind: (%d), prevhash: (%x), (%s), prevfiles: (%s), findathash: (%s), md5hex: (%x)", pRes->GetFileName(), pRes->GetFileHash(), hash, typeFind, m_PrevHash, pSenderClient->GetName(), prevHashFoundFile, hashFoundFile, swap_endian(hash)); + Log(" -> file: (%s), exphash: (%x), got: (%x), typeFind: (%d), prevhash: (%x), (%s), prevfile: (%s), findathash: (%s), md5hex: (%x)", + pRes->GetFileName(), pRes->GetFileHash(), hash, typeFind, m_PrevHash, pSenderClient->GetName(), + FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash)); } bHandled = true; @@ -622,7 +642,7 @@ CResourceBuffer::CResourceBuffer(char *filename, char *cmdExec, flag_type_resour m_Break = bBreak; } -CResourceFile::ResponseBuffer::ResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash) +CResourceFile::CResponseBuffer::CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash) { m_pClient = pSenderClient; m_FileName = DuplicateString(filename); @@ -637,6 +657,5 @@ const char *CResourceFile::FindFilenameOfHash(uint32 hash) return (*iter)->GetFileName(); } - return NULL; + return "null"; } - diff --git a/src/resource.h b/src/resource.h index dcac538..68621e8 100644 --- a/src/resource.h +++ b/src/resource.h @@ -65,10 +65,10 @@ public: private: // buffer for response list - class ResponseBuffer + class CResponseBuffer { public: - ResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash); + CResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash); IGameClient *GetGameClient() const { return m_pClient; }; const char *GetFileName() const { return m_FileName; }; @@ -92,7 +92,7 @@ private: private: typedef std::vector ResourceList; - typedef std::vector ResponseList; + typedef std::vector ResponseList; ResourceList m_resourceList; ResponseList m_responseList;