Add own head the file delta.lst on first element of the resource list.

In order to always have the previous hash.
Refactoring
This commit is contained in:
s1lent 2017-10-21 00:42:04 +07:00 committed by s1lentq
parent d1d4c4766c
commit 9cdd1d1be8
32 changed files with 542 additions and 645 deletions

View File

@ -36,7 +36,7 @@
#include "archtypes.h"
#include "maintypes.h"
#include "regamedll_common.h"
#include "strtools.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN

View File

@ -1,96 +0,0 @@
/*
*
* 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.
*
*/
#pragma once
#ifndef _WIN32
#define _strlwr(p) for (int i = 0; p[i] != 0; i++) p[i] = tolower(p[i]);
#endif
#define Q_isspace isspace
#define Q_isalnum isalnum
#define Q_isalpha isalpha
#define Q_malloc malloc
#define Q_calloc calloc
#define Q_alloca alloca
#define Q_free free
#define Q_min min
#define Q_max max
#define Q_clamp clamp
#define Q_access _access
#define Q_close _close
#define Q_write _write
#define Q_memset memset
#define Q_memcpy memcpy
#define Q_strlen strlen
#define Q_memcmp memcmp
#define Q_strcpy strcpy
#define Q_strncpy strncpy
#define Q_strrchr strrchr
#define Q_strcat strcat
#define Q_strncat strncat
#define Q_strcmp strcmp
#define Q_strncmp strncmp
#define Q_sscanf sscanf
#define Q_strdup _strdup
#define Q_stricmp _stricmp
#define Q_strnicmp _strnicmp
#define Q_strstr strstr
#define Q_strchr strchr
#define Q_strrchr strrchr
#define Q_strlwr _strlwr
#define Q_sprintf sprintf
#define Q_snprintf _snprintf
#define Q_atoi atoi
#define Q_atof atof
#define Q_toupper toupper
#define Q_memmove memmove
#define Q_vsnprintf _vsnprintf
#define Q_vsnwprintf _vsnwprintf
#define Q_abs abs
#define Q_fabs fabs
#define Q_tan tan
#define Q_atan atan
#define Q_atan2 atan2
#define Q_acos acos
#define Q_cos cos
#define Q_sin sin
#define Q_pow pow
#define Q_fmod fmod
#define Q_fopen fopen
#define Q_fwrite fwrite
#define Q_fprintf fprintf
#define Q_fclose fclose
#ifdef REGAMEDLL_FIXES
#define Q_sqrt M_sqrt
#else
#define Q_sqrt sqrt
#endif

View File

@ -25,6 +25,7 @@
* version.
*
*/
#pragma once
template<typename t_ret, typename ...t_args>

View File

@ -48,6 +48,7 @@
#include <functional>
#ifdef _WIN32 // WINDOWS
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <winsock.h>
#include <wsipx.h> // for support IPX
@ -102,12 +103,15 @@
#ifndef CDECL
#define CDECL __cdecl
#endif
#define FASTCALL __fastcall
#define STDCALL __stdcall
#define HIDDEN
#define FORCEINLINE __forceinline
#define NOINLINE __declspec(noinline)
#define ALIGN16 __declspec(align(16))
#define NORETURN __declspec(noreturn)
#define FORCE_STACK_ALIGN
#define FUNC_TARGET(x)
#define __builtin_bswap16 _byteswap_ushort
#define __builtin_bswap32 _byteswap_ulong
@ -146,18 +150,24 @@
typedef unsigned short WORD;
typedef unsigned int UNINT32;
#define FASTCALL
#define CDECL __attribute__ ((cdecl))
#define STDCALL __attribute__ ((stdcall))
#define HIDDEN __attribute__((visibility("hidden")))
#define FORCEINLINE inline
#define NOINLINE __attribute__((noinline))
#define ALIGN16 __attribute__((aligned(16)))
#define NORETURN __attribute__((noreturn))
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
#if defined __INTEL_COMPILER
#define FUNC_TARGET(x)
#define __builtin_bswap16 _bswap16
#define __builtin_bswap32 _bswap
#define __builtin_bswap64 _bswap64
#else
#define FUNC_TARGET(x) __attribute__((target(x)))
#endif // __INTEL_COMPILER
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }

View File

@ -166,6 +166,7 @@
<ClInclude Include="..\public\rechecker_interfaces.h" />
<ClInclude Include="..\src\cmdexec.h" />
<ClInclude Include="..\src\hookchains_impl.h" />
<ClInclude Include="..\src\rechecker_api.h" />
<ClInclude Include="..\src\rechecker_api_impl.h" />
<ClInclude Include="..\src\resource.h" />
<ClInclude Include="..\src\engine_rehlds.h" />

View File

@ -467,6 +467,7 @@
<ClInclude Include="..\public\rechecker_interfaces.h">
<Filter>public</Filter>
</ClInclude>
<ClInclude Include="..\src\rechecker_api.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\common\parsemsg.cpp">

View File

