diff --git a/engine/rehlds_api.h b/engine/rehlds_api.h index 14280f3..238ca36 100644 --- a/engine/rehlds_api.h +++ b/engine/rehlds_api.h @@ -141,9 +141,9 @@ typedef IVoidHookChainRegistry IRehldsHook_SV_WriteFullClientUpdate; typedef IVoidHookChainRegistry IRehldsHookRegistry_SV_WriteFullClientUpdate; -//SV_CheckConsistencyResponce hook -typedef IHookChain IRehldsHook_SV_CheckConsistencyResponce; -typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckConsistencyResponce; +//SV_CheckConsistencyResponse hook +typedef IHookChain IRehldsHook_SV_CheckConsistencyResponse; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckConsistencyResponse; //SV_DropClient hook typedef IVoidHookChain IRehldsHook_SV_DropClient; @@ -183,7 +183,7 @@ public: virtual IRehldsHookRegistry_PF_Remove_I* PF_Remove_I() = 0; virtual IRehldsHookRegistry_PF_BuildSoundMsg_I* PF_BuildSoundMsg_I() = 0; virtual IRehldsHookRegistry_SV_WriteFullClientUpdate* SV_WriteFullClientUpdate() = 0; - virtual IRehldsHookRegistry_SV_CheckConsistencyResponce* SV_CheckConsistencyResponce() = 0; + virtual IRehldsHookRegistry_SV_CheckConsistencyResponse* SV_CheckConsistencyResponse() = 0; virtual IRehldsHookRegistry_SV_DropClient* SV_DropClient() = 0; virtual IRehldsHookRegistry_SV_ActivateServer* SV_ActivateServer() = 0; }; diff --git a/src/cmdexec.cpp b/src/cmdexec.cpp index f88f39e..9c4f58d 100644 --- a/src/cmdexec.cpp +++ b/src/cmdexec.cpp @@ -62,6 +62,11 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32 StringReplace(string, "[ip]", UTIL_VarArgs("%i.%i.%i.%i", net->ip[0], net->ip[1], net->ip[2], net->ip[3])); StringReplace(string, "[name]", pClient->GetName()); + if (string != NULL && string[0] != '\0') + { + Resource.Log(" -> ExecuteCMD: (%s), for (%s)", string, pClient->GetName()); + } + len = strlen(string); if (len < sizeof(string) - 2) @@ -96,15 +101,16 @@ void CExecMngr::CommandExecute(IGameClient *pClient) break; } - char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash()); - - if (!bBreak // erase all cmdexec because have flag is break - && cmdExec != NULL && cmdExec[0] != '\0') + // erase all cmdexec because have flag is break + if (!bBreak) { - Resource.Log(" -> ExecuteCMD: (%s), for (%s)", cmdExec, pClient->GetName()); + char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash()); - // execute cmdexec - SERVER_COMMAND(cmdExec); + if (cmdExec != NULL && cmdExec[0] != '\0') + { + // execute cmdexec + SERVER_COMMAND(cmdExec); + } } // erase cmdexec diff --git a/src/main.cpp b/src/main.cpp index eb77399..9eaa277 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,7 +44,7 @@ bool OnMetaAttach() // register function from ReHLDS API g_RehldsApi->GetHookchains()->SV_DropClient()->registerHook(&SV_DropClient); g_RehldsApi->GetHookchains()->SV_ActivateServer()->registerHook(&SV_ActivateServer); - g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponce()->registerHook(&SV_CheckConsistencyResponce); + g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse); SV_AddResource = g_RehldsApi->GetFuncs()->SV_AddResource; @@ -81,7 +81,7 @@ void OnMetaDetach() g_RehldsApi->GetHookchains()->SV_DropClient()->unregisterHook(&SV_DropClient); g_RehldsApi->GetHookchains()->SV_ActivateServer()->unregisterHook(&SV_ActivateServer); - g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponce()->unregisterHook(&SV_CheckConsistencyResponce); + g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponse()->unregisterHook(&SV_CheckConsistencyResponse); } void ServerDeactivate_Post() @@ -98,6 +98,9 @@ void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool // clear buffer cmdexec the client when was disconnected up to perform cmdexec Exec.Clear(pClient); + // clear temporary files of response + Resource.Clear(pClient); + // call next hook chain->callNext(pClient, crash, string); } @@ -123,12 +126,16 @@ void ClientPutInServer_Post(edict_t *pEntity) // client is connected to putinserver, go execute cmd out buffer Exec.CommandExecute(pClient); + + // clear temporary files of response + Resource.Clear(pClient); + SET_META_RESULT(MRES_IGNORED); } -bool SV_CheckConsistencyResponce(IRehldsHook_SV_CheckConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash) +bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash) { - if (!Resource.FileConsistencyResponce(pSenderClient, resource, hash)) + if (!Resource.FileConsistencyResponse(pSenderClient, resource, hash)) return false; // call next hook and take return of values from original func diff --git a/src/main.h b/src/main.h index c302874..b55f846 100644 --- a/src/main.h +++ b/src/main.h @@ -2,11 +2,6 @@ void SV_ActivateServer(IRehldsHook_SV_ActivateServer *chain, int runPhysics); void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string); -bool SV_CheckConsistencyResponce(IRehldsHook_SV_CheckConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash); - -/* -void StartFrame(); -extern DLL_FUNCTIONS *g_pFunctionTable; -*/ +bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash); extern void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index); diff --git a/src/meta_api.cpp b/src/meta_api.cpp index f45ff63..7c390f5 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.0", + "1.1", __DATE__, "s1lent", "http://www.dedicated-server.ru/", diff --git a/src/precompiled.h b/src/precompiled.h index e9f2f32..ce88f90 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -4,6 +4,7 @@ #pragma warning(disable : 4005) #else #define _stricmp strcasecmp + #define _mkdir mkdir // Deail with stupid macro in kernel.h #undef __FUNCTION__ #endif // _WIN32 diff --git a/src/resource.cpp b/src/resource.cpp index cdd0144..670e35e 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -36,8 +36,30 @@ void CResourceFile::CreateResourceList() g_RehldsServerData->SetConsistencyNum(nConsistency); } -void CResourceFile::Clear() +void CResourceFile::Clear(IGameClient *pClient) { + if (pClient != NULL) + { + auto iter = m_responseList.begin(); + while (iter != m_responseList.end()) + { + ResponseBuffer *pFiles = (*iter); + + if (pFiles->GetGameClient() != pClient) + { + iter++; + continue; + } + + // erase cmdexec + delete pFiles; + iter = m_responseList.erase(iter); + } + + m_PrevHash = 0; + return; + } + m_PrevHash = 0; m_DecalsNum = 0; @@ -49,15 +71,18 @@ void CResourceFile::Clear() void CResourceFile::Log(const char *fmt, ...) { - if (pcv_rch_log->string[0] != '1') - return; - static char string[2048]; FILE *fp; + time_t td; + tm *lt; char *file; + char dateLog[64]; bool bFirst = false; + if (pcv_rch_log->string[0] != '1') + return; + fp = fopen(m_LogFilePath, "r"); if (fp != NULL) @@ -79,16 +104,22 @@ void CResourceFile::Log(const char *fmt, ...) va_end(argptr); strcat(string, "\n"); + + td = time(NULL); + lt = localtime(&td); + + strftime(dateLog, sizeof(dateLog), "%m/%d/%Y - %H:%M:%S", lt); + if (!bFirst) { file = strrchr(m_LogFilePath, '/'); if (file == NULL) - file = "null"; + file = ""; - fprintf(fp, "L %s: Log file started (file \"%s\") (version \"%s\")\n", m_LogDate, file, Plugin_info.version); + fprintf(fp, "L %s: Log file started (file \"%s\") (version \"%s\")\n", dateLog, file, Plugin_info.version); } - fprintf(fp, "L %s: %s", m_LogDate, string); + fprintf(fp, "L %s: %s", dateLog, string); fclose(fp); } @@ -194,7 +225,6 @@ void CResourceFile::LogPrepare() } strftime(dateFile, sizeof(dateFile), "L_%d_%m_%Y.log", lt); - strftime(m_LogDate, sizeof(m_LogDate), "%m/%d/%Y - %H:%M:%S", lt); strcat(m_LogFilePath, dateFile); } @@ -338,7 +368,6 @@ void CResourceFile::LoadResources() UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing hash failed on line %d\n", cline); continue; } - // TODO: is there a need to flag FLAG_TYPE_BREAK without cmdexec? else if (strlen(cmdBufExec) <= 0 && (flag != FLAG_TYPE_IGNORE && flag != FLAG_TYPE_BREAK)) { UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing command line is empty on line %d\n", cline); @@ -441,12 +470,24 @@ void CResourceFile::AddElement(char *filename, char *cmdExec, flag_type_resource m_resourceList.push_back(nRes); } -bool CResourceFile::FileConsistencyResponce(IGameClient *pSenderClient, resource_t *resource, uint32 hash) +void CResourceFile::AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash) { + m_responseList.push_back(new ResponseBuffer(pSenderClient, filename, hash)); +} + +bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource_t *resource, uint32 hash) +{ + 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 { + AddFileResponse(pSenderClient, resource->szFileName, hash); m_PrevHash = hash; return true; } @@ -458,10 +499,6 @@ bool CResourceFile::FileConsistencyResponce(IGameClient *pSenderClient, resource return true; } - bool bHandled = false; - flag_type_resources typeFind; - std::vector tempResourceList; - for (auto iter = m_resourceList.cbegin(), end = m_resourceList.cend(); iter != end; ++iter) { CResourceBuffer *pRes = (*iter); @@ -516,13 +553,22 @@ bool CResourceFile::FileConsistencyResponce(IGameClient *pSenderClient, resource if (typeFind != FLAG_TYPE_NONE) { - // TODO: what is? if (hash != 0x0) { // push exec cmd Exec.AddElement(pSenderClient, pRes, hash); } - Log(" -> file: (%s), exphash: (%x), got: (%x), typeFind: (%d), prevhash: (%x), (%s)", pRes->GetFileName(), pRes->GetFileHash(), hash, typeFind, m_PrevHash, pSenderClient->GetName()); + + 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)", pRes->GetFileName(), pRes->GetFileHash(), hash, typeFind, m_PrevHash, pSenderClient->GetName(), prevHashFoundFile, hashFoundFile); } bHandled = true; @@ -564,3 +610,22 @@ CResourceBuffer::CResourceBuffer(char *filename, char *cmdExec, flag_type_resour m_FileHash = hash; m_Line = line; } + +CResourceFile::ResponseBuffer::ResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash) +{ + m_pClient = pSenderClient; + m_FileName = DuplicateString(filename); + m_ClientHash = hash; +} + +const char *CResourceFile::FindFilenameOfHash(uint32 hash) +{ + for (auto iter = m_responseList.begin(), end = m_responseList.end(); iter != end; ++iter) + { + if ((*iter)->GetClientHash() == hash) + return (*iter)->GetFileName(); + } + + return NULL; +} + diff --git a/src/resource.h b/src/resource.h index 9dafea3..57d5c74 100644 --- a/src/resource.h +++ b/src/resource.h @@ -25,6 +25,7 @@ enum arg_type_e MAX_PARSE_ARGUMENT, }; +// buffer for checker list class CResourceBuffer { public: @@ -55,15 +56,35 @@ class CResourceFile { public: void Init(); - void Clear(); + void Clear(IGameClient *pClient = NULL); void LoadResources(); void CreateResourceList(); void Log(const char *fmt, ...); - bool FileConsistencyResponce(IGameClient *pSenderClient, resource_t *resource, uint32 hash); + bool FileConsistencyResponse(IGameClient *pSenderClient, resource_t *resource, uint32 hash); private: + // buffer for response list + class ResponseBuffer + { + public: + ResponseBuffer(IGameClient *pSenderClient, char *filename, uint32 hash); + + IGameClient *GetGameClient() const { return m_pClient; }; + const char *GetFileName() const { return m_FileName; }; + uint32 GetClientHash() const { return m_ClientHash; }; + + private: + IGameClient *m_pClient; + const char *m_FileName; + uint32 m_ClientHash; + }; + +private: + // for temporary files of responses void AddElement(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash, int line); + void AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash); + const char *FindFilenameOfHash(uint32 hash); void LogPrepare(); // parse @@ -71,16 +92,16 @@ private: private: typedef std::vector ResourceList; + typedef std::vector ResponseList; + ResourceList m_resourceList; + ResponseList m_responseList; int m_DecalsNum; uint32 m_PrevHash; char m_PathDir[MAX_PATH_LENGTH]; - - // log data - char m_LogFilePath[MAX_PATH_LENGTH]; - char m_LogDate[64]; + char m_LogFilePath[MAX_PATH_LENGTH]; // log data }; extern CResourceFile Resource;