diff --git a/msvc/rechecker.vcxproj b/msvc/rechecker.vcxproj index 5c51048..5655ba9 100644 --- a/msvc/rechecker.vcxproj +++ b/msvc/rechecker.vcxproj @@ -168,6 +168,7 @@ + @@ -191,6 +192,7 @@ Create + diff --git a/msvc/rechecker.vcxproj.filters b/msvc/rechecker.vcxproj.filters index 216e9fe..4ca9a3c 100644 --- a/msvc/rechecker.vcxproj.filters +++ b/msvc/rechecker.vcxproj.filters @@ -462,6 +462,7 @@ + @@ -480,6 +481,7 @@ + diff --git a/src/dllapi.cpp b/src/dllapi.cpp index 8be2e91..9594d30 100644 --- a/src/dllapi.cpp +++ b/src/dllapi.cpp @@ -4,7 +4,6 @@ DLL_FUNCTIONS *g_pFunctionTable; extern void ServerDeactivate_Post(); extern void ClientPutInServer_Post(edict_t *pEntity); -extern void StartFrame(); static DLL_FUNCTIONS gFunctionTable = { diff --git a/src/main.cpp b/src/main.cpp index 706d0f6..8cee2b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -99,6 +99,7 @@ void OnMetaDetach() // clear Exec.Clear(); + Task.Clear(); Resource.Clear(); g_RehldsApi->GetHookchains()->SV_DropClient()->unregisterHook(&SV_DropClient); @@ -110,6 +111,7 @@ void ServerDeactivate_Post() { // clear Exec.Clear(); + Task.Clear(); Resource.Clear(); SET_META_RESULT(MRES_IGNORED); @@ -120,6 +122,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); + // to clear the current tasks + Task.Clear(pClient); + // clear temporary files of response Resource.Clear(pClient); @@ -138,6 +143,18 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain) return chain->callNext() + nConsistency; } +void TaskCommandExecute_Handler(IGameClient *pClient) +{ + if (!pClient->IsConnected()) + return; + + // client is connected to putinserver, go execute cmd out buffer + Exec.CommandExecute(pClient); + + // clear temporary files of response + Resource.Clear(pClient); +} + void ClientPutInServer_Post(edict_t *pEntity) { int nIndex = ENTINDEX(pEntity) - 1; @@ -147,11 +164,19 @@ void ClientPutInServer_Post(edict_t *pEntity) IGameClient *pClient = g_RehldsApi->GetServerStatic()->GetClient(nIndex); - // client is connected to putinserver, go execute cmd out buffer - Exec.CommandExecute(pClient); + if (pcv_rch_delay->value == 0.0f) + { + // client is connected to putinserver, go execute cmd out buffer + Exec.CommandExecute(pClient); - // clear temporary files of response - Resource.Clear(pClient); + // clear temporary files of response + Resource.Clear(pClient); + } + else + { + // hold to execute cmd + Task.AddTask(pClient, pcv_rch_delay->value, (xtask_t)TaskCommandExecute_Handler); + } SET_META_RESULT(MRES_IGNORED); } @@ -164,3 +189,9 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, // call next hook and take return of values from original func return chain->callNext(pSenderClient, resource, hash); } + +void StartFrame() +{ + Task.StartFrame(); + SET_META_RESULT(MRES_IGNORED); +} diff --git a/src/meta_api.cpp b/src/meta_api.cpp index 523f72e..c6cab09 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.3", + "1.6", __DATE__, "s1lent", "http://www.dedicated-server.ru/", diff --git a/src/precompiled.h b/src/precompiled.h index 88204a3..53af876 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -28,7 +28,7 @@ #include "consistency.h" #include "main.h" -//#include "task.h" +#include "task.h" //#include "config.h" #include "resource.h" #include "cmdexec.h" diff --git a/src/resource.cpp b/src/resource.cpp index 75092f5..4f74272 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -4,7 +4,10 @@ CResourceFile Resource; std::vector StringsCache; cvar_t cv_rch_log = { "rch_log", "0", 0, 0.0f, NULL }; +cvar_t cv_rch_delay = { "rch_delay", "0", 0, 0.0f, NULL }; + cvar_t *pcv_rch_log = NULL; +cvar_t *pcv_rch_delay = NULL; int CResourceFile::CreateResourceList() { @@ -17,7 +20,7 @@ int CResourceFile::CreateResourceList() // prevent duplicate of filenames // check if filename is been marked so do not add the resource again - if (!pRes->IsDuplicate()) + if (!pRes->IsDuplicate() && !SV_FileInConsistencyList(pRes->GetFileName(), NULL)) { // check limit resource if (g_RehldsServerData->GetResourcesNum() >= MAX_RESOURCE_LIST) @@ -213,7 +216,10 @@ void CResourceFile::Init() snprintf(m_PathDir, sizeof(m_PathDir), "%s" FILE_INI_RESOURCES, path); g_engfuncs.pfnCvar_RegisterVariable(&cv_rch_log); + g_engfuncs.pfnCvar_RegisterVariable(&cv_rch_delay); + pcv_rch_log = g_engfuncs.pfnCVarGetPointer(cv_rch_log.name); + pcv_rch_delay = g_engfuncs.pfnCVarGetPointer(cv_rch_delay.name); } inline uint8 hexbyte(uint8 *hex) @@ -408,8 +414,8 @@ void CResourceFile::LoadResources() } } - #define LOG_PRINT_FAILED(str, argv)\ - UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; " str, argv);\ + #define LOG_PRINT_FAILED(str, ...)\ + UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; " str, __VA_ARGS__);\ continue; if (argc >= MAX_PARSE_ARGUMENT) @@ -425,7 +431,7 @@ void CResourceFile::LoadResources() } else if (!IsValidFilename(filename, pchar)) { - LOG_PRINT_FAILED("filename has invalid character '%c' on line %d\n", (pchar, cline)); + LOG_PRINT_FAILED("filename has invalid character '%c' on line %d\n", pchar, cline); } else if (flag == FLAG_TYPE_NONE) { @@ -440,7 +446,7 @@ void CResourceFile::LoadResources() } else if (pToken != NULL || argc > ARG_TYPE_FILE_NAME) { - LOG_PRINT_FAILED("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); } } @@ -613,8 +619,9 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource // push exec cmd Exec.AddElement(pSenderClient, pRes, 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(), + static const char *szTypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" }; + Log(" -> file: (%s), exphash: (%x), got: (%x), typeFind: (%s), prevhash: (%x), (%s), prevfile: (%s), findathash: (%s), md5hex: (%x)", + pRes->GetFileName(), pRes->GetFileHash(), hash, szTypeNames[typeFind], m_PrevHash, pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash)); } diff --git a/src/resource.h b/src/resource.h index b8b02c2..d105318 100644 --- a/src/resource.h +++ b/src/resource.h @@ -110,4 +110,7 @@ private: extern CResourceFile Resource; +extern cvar_t *pcv_rch_log; +extern cvar_t *pcv_rch_delay; + void ClearStringsCache(); diff --git a/src/task.cpp b/src/task.cpp index 96dcbfc..f099131 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -53,7 +53,7 @@ void CTaskMngr::Clear(IGameClient *pClient) { if (pClient == NULL) { - // reset next frame + // reset next frame on level change m_nextFrame = 0; } diff --git a/src/task.h b/src/task.h index 3ca3b01..585f564 100644 --- a/src/task.h +++ b/src/task.h @@ -1,6 +1,6 @@ #pragma once -#define TASK_FREQUENCY_TIME 1.0f // check frequency current tasks +#define TASK_FREQUENCY_TIME 0.1f // check frequency current tasks typedef void (*xtask_t)(IGameClient *); @@ -34,3 +34,6 @@ private: }; extern CTaskMngr Task; +extern DLL_FUNCTIONS *g_pFunctionTable; + +extern void StartFrame();