@ -145,9 +145,12 @@ inline char *_strlwr(char *start)
#endif // #if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS)
// a safe variant of strcpy that truncates the result to fit in the destination buffer
template <size_t size>
char *Q_strlcpy(char (&dest)[size], const char *src) {
Q_strncpy(dest, src, size - 1);
template <typename T, size_t size>
T *Q_strlcpy(T (&dest)[size], const char *src)
{
static_assert(sizeof(T) == sizeof(char), "invalid size of type != sizeof(char)");
Q_strncpy((char *)dest, src, size - 1);
dest[size - 1] = '\0';
return dest;
}
@ -160,9 +163,11 @@ inline char *Q_strnlcpy(char *dest, const char *src, size_t n) {
// safely concatenate two strings.
// a variant of strcat that truncates the result to fit in the destination buffer
template <size_t size>
size_t Q_strlcat(char (&dest)[size], const char *src)
template <typename T, size_t size>
size_t Q_strlcat(T (&dest)[size], const char *src)
{
static_assert(sizeof(T) == sizeof(char), "invalid size of type != sizeof(char)");
size_t srclen; // Length of source string
size_t dstlen; // Length of destination string

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#include "precompiled.h"
CExecMngr Exec;
@ -26,14 +44,15 @@ void StringReplace(char *src, const char *strold, const char *strnew)
return;
char *p = src;
int oldLen = strlen(strold), newLen = strlen(strnew);
int oldLen = Q_strlen(strold), newLen = Q_strlen(strnew);
while ((p = strstr(p, strold)) != nullptr)
while ((p = Q_strstr(p, strold)))
{
if (oldLen != newLen)
memmove(p + newLen, p + oldLen, strlen(p) - oldLen + 1);
if (oldLen != newLen) {
Q_memmove(p + newLen, p + oldLen, Q_strlen(p) - oldLen + 1);
}
memcpy(p, strnew, newLen);
Q_memcpy(p, strnew, newLen);
p += newLen;
}
}
@ -45,22 +64,21 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
const netadr_t *net;
static char string[256];
// check cmdexec is empty
// Check cmdexec is empty
if (!pResource->GetCmdExec())
return nullptr;
strncpy(string, pResource->GetCmdExec(), sizeof(string) - 1);
string[sizeof(string) - 1] = '\0';
Q_strlcpy(string, pResource->GetCmdExec());
net = pClient->GetNetChan()->GetRemoteAdr();
nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
// replace key values
// Replace key values
StringReplace(string, "[file_name]", pResource->GetFileName());
StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", responseHash));
StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", _byteswap_ulong(responseHash)));
// replace of templates for identification
// Replace of templates for identification
StringReplace(string, "[userid]", UTIL_VarArgs("#%u", nUserID));
StringReplace(string, "[steamid]", UTIL_VarArgs("%s", g_engfuncs.pfnGetPlayerAuthId(pClient->GetEdict())));
StringReplace(string, "[ip]", UTIL_VarArgs("%i.%i.%i.%i", net->ip[0], net->ip[1], net->ip[2], net->ip[3]));
@ -70,7 +88,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
{
g_pResource->Log(LOG_NORMAL, " -> ExecuteCMD: (%s), for (#%u)(%s)", string, nUserID, pClient->GetName());
len = strlen(string);
len = Q_strlen(string);
if (len < sizeof(string) - 2)
strcat(string, "\n");
@ -83,7 +101,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
bool haveAtLeastOneExecuted = false;
void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cmdExec, uint32 responseHash) {
// execute cmdexec
// Execute cmdexec
SERVER_COMMAND(cmdExec);
haveAtLeastOneExecuted = true;
}
@ -96,8 +114,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
while (iter != m_execList.end())
{
CBufExec *pExec = (*iter);
auto pExec = (*iter);
if (pExec->GetUserID() != nUserID)
{
iter++;
@ -106,14 +123,13 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
CResourceBuffer *pRes = pExec->GetResource();
// exit the loop if the client is out of the game
// TODO: Check me!
// Exit the loop if the client is out of the game
if (!pClient->IsConnected())
{
break;
}
// erase all cmdexec because have flag is break
// Erase all cmdexec because have flag is break
if (!bBreak)
{
char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash());
@ -125,7 +141,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
bBreak = pRes->IsBreak();
}
// erase cmdexec
// Erase cmdexec
delete pExec;
iter = m_execList.erase(iter);
}
@ -152,9 +168,9 @@ void CExecMngr::Clear(IGameClient *pClient)
auto iter = m_execList.begin();
while (iter != m_execList.end())
{
CBufExec *pExec = (*iter);
auto pExec = (*iter);
// erase cmdexec
// Erase cmdexec
if (pExec->GetUserID() != nUserID)
{
iter++;

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#pragma once
class CExecMngr

View File

@ -1,99 +0,0 @@
#include "precompiled.h"
#define TRY_READ_INT(a,b,min,max) if (_stricmp(argv[0], ##a) == 0) b = clamp(atoi(argv[1]), min, max);
#define TRY_READ_FLOAT(a,b,min,max) if (_stricmp(argv[0], ##a) == 0) b = clamp(atof(argv[1]), min, max);
#define TRY_READ_STRING(a,b) if (_stricmp(argv[0], ##a) == 0) strncpy(b, argv[1], sizeof(b) - 1); b[sizeof(b) - 1] = '\0';
CConfig Config;
void CConfig::Init()
{
char *pos;
char path[MAX_PATH];
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
pos = strrchr(path, '/');
if (*pos == '\0')
return;
*(pos + 1) = '\0';
// config.ini
snprintf(m_PathDir, sizeof(m_PathDir), "%s" FILE_INI_CONFIG, path);
}
int parse(char *line, char **argv, int max_args)
{
int count = 0;
while (*line)
{
// null whitespaces
while (*line == ' ' || *line == '\t' || *line == '\n' || *line == '\r' || *line == '=' || *line == '"')
*line++ = '\0';
if (*line)
{
// save arg address
argv[count++] = line;
if (count == max_args)
break;
// skip arg
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n' && *line != '\r' && *line != '=' && *line != '"')
line++;
}
}
return count;
}
void CConfig::ResetValues()
{
m_DelayExec = 2.5f;
// [..]
}
void CConfig::Load()
{
FILE *fp;
char line[1024];
char *argv[3];
int argc;
char *pos;
// reset config
ResetValues();
fp = fopen(m_PathDir, "rt");
if (fp == NULL)
{
UTIL_Printf("%s: can't find path to " FILE_INI_CONFIG "\n", __func__);
return;
}
while (!feof(fp) && fgets(line, sizeof(line), fp))
{
pos = line;
if (*pos == '\0' || *pos == ';' || *pos == '\\' || *pos == '/' || *pos == '#')
continue;
if ((pos = strchr(line, ';')) != NULL || (pos = strstr(line, "//")) != NULL)
*pos = '\0';
argc = parse(line, argv, ARRAYSIZE(argv));
if (argc != 2)
continue;
else TRY_READ_FLOAT("delay_exec", m_DelayExec, 0.0, 60.0)
}
fclose(fp);
}

View File

@ -1,26 +0,0 @@
#pragma once
#define FILE_INI_CONFIG "config.ini"
class CConfig
{
public:
void Init();
void Load();
float GetDelay() const { return m_DelayExec; };
private:
void ResetValues();
private:
char m_PathDir[MAX_PATH];
// settings
float m_DelayExec;
};
template <typename T>
T clamp(T a, T min, T max) { return (a > max) ? max : (a < min) ? min : a; }
extern CConfig Config;

View File

@ -1,9 +1,25 @@
/*
*
* 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
*
*/
#include "precompiled.h"
DLL_FUNCTIONS *g_pFunctionTable;
extern void ServerDeactivate_Post();
static DLL_FUNCTIONS gFunctionTable =
{
NULL, // pfnGameInit
@ -148,7 +164,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
return FALSE;
}
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
Q_memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
g_pFunctionTable = pFunctionTable;
return TRUE;
@ -170,7 +186,7 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
return FALSE;
}
memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
Q_memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
g_pFunctionTable = pFunctionTable;
return TRUE;

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#include "precompiled.h"
enginefuncs_t meta_engfuncs_post =
@ -227,6 +245,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
return FALSE;
}
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
Q_memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return TRUE;
}

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#include "precompiled.h"
IRehldsApi *g_RehldsApi;

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#pragma once
enum rehlds_ret

View File

@ -1,32 +1,24 @@
// From SDK dlls/h_export.cpp:
/***
*
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
/*
===== h_export.cpp ========================================================
Entity classes exported by Halflife.
*
* 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
*
*/
#include "precompiled.h"
// From SDK dlls/h_export.cpp:
//! Holds engine functionality callbacks
// Holds engine functionality callbacks
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
@ -35,6 +27,6 @@ globalvars_t *gpGlobals;
// do some setup operations here.
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
{
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
Q_memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
gpGlobals = pGlobals;
}

View File

@ -76,15 +76,17 @@ void AbstractHookChainRegistry::removeHook(void *hookFunc) {
{
if (hookFunc == m_Hooks[i])
{
--m_NumHooks;
m_NumHooks--;
if (m_NumHooks != i)
{
Q_memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
Q_memmove(&m_Priorities[i], &m_Priorities[i + 1], (m_NumHooks - i) * sizeof(m_Priorities[0]));
m_Hooks[m_NumHooks] = NULL;
m_Hooks[m_NumHooks] = nullptr;
}
else
m_Hooks[i] = NULL;
{
m_Hooks[i] = nullptr;
}
return;
}

View File

@ -14,22 +14,26 @@
* 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.
*
*/
#pragma once
#include "hookchains.h"
const int MAX_HOOKS_IN_CHAIN = 19;
template <typename t_ret, typename t_class, typename ...t_args>
bool is_void(t_ret (t_class::*)(t_args...)) { return false; }
template <typename t_ret, typename ...t_args>
bool is_void(t_ret (*)(t_args...)) { return false; }
template <typename t_class, typename ...t_args>
bool is_void(void (t_class::*)(t_args...)) { return true; }
template <typename ...t_args>
bool is_void(void (*)(t_args...)) { return true; }
// Implementation for chains in modules
template<typename t_ret, typename ...t_args>
class IHookChainImpl: public IHookChain<t_ret, t_args...> {
@ -39,7 +43,7 @@ public:
IHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
{
if (orig == NULL)
if (!orig && !is_void(orig))
Sys_Error("%s: Non-void HookChain without original function.", __func__);
}
@ -54,46 +58,11 @@ public:
return nexthook(&nextChain, args...);
}
return m_OriginalFunc(args...);
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
}
virtual t_ret callOriginal(t_args... args) {
return m_OriginalFunc(args...);
}
private:
void **m_Hooks;
origfunc_t m_OriginalFunc;
};
// Implementation for void chains in modules
template<typename ...t_args>
class IVoidHookChainImpl: public IVoidHookChain<t_args...> {
public:
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
typedef void (*origfunc_t)(t_args...);
IVoidHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig) {}
virtual ~IVoidHookChainImpl() {}
virtual void callNext(t_args... args) {
hookfunc_t nexthook = (hookfunc_t)m_Hooks[0];
if (nexthook)
{
IVoidHookChainImpl nextChain(m_Hooks + 1, m_OriginalFunc);
nexthook(&nextChain, args...);
}
else
{
if (m_OriginalFunc)
m_OriginalFunc(args...);
}
}
virtual void callOriginal(t_args... args) {
if (m_OriginalFunc)
m_OriginalFunc(args...);
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
}
private:
@ -116,10 +85,10 @@ public:
AbstractHookChainRegistry();
};
template<typename t_ret, typename ...t_args>
class IHookChainRegistryImpl : public IHookChainRegistry < t_ret, t_args...>, public AbstractHookChainRegistry {
template <typename t_ret, typename ...t_args>
class IHookChainRegistryImpl: public IHookChainRegistry<t_ret, t_args...>, public AbstractHookChainRegistry {
public:
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...> *, t_args...);
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
typedef t_ret (*origfunc_t)(t_args...);
virtual ~IHookChainRegistryImpl() { }
@ -136,25 +105,3 @@ public:
removeHook((void *)hook);
}
};
template<typename ...t_args>
class IVoidHookChainRegistryImpl: public IVoidHookChainRegistry <t_args...>, public AbstractHookChainRegistry {
public:
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
typedef void (*origfunc_t)(t_args...);
virtual ~IVoidHookChainRegistryImpl() { }
void callChain(origfunc_t origFunc, t_args... args) {
IVoidHookChainImpl<t_args...> chain(m_Hooks, origFunc);
chain.callNext(args...);
}
virtual void registerHook(hookfunc_t hook, int priority) {
addHook((void *)hook, priority);
}
virtual void unregisterHook(hookfunc_t hook) {
removeHook((void *)hook);
}
};

View File

@ -1,7 +1,25 @@
/*
*
* 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
*
*/
#include "precompiled.h"
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, NULL };
cvar_t *pcv_consistency_old = NULL;
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, nullptr };
cvar_t *pcv_consistency_old = nullptr;
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);
@ -13,14 +31,14 @@ bool OnMetaAttach()
g_pResource = new CResourceFile();
// initialize resource config
// Initialize resource environment
g_pResource->Init();
Rechecker_Api_Init();
// if have already registered take it
// If have already registered take it
cvar_t *pcv_consistency_prev = g_engfuncs.pfnCVarGetPointer("mp_consistency_");
if (pcv_consistency_prev != NULL)
if (pcv_consistency_prev)
{
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
@ -34,7 +52,7 @@ bool OnMetaAttach()
}
else
{
// set force cvar on own value and replacement of original
// Set force cvar on own value and replacement of original
// NOTE: in gamedll used this cvar not through a pointer thus we create own cvar for gamedll with default values
// so for engine set it the cvar values is 1.
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
@ -50,13 +68,13 @@ bool OnMetaAttach()
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, "1");
// to remove the old cvar of cvars list
// To remove the old cvar of cvars list
cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars();
for (cvar_t *var = cvar_vars, *prev = NULL; var != NULL; prev = var, var = var->next)
for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next)
{
if (var == pcv_consistency_old)
{
if (prev != NULL)
if (prev)
prev->next = var->next;
else
cvar_vars = cvar_vars->next;
@ -64,7 +82,7 @@ bool OnMetaAttach()
}
}
// register function from ReHLDS API
// Register function from ReHLDS API
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient);
g_RehldsHookchains->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse);
g_RehldsHookchains->SV_TransferConsistencyInfo()->registerHook(&SV_TransferConsistencyInfo);
@ -74,7 +92,7 @@ bool OnMetaAttach()
SV_AddResource = g_RehldsFuncs->SV_AddResource;
SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList;
// go to attach
// Go to attach
return true;
}
@ -82,19 +100,19 @@ void OnMetaDetach()
{
cvar_t *pcv_mp_consistency = g_engfuncs.pfnCVarGetPointer("mp_consistency");
// to restore the pointer address of a string
// To restore the pointer address of a string
const char *tempName = pcv_consistency_old->name;
pcv_consistency_old->name = cv_mp_consistency.name;
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, pcv_mp_consistency->string);
pcv_mp_consistency->name = tempName;
// restore old cvar mp_consistency
// Restore old cvar mp_consistency
cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars();
for (cvar_t *var = cvar_vars, *prev = NULL; var != NULL; prev = var, var = var->next)
for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next)
{
if (var == pcv_mp_consistency)
{
if (prev != NULL)
if (prev)
prev->next = pcv_consistency_old;
else
cvar_vars = pcv_consistency_old;
@ -102,7 +120,7 @@ void OnMetaDetach()
}
}
// clear
// Clear
Exec.Clear();
delete g_pResource;
@ -117,7 +135,7 @@ void OnMetaDetach()
void ServerDeactivate_Post()
{
// clear
// Clear
Exec.Clear();
g_pResource->Clear();
@ -126,13 +144,13 @@ void ServerDeactivate_Post()
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string)
{
// clear buffer cmdexec the client when was disconnected up to perform cmdexec
// Clear buffer cmdexec the client when was disconnected up to perform cmdexec
Exec.Clear(pClient);
// clear temporary files of response
// Clear temporary files of response
g_pResource->Clear(pClient);
// call next hook
// Call next hook
chain->callNext(pClient, crash, string);
}
@ -140,10 +158,10 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain)
{
g_pResource->LoadResources();
// add to the resource
// Add to the resource
int nConsistency = g_pResource->CreateResourceList();
// returns the total number of consistency files
// Returns the total number of consistency files
return chain->callNext() + nConsistency;
}
@ -152,7 +170,7 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash))
return false;
// call next hook and take return of values from original func
// Call next hook and take return of values from original func
return chain->callNext(pSenderClient, resource, hash);
}
@ -171,7 +189,7 @@ void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain)
g_RecheckerHookchains.m_FileConsistencyFinal.callChain(nullptr, pClient);
}
// client is connected to putinserver, go execute cmd out buffer
// Client is connected to putinserver, go execute cmd out buffer
Exec.ExecuteCommand(pClient);
}
@ -179,7 +197,7 @@ const int clc_fileconsistency = 7;
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode)
{
if (opcode == clc_fileconsistency) {
// clear temporary files of response
// Clear temporary files of response
g_pResource->Clear(cl);
}

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#pragma once
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string);
@ -5,6 +23,7 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain);
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain);
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode);
void ServerDeactivate_Post();
extern void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
extern qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);

View File

@ -1,10 +1,28 @@
/*
*
* 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
*
*/
#include "precompiled.h"
plugin_info_t Plugin_info =
{
META_INTERFACE_VERSION,
"Rechecker",
"2.4",
"2.5",
__DATE__,
"s1lent",
"http://www.dedicated-server.ru/",
@ -41,12 +59,11 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
return FALSE;
}
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
GET_HOOK_TABLES(PLID, NULL, &gMetaEntityInterface, NULL);
GET_HOOK_TABLES(PLID, nullptr, &gMetaEntityInterface, nullptr);
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
Q_memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
return TRUE;
}

View File

@ -1 +1,19 @@
/*
*
* 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
*
*/
#include "precompiled.h"

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#pragma once
#include "basetypes.h"
@ -24,7 +42,6 @@
#include "rechecker_api_impl.h"
#include "main.h"
#include "task.h"
#include "resource.h"
#include "cmdexec.h"

View File

@ -1,3 +1,20 @@
#include "precompiled.h"
/*
*
* 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
*
*/
#include "precompiled.h"
#include "interface.cpp"

View File

@ -14,17 +14,8 @@
* 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.
*
*/
#pragma once
#include "hookchains.h"
@ -45,16 +36,16 @@ enum ResourceType_e
class IResourceBuffer;
// FileConsistencyProcess hook
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
typedef IHookChain<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
// CmdExec hook
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
typedef IHookChain<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
// FileConsistencyFinal hook
typedef IVoidHookChain<IGameClient *> IRecheckerHook_FileConsistencyFinal;
typedef IVoidHookChainRegistry<IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
typedef IHookChain<void, IGameClient *> IRecheckerHook_FileConsistencyFinal;
typedef IHookChainRegistry<void, IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
class IRecheckerHookchains {
protected:

View File

@ -14,17 +14,8 @@
* 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.
*
*/
#include "precompiled.h"
CRecheckerApi g_RecheckerApi;

View File

@ -14,30 +14,21 @@
* 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.
*
*/
#pragma once
// FileConsistencyProcess hook
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
// CmdExec hook
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
// FileConsistencyFinal hook
typedef IVoidHookChainImpl<IGameClient *> CRecheckerHook_FileConsistencyFinal;
typedef IVoidHookChainRegistryImpl<IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
typedef IHookChainImpl<void, IGameClient *> CRecheckerHook_FileConsistencyFinal;
typedef IHookChainRegistryImpl<void, IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
class CRecheckerHookchains: public IRecheckerHookchains {
public:
@ -91,8 +82,8 @@ struct query_file_t
inline query_file_t::query_file_t(const char *filename, const ResourceType_e flag, uint32 hash, query_func_t func, int uniqueId)
{
this->filename = new char [strlen(filename) + 1];
strcpy(this->filename, filename);
this->filename = new char [Q_strlen(filename) + 1];
Q_strcpy(this->filename, filename);
this->flag = flag;
this->hash = hash;

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#include "precompiled.h"
CResourceFile *g_pResource = nullptr;
@ -6,8 +24,6 @@ CResourceFile::StringList CResourceFile::m_StringsCache;
cvar_t cv_rch_log = { "rch_log", "0", 0, 0.0f, nullptr };
cvar_t *pcv_rch_log = nullptr;
const char *szTypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" };
CResourceFile::CResourceFile() :
m_resourceList(),
m_responseList(),
@ -16,6 +32,8 @@ CResourceFile::CResourceFile() :
{
m_PathDir[0] = '\0';
m_LogFilePath[0] = '\0';
Q_memset(&m_HeadResource, 0, sizeof(m_HeadResource));
}
CResourceFile::~CResourceFile()
@ -25,20 +43,22 @@ CResourceFile::~CResourceFile()
int CResourceFile::CreateResourceList()
{
// max value of 12 bits
// we need to go over the threshold
int startIndex = (1 << RESOURCE_INDEX_BITS) - 1;
int nCustomConsistency = 0;
ComputeConsistencyFiles();
AddHeadResource();
// Max value of 12 bits,
// we need to hit over the threshold
int nIndex = m_HeadResource.nIndex + 1;
int nCustomConsistency = 1;
std::vector<resource_t> sortList;
for (auto res : m_resourceList)
{
// prevent duplicate of filenames
// check if filename is been marked so do not add the resource again
// Prevent duplicate of filenames
// Check if filename is been marked so do not add the resource again
if (!res->IsDuplicate())
{
// check limit resource
// Check limit resource
if (g_RehldsServerData->GetResourcesNum() >= RESOURCE_MAX_COUNT)
{
if (res->IsAddEx()) {
@ -50,7 +70,7 @@ int CResourceFile::CreateResourceList()
break;
}
// not allow to add a resource if the index is larger than 1024 or we will get Bad file data.
// Not allow to add a resource if the index is larger than 1024 or we will get Bad file data.
// https://github.com/dreamstalker/rehlds/blob/beaeb65/rehlds/engine/sv_user.cpp#L374
if (nCustomConsistency + m_ConsistencyNum >= MAX_RANGE_CONSISTENCY)
{
@ -63,13 +83,21 @@ int CResourceFile::CreateResourceList()
break;
}
Log(LOG_DETAILED, "%s -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), res->GetCmdExec(), res->GetFileHash(), szTypeNames[ res->GetFileFlag() ], res->IsAddEx());
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, startIndex++);
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, nIndex++);
nCustomConsistency++;
}
auto pszCmdExec = res->GetCmdExec();
if (pszCmdExec[0] != '\0')
{
Log(LOG_DETAILED, "%s -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), pszCmdExec, res->GetFileHash(), m_TypeNames[res->GetFileFlag()], res->IsAddEx());
}
else
{
Log(LOG_DETAILED, "%s -> file: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), res->GetFileHash(), m_TypeNames[res->GetFileFlag()], res->IsAddEx());
}
}
std::vector<resource_t> sortList;
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
{
sortList.push_back(*g_RehldsServerData->GetResource(i));
@ -78,7 +106,7 @@ int CResourceFile::CreateResourceList()
// Start a first resource list
g_RehldsServerData->SetResourcesNum(0);
// sort
// Sorting
std::sort(sortList.begin(), sortList.end(), [](const resource_t &a, const resource_t &b)
{
bool a_cons = (a.ucFlags & RES_CHECKFILE) || SV_FileInConsistencyList(a.szFileName, nullptr);
@ -93,6 +121,9 @@ int CResourceFile::CreateResourceList()
return a.nIndex < b.nIndex;
});
// Insert to front head resource
sortList.insert(sortList.begin(), m_HeadResource);
for (auto& res : sortList)
{
// Add new resource in the own order
@ -107,47 +138,60 @@ void CResourceFile::ComputeConsistencyFiles()
{
m_ConsistencyNum = 0;
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); ++i)
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
{
auto res = g_RehldsServerData->GetResource(i);
if (res->ucFlags == (RES_CUSTOM | RES_REQUESTED | RES_UNK_6) || (res->ucFlags & RES_CHECKFILE))
continue;
if (SV_FileInConsistencyList(res->szFileName, nullptr))
++m_ConsistencyNum;
if (!SV_FileInConsistencyList(res->szFileName, nullptr))
continue;
m_ConsistencyNum++;
}
}
void CResourceFile::AddHeadResource()
{
Q_strlcpy(m_HeadResource.szFileName, m_HeadFileName);
m_HeadResource.type = t_decal;
m_HeadResource.ucFlags = RES_CHECKFILE;
m_HeadResource.nDownloadSize = 0;
m_HeadResource.nIndex = RESOURCE_MAX_COUNT - 1;
}
void CResourceFile::Clear(IGameClient *pClient)
{
if (pClient)
{
// remove each entries by pClient
// Remove each entries by pClient
auto nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
auto iter = m_responseList.begin();
while (iter != m_responseList.end())
{
CResponseBuffer *pFiles = (*iter);
auto pFiles = (*iter);
// erase cmdexec
if (pFiles->GetUserID() == nUserID)
// Erase cmdexec
if (pFiles->GetUserID() != nUserID)
{
delete pFiles;
iter = m_responseList.erase(iter);
}
else
iter++;
continue;
}
delete pFiles;
iter = m_responseList.erase(iter);
}
m_PrevHash = 0;
return;
}
// remove all
// Remove all
m_PrevHash = 0;
m_ConsistencyNum = 0;
// clear resources
// Clear resources
for (auto it : m_resourceList)
delete it;
@ -190,10 +234,10 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
va_list argptr;
va_start(argptr, fmt);
vsnprintf(string, sizeof(string), fmt, argptr);
Q_vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr);
strcat(string, "\n");
Q_strlcat(string, "\n");
td = time(nullptr);
lt = localtime(&td);
@ -202,7 +246,7 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
if (!bFirst)
{
file = strrchr(m_LogFilePath, '/');
file = Q_strrchr(m_LogFilePath, '/');
if (file == nullptr)
file = "<null>";
@ -239,23 +283,20 @@ void CResourceFile::Init()
char *pos;
char path[MAX_PATH];
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
pos = strrchr(path, '/');
Q_strlcpy(path, GET_PLUGIN_PATH(PLID));
pos = Q_strrchr(path, '/');
if (*pos == '\0')
return;
*(pos + 1) = '\0';
strncpy(m_LogFilePath, path, sizeof(m_LogFilePath) - 1);
m_LogFilePath[sizeof(m_LogFilePath) - 1] = '\0';
strcat(m_LogFilePath, "logs/");
Q_strlcpy(m_LogFilePath, path);
Q_strlcat(m_LogFilePath, "logs/");
CreateDirectory(m_LogFilePath);
// resources.ini
snprintf(m_PathDir, sizeof(m_PathDir), "%s" FILE_INI_RESOURCES, path);
Q_snprintf(m_PathDir, sizeof(m_PathDir), "%s%s", path, FILE_INI_RESOURCES);
g_engfuncs.pfnCvar_RegisterVariable(&cv_rch_log);
pcv_rch_log = g_engfuncs.pfnCVarGetPointer(cv_rch_log.name);
@ -269,7 +310,7 @@ inline uint8 hexbyte(uint8 *hex)
inline bool invalidchar(const char c)
{
// to check for invalid characters
// To check for invalid characters
return (c == '\\' || c == '/' || c == ':'
|| c == '*' || c == '?'
|| c == '"' || c == '<'
@ -278,7 +319,7 @@ inline bool invalidchar(const char c)
bool IsValidFilename(char *psrc, char &pchar)
{
char *pch = strrchr(psrc, '/');
char *pch = Q_strrchr(psrc, '/');
if (!pch)
pch = psrc;
@ -296,16 +337,16 @@ bool IsValidFilename(char *psrc, char &pchar)
bool IsFileHasExtension(char *psrc)
{
// find the extension filename
char *pch = strrchr(psrc, '.');
// Find the extension filename
char *pch = Q_strrchr(psrc, '.');
if (!pch)
return false;
// the size extension
if (strlen(&pch[1]) <= 0)
// The size extension
if (Q_strlen(&pch[1]) <= 0)
return false;
return strchr(pch, '/') == nullptr;
return Q_strchr(pch, '/') == nullptr;
}
void CResourceFile::LogPrepare()
@ -318,14 +359,14 @@ void CResourceFile::LogPrepare()
td = time(nullptr);
lt = localtime(&td);
// remove path to log file
if ((pos = strrchr(m_LogFilePath, '/')) != nullptr)
// Remove path to log file
if ((pos = Q_strrchr(m_LogFilePath, '/')))
{
*(pos + 1) = '\0';
}
strftime(dateFile, sizeof(dateFile), "L_%d_%m_%Y.log", lt);
strcat(m_LogFilePath, dateFile);
Q_strlcat(m_LogFilePath, dateFile);
}
void CResourceFile::LoadResources()
@ -335,7 +376,6 @@ void CResourceFile::LoadResources()
uint8 hash[16];
FILE *fp;
int argc;
int len;
ResourceType_e flag;
char filename[MAX_PATH];
char cmdBufExec[MAX_PATH];
@ -352,7 +392,7 @@ void CResourceFile::LoadResources()
while (!feof(fp) && fgets(line, sizeof(line), fp))
{
// skip bytes BOM signature
// Skip bytes BOM signature
if ((byte)line[0] == 0xEFu && (byte)line[1] == 0xBBu && (byte)line[2] == 0xBFu)
pos = &line[3];
else
@ -369,38 +409,33 @@ void CResourceFile::LoadResources()
bBreak = false;
flag = RES_TYPE_NONE;
memset(hash, 0, sizeof(hash));
Q_memset(hash, 0, sizeof(hash));
while (pToken && argc <= MAX_PARSE_ARGUMENT)
{
len = strlen(pToken);
switch (argc)
{
case ARG_TYPE_FILE_NAME:
{
strncpy(filename, pToken, len);
filename[len] = '\0';
Q_strlcpy(filename, pToken);
break;
}
case ARG_TYPE_FILE_HASH:
{
uint8 pbuf[33];
Q_strlcpy(pbuf, pToken);
strncpy((char *)pbuf, pToken, len);
pbuf[len] = '\0';
if (_stricmp((const char *)pbuf, "UNKNOWN") == 0)
if (Q_stricmp((const char *)pbuf, "UNKNOWN") == 0)
{
flag = RES_TYPE_HASH_ANY;
}
else if (_stricmp((const char *)pbuf, "MISSING") == 0)
else if (Q_stricmp((const char *)pbuf, "MISSING") == 0)
{
flag = RES_TYPE_MISSING;
}
else
{
for (int i = 0; i < sizeof(pbuf) / 2; ++i)
for (int i = 0; i < sizeof(pbuf) / 2; i++)
hash[i] = hexbyte(&pbuf[i * 2]);
flag = RES_TYPE_EXISTS;
@ -409,33 +444,32 @@ void CResourceFile::LoadResources()
}
case ARG_TYPE_CMD_EXEC:
{
strncpy(cmdBufExec, pToken, len);
cmdBufExec[len] = '\0';
Q_strlcpy(cmdBufExec, pToken);
if (_stricmp(cmdBufExec, "IGNORE") == 0)
if (Q_stricmp(cmdBufExec, "IGNORE") == 0)
{
flag = RES_TYPE_IGNORE;
cmdBufExec[0] = '\0';
}
else if (_stricmp(cmdBufExec, "BREAK") == 0)
else if (Q_stricmp(cmdBufExec, "BREAK") == 0)
{
bBreak = true;
cmdBufExec[0] = '\0';
}
else
{
// replface \' to "
// Replace \' to "
StringReplace(cmdBufExec, "'", "\"");
}
break;
}
case ARG_TYPE_FLAG:
{
if (_stricmp(pToken, "IGNORE") == 0)
if (Q_stricmp(pToken, "IGNORE") == 0)
{
flag = RES_TYPE_IGNORE;
}
else if (_stricmp(pToken, "BREAK") == 0)
else if (Q_stricmp(pToken, "BREAK") == 0)
{
bBreak = true;
}
@ -449,19 +483,19 @@ void CResourceFile::LoadResources()
if (++argc == ARG_TYPE_FLAG && pToken == nullptr)
{
// go to next argument
// Go to next argument
argc++;
}
}
#define LOG_PRINT_FAILED(str, ...)\
UTIL_Printf("%s: Failed to load \"" FILE_INI_RESOURCES "\"; %s", __func__, str, __VA_ARGS__);\
UTIL_Printf("%s: Failed to load \"%s\"; " str "", __func__, FILE_INI_RESOURCES, __VA_ARGS__);\
continue;
if (argc >= MAX_PARSE_ARGUMENT)
{
char pchar;
if (strlen(filename) <= 0)
char pchar = '?';
if (Q_strlen(filename) <= 0)
{
LOG_PRINT_FAILED("path to filename is empty on line %d\n", cline);
}
@ -477,7 +511,7 @@ void CResourceFile::LoadResources()
{
LOG_PRINT_FAILED("parsing hash failed on line %d\n", cline);
}
else if (strlen(cmdBufExec) <= 0 && (flag != RES_TYPE_IGNORE && !bBreak))
else if (Q_strlen(cmdBufExec) <= 0 && (flag != RES_TYPE_IGNORE && !bBreak))
{
LOG_PRINT_FAILED("parsing command line is empty on line %d\n", cline);
}
@ -500,7 +534,7 @@ const char *CResourceFile::GetNextToken(char **pbuf)
if (*rpos == '\0')
return nullptr;
// skip spaces at the beginning
// Skip spaces at the beginning
while (*rpos != '\0' && isspace(*rpos))
rpos++;
@ -563,12 +597,12 @@ CResourceBuffer *CResourceFile::Add(const char *filename, char *cmdExec, Resourc
{
auto nRes = new CResourceBuffer(filename, cmdExec, flag, hash, line, bBreak);
// to mark files which are not required to add to the resource again
// To mark files which are not required to add to the resource again
for (auto res : m_resourceList)
{
if (_stricmp(res->GetFileName(), filename) == 0)
if (Q_stricmp(res->GetFileName(), filename) == 0)
{
// resource name already registered
// Resource name already registered
nRes->SetDuplicate();
break;
}
@ -593,7 +627,7 @@ void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceB
// Fire query to callback's
for (auto query : g_QueryFiles)
{
if (!res->IsAddEx() || strcmp(query->filename, pRes->GetFileName()) != 0)
if (!res->IsAddEx() || Q_strcmp(query->filename, pRes->GetFileName()) != 0)
continue;
if (query->flag == typeFind) {
@ -601,7 +635,7 @@ void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceB
}
}
// push exec cmd
// Push exec cmd
Exec.Add(pSenderClient, pRes, hash);
g_pResource->PrintLog(pSenderClient, pRes, typeFind, hash);
}
@ -610,18 +644,18 @@ void CResourceFile::PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, R
{
flag_type_log type = (typeFind == RES_TYPE_IGNORE) ? LOG_DETAILED : LOG_NORMAL;
Log(type, " -> file: (%s), exphash: (%x), got: (%x), typeFind: (%s), prevhash: (%x), (#%u)(%s), prevfile: (%s), findathash: (%s), md5hex: (%x), ex: (%d)",
res->GetFileName(), res->GetFileHash(), hash, szTypeNames[ typeFind ], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()),
res->GetFileName(), res->GetFileHash(), hash, m_TypeNames[typeFind], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()),
pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash), res->IsAddEx());
}
IResourceBuffer *CResourceFile::GetResourceFile(const char *filename)
{
// to mark files which are not required to add to the resource again
// To mark files which are not required to add to the resource again
for (auto res : m_resourceList)
{
if (_stricmp(res->GetFileName(), filename) == 0)
if (Q_stricmp(res->GetFileName(), filename) == 0)
{
// resource name already have, return its;
// Resource name already have, return its;
return res;
}
}
@ -650,7 +684,7 @@ IResponseBuffer *CResourceFile::GetResponseFile(IGameClient *pClient, const char
break;
}
if (_stricmp(res->GetFileName(), filename) == 0) {
if (Q_stricmp(res->GetFileName(), filename) == 0) {
return res;
}
}
@ -665,7 +699,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
std::vector<CResourceBuffer *> tempResourceList;
if (resource->type != t_decal
|| resource->nIndex < 4095) // if by some miracle the decals will have the flag RES_CHECKFILE
|| resource->nIndex < 4095) // If by some miracle the decals will have the flag RES_CHECKFILE
// to be sure not bypass the decals
{
AddFileResponse(pSenderClient, resource->szFileName, hash);
@ -673,16 +707,28 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
return true;
}
// strange thing
// Strange thing
// if this happened when missing all the files from client
if (!m_PrevHash)
{
// Received a head file
if (!Q_stricmp(resource->szFileName, m_HeadFileName))
{
if (hash == 0) {
Log(LOG_DETAILED, "WARNING: %s received unwanted hash: (%x)\n", m_HeadFileName, hash);
}
AddFileResponse(pSenderClient, resource->szFileName, hash);
m_PrevHash = hash;
return false;
}
return true;
}
for (auto res : m_resourceList)
{
if (strcmp(resource->szFileName, res->GetFileName()) != 0)
if (Q_strcmp(resource->szFileName, res->GetFileName()) != 0)
continue;
typeFind = res->GetFileFlag();
@ -704,7 +750,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
case RES_TYPE_HASH_ANY:
for (auto temp : tempResourceList)
{
if (_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
if (Q_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
continue;
if (temp->GetFileHash() == hash)
@ -731,6 +777,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
AddFileResponse(pSenderClient, resource->szFileName, hash);
m_PrevHash = hash;
return !bHandled;
}
@ -738,11 +785,11 @@ const char *CResourceFile::DuplicateString(const char *str)
{
for (auto string : m_StringsCache)
{
if (!strcmp(string, str))
if (!Q_strcmp(string, str))
return string;
}
const char *s = strcpy(new char[strlen(str) + 1], str);
const char *s = Q_strcpy(new char[Q_strlen(str) + 1], str);
m_StringsCache.push_back(s);
return s;
}

View File

@ -1,11 +1,30 @@
/*
*
* 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
*
*/
#pragma once
#define FILE_INI_RESOURCES "resources.ini"
#define MAX_CMD_LENGTH 128
#define MAX_RANGE_CONSISTENCY 1024
const int MAX_CMD_LENGTH = 128;
const int MAX_RANGE_CONSISTENCY = 1024;
#define RESOURCE_INDEX_BITS 12
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
const int RESOURCE_INDEX_BITS = 12;
const int RESOURCE_MAX_COUNT = BIT(RESOURCE_INDEX_BITS);
constexpr char *FILE_INI_RESOURCES = "resources.ini";
enum flag_type_log
{
@ -98,6 +117,7 @@ private:
private:
// for temporary files of responses
void AddHeadResource();
void AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash);
void LogPrepare();
@ -111,14 +131,18 @@ private:
typedef std::vector<CResourceBuffer *> ResourceList;
typedef std::vector<CResponseBuffer *> ResponseList;
static constexpr char *m_TypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" };
static constexpr char *m_HeadFileName = "delta.lst";
ResourceList m_resourceList;
ResponseList m_responseList;
resource_t m_HeadResource;
int m_ConsistencyNum;
uint32 m_PrevHash;
char m_PathDir[MAX_PATH];
char m_LogFilePath[MAX_PATH]; // log data
char m_LogFilePath[MAX_PATH]; // Log data
typedef std::vector<const char *> StringList;
static StringList m_StringsCache;

View File

@ -1,3 +1,21 @@
/*
*
* 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
*
*/
#include "precompiled.h"
void UTIL_Printf(const char *fmt, ...)
@ -6,7 +24,7 @@ void UTIL_Printf(const char *fmt, ...)
static char string[1024];
va_start(argptr, fmt);
vsnprintf(string, sizeof(string), fmt, argptr);
Q_vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr);
// Print to server console
@ -19,7 +37,7 @@ void UTIL_LogPrintf(const char *fmt, ...)
static char string[1024];
va_start(argptr, fmt);
vsnprintf(string, sizeof(string), fmt, argptr);
Q_vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr);
// Print to log
@ -32,7 +50,7 @@ char *UTIL_VarArgs(const char *format, ...)
static char string[1024];
va_start(argptr, format);
vsnprintf(string, sizeof(string), format, argptr);
Q_vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr);
return string;
@ -44,7 +62,7 @@ void NORETURN Sys_Error(const char *error, ...)
static char text[1024];
va_start(argptr, error);
vsnprintf(text, ARRAYSIZE(text), error, argptr);
Q_vsnprintf(text, ARRAYSIZE(text), error, argptr);
va_end(argptr);
#ifdef _WIN32
@ -57,6 +75,7 @@ void NORETURN Sys_Error(const char *error, ...)
UTIL_Printf("FATAL ERROR (shutting down): %s\n", text);
//TerminateProcess(GetCurrentProcess(), 1);
*((int*)NULL) = 0;
while (true);
int *null = 0;
*null = 0;
exit(-1);
}

View File

@ -1,75 +0,0 @@
#include "precompiled.h"
CTaskMngr Task;
CTaskMngr::CBufTask::CBufTask(IGameClient *pClient, float time, xtask_t handler)
{
m_pClient = pClient;
m_Handler = handler;
m_EndTime = gpGlobals->time + time;
}
void CTaskMngr::AddTask(IGameClient *pClient, float time, xtask_t handler)
{
g_pFunctionTable->pfnStartFrame = ::StartFrame;
m_taskList.push_back(new CBufTask(pClient, time, handler));
}
void CTaskMngr::StartFrame()
{
if (m_taskList.empty())
{
// more not to call
g_pFunctionTable->pfnStartFrame = NULL;
return;
}
if (m_nextFrame > gpGlobals->time)
return;
auto iter = m_taskList.begin();
while (iter != m_taskList.end())
{
CBufTask *pTask = (*iter);
if (pTask->GetEndTime() >= gpGlobals->time)
{
iter++;
continue;
}
// is call a callback
pTask->Handler();
// erase task
delete pTask;
iter = m_taskList.erase(iter);
}
m_nextFrame = gpGlobals->time + TASK_FREQUENCY_TIME;
}
void CTaskMngr::Clear(IGameClient *pClient)
{
if (pClient == NULL)
{
// reset next frame on level change
m_nextFrame = 0;
}
auto iter = m_taskList.begin();
while (iter != m_taskList.end())
{
CBufTask *pTask = (*iter);
if (pClient != NULL && pTask->GetClient() != pClient)
{
iter++;
continue;
}
// erase task
delete pTask;
iter = m_taskList.erase(iter);
}
}

View File

@ -1,39 +0,0 @@
#pragma once
#define TASK_FREQUENCY_TIME 0.1f // check frequency current tasks
typedef void (*xtask_t)(IGameClient *);
class CTaskMngr
{
public:
void AddTask(IGameClient *pClient, float time, xtask_t handler);
void StartFrame();
void Clear(IGameClient *pClient = NULL);
private:
class CBufTask
{
public:
CBufTask(IGameClient *pClient, float time, xtask_t handler);
IGameClient *GetClient() const { return m_pClient; };
float GetEndTime() const { return m_EndTime; };
void Handler() const { m_Handler(m_pClient); };
private:
IGameClient *m_pClient;
xtask_t m_Handler;
float m_EndTime;
};
typedef std::vector<CBufTask *> CBufTaskList;
CBufTaskList m_taskList;
float m_nextFrame;
};
extern CTaskMngr Task;
extern DLL_FUNCTIONS *g_pFunctionTable;
extern void StartFrame();