mirror of
https://github.com/rehlds/rechecker.git
synced 2025-01-12 11:47:54 +03:00
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:
parent
d1d4c4766c
commit
9cdd1d1be8
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "archtypes.h"
|
#include "archtypes.h"
|
||||||
#include "maintypes.h"
|
#include "maintypes.h"
|
||||||
#include "regamedll_common.h"
|
#include "strtools.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
@ -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
|
|
@ -25,6 +25,7 @@
|
|||||||
* version.
|
* version.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
template<typename t_ret, typename ...t_args>
|
template<typename t_ret, typename ...t_args>
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifdef _WIN32 // WINDOWS
|
#ifdef _WIN32 // WINDOWS
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#include <wsipx.h> // for support IPX
|
#include <wsipx.h> // for support IPX
|
||||||
@ -102,12 +103,15 @@
|
|||||||
#ifndef CDECL
|
#ifndef CDECL
|
||||||
#define CDECL __cdecl
|
#define CDECL __cdecl
|
||||||
#endif
|
#endif
|
||||||
|
#define FASTCALL __fastcall
|
||||||
#define STDCALL __stdcall
|
#define STDCALL __stdcall
|
||||||
#define HIDDEN
|
#define HIDDEN
|
||||||
|
#define FORCEINLINE __forceinline
|
||||||
#define NOINLINE __declspec(noinline)
|
#define NOINLINE __declspec(noinline)
|
||||||
#define ALIGN16 __declspec(align(16))
|
#define ALIGN16 __declspec(align(16))
|
||||||
#define NORETURN __declspec(noreturn)
|
#define NORETURN __declspec(noreturn)
|
||||||
#define FORCE_STACK_ALIGN
|
#define FORCE_STACK_ALIGN
|
||||||
|
#define FUNC_TARGET(x)
|
||||||
|
|
||||||
#define __builtin_bswap16 _byteswap_ushort
|
#define __builtin_bswap16 _byteswap_ushort
|
||||||
#define __builtin_bswap32 _byteswap_ulong
|
#define __builtin_bswap32 _byteswap_ulong
|
||||||
@ -146,18 +150,24 @@
|
|||||||
typedef unsigned short WORD;
|
typedef unsigned short WORD;
|
||||||
typedef unsigned int UNINT32;
|
typedef unsigned int UNINT32;
|
||||||
|
|
||||||
|
#define FASTCALL
|
||||||
#define CDECL __attribute__ ((cdecl))
|
#define CDECL __attribute__ ((cdecl))
|
||||||
#define STDCALL __attribute__ ((stdcall))
|
#define STDCALL __attribute__ ((stdcall))
|
||||||
#define HIDDEN __attribute__((visibility("hidden")))
|
#define HIDDEN __attribute__((visibility("hidden")))
|
||||||
|
#define FORCEINLINE inline
|
||||||
#define NOINLINE __attribute__((noinline))
|
#define NOINLINE __attribute__((noinline))
|
||||||
#define ALIGN16 __attribute__((aligned(16)))
|
#define ALIGN16 __attribute__((aligned(16)))
|
||||||
#define NORETURN __attribute__((noreturn))
|
#define NORETURN __attribute__((noreturn))
|
||||||
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
|
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
|
||||||
|
|
||||||
#if defined __INTEL_COMPILER
|
#if defined __INTEL_COMPILER
|
||||||
|
#define FUNC_TARGET(x)
|
||||||
|
|
||||||
#define __builtin_bswap16 _bswap16
|
#define __builtin_bswap16 _bswap16
|
||||||
#define __builtin_bswap32 _bswap
|
#define __builtin_bswap32 _bswap
|
||||||
#define __builtin_bswap64 _bswap64
|
#define __builtin_bswap64 _bswap64
|
||||||
|
#else
|
||||||
|
#define FUNC_TARGET(x) __attribute__((target(x)))
|
||||||
#endif // __INTEL_COMPILER
|
#endif // __INTEL_COMPILER
|
||||||
|
|
||||||
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
|
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
|
||||||
|
@ -166,6 +166,7 @@
|
|||||||
<ClInclude Include="..\public\rechecker_interfaces.h" />
|
<ClInclude Include="..\public\rechecker_interfaces.h" />
|
||||||
<ClInclude Include="..\src\cmdexec.h" />
|
<ClInclude Include="..\src\cmdexec.h" />
|
||||||
<ClInclude Include="..\src\hookchains_impl.h" />
|
<ClInclude Include="..\src\hookchains_impl.h" />
|
||||||
|
<ClInclude Include="..\src\rechecker_api.h" />
|
||||||
<ClInclude Include="..\src\rechecker_api_impl.h" />
|
<ClInclude Include="..\src\rechecker_api_impl.h" />
|
||||||
<ClInclude Include="..\src\resource.h" />
|
<ClInclude Include="..\src\resource.h" />
|
||||||
<ClInclude Include="..\src\engine_rehlds.h" />
|
<ClInclude Include="..\src\engine_rehlds.h" />
|
||||||
|
@ -467,6 +467,7 @@
|
|||||||
<ClInclude Include="..\public\rechecker_interfaces.h">
|
<ClInclude Include="..\public\rechecker_interfaces.h">
|
||||||
<Filter>public</Filter>
|
<Filter>public</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\rechecker_api.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\common\parsemsg.cpp">
|
<ClCompile Include="..\common\parsemsg.cpp">
|
||||||
|
@ -145,9 +145,12 @@ inline char *_strlwr(char *start)
|
|||||||
#endif // #if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS)
|
#endif // #if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS)
|
||||||
|
|
||||||
// a safe variant of strcpy that truncates the result to fit in the destination buffer
|
// a safe variant of strcpy that truncates the result to fit in the destination buffer
|
||||||
template <size_t size>
|
template <typename T, size_t size>
|
||||||
char *Q_strlcpy(char (&dest)[size], const char *src) {
|
T *Q_strlcpy(T (&dest)[size], const char *src)
|
||||||
Q_strncpy(dest, src, size - 1);
|
{
|
||||||
|
static_assert(sizeof(T) == sizeof(char), "invalid size of type != sizeof(char)");
|
||||||
|
|
||||||
|
Q_strncpy((char *)dest, src, size - 1);
|
||||||
dest[size - 1] = '\0';
|
dest[size - 1] = '\0';
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
@ -160,9 +163,11 @@ inline char *Q_strnlcpy(char *dest, const char *src, size_t n) {
|
|||||||
|
|
||||||
// safely concatenate two strings.
|
// safely concatenate two strings.
|
||||||
// a variant of strcat that truncates the result to fit in the destination buffer
|
// a variant of strcat that truncates the result to fit in the destination buffer
|
||||||
template <size_t size>
|
template <typename T, size_t size>
|
||||||
size_t Q_strlcat(char (&dest)[size], const char *src)
|
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 srclen; // Length of source string
|
||||||
size_t dstlen; // Length of destination string
|
size_t dstlen; // Length of destination string
|
||||||
|
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
CExecMngr Exec;
|
CExecMngr Exec;
|
||||||
@ -26,14 +44,15 @@ void StringReplace(char *src, const char *strold, const char *strnew)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
char *p = src;
|
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)
|
if (oldLen != newLen) {
|
||||||
memmove(p + newLen, p + oldLen, strlen(p) - oldLen + 1);
|
Q_memmove(p + newLen, p + oldLen, Q_strlen(p) - oldLen + 1);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(p, strnew, newLen);
|
Q_memcpy(p, strnew, newLen);
|
||||||
p += newLen;
|
p += newLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,22 +64,21 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
|
|||||||
const netadr_t *net;
|
const netadr_t *net;
|
||||||
static char string[256];
|
static char string[256];
|
||||||
|
|
||||||
// check cmdexec is empty
|
// Check cmdexec is empty
|
||||||
if (!pResource->GetCmdExec())
|
if (!pResource->GetCmdExec())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
strncpy(string, pResource->GetCmdExec(), sizeof(string) - 1);
|
Q_strlcpy(string, pResource->GetCmdExec());
|
||||||
string[sizeof(string) - 1] = '\0';
|
|
||||||
|
|
||||||
net = pClient->GetNetChan()->GetRemoteAdr();
|
net = pClient->GetNetChan()->GetRemoteAdr();
|
||||||
nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
||||||
|
|
||||||
// replace key values
|
// Replace key values
|
||||||
StringReplace(string, "[file_name]", pResource->GetFileName());
|
StringReplace(string, "[file_name]", pResource->GetFileName());
|
||||||
StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", responseHash));
|
StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", responseHash));
|
||||||
StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", _byteswap_ulong(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, "[userid]", UTIL_VarArgs("#%u", nUserID));
|
||||||
StringReplace(string, "[steamid]", UTIL_VarArgs("%s", g_engfuncs.pfnGetPlayerAuthId(pClient->GetEdict())));
|
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]));
|
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());
|
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)
|
if (len < sizeof(string) - 2)
|
||||||
strcat(string, "\n");
|
strcat(string, "\n");
|
||||||
@ -83,7 +101,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
|
|||||||
|
|
||||||
bool haveAtLeastOneExecuted = false;
|
bool haveAtLeastOneExecuted = false;
|
||||||
void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cmdExec, uint32 responseHash) {
|
void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cmdExec, uint32 responseHash) {
|
||||||
// execute cmdexec
|
// Execute cmdexec
|
||||||
SERVER_COMMAND(cmdExec);
|
SERVER_COMMAND(cmdExec);
|
||||||
haveAtLeastOneExecuted = true;
|
haveAtLeastOneExecuted = true;
|
||||||
}
|
}
|
||||||
@ -96,8 +114,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
|||||||
|
|
||||||
while (iter != m_execList.end())
|
while (iter != m_execList.end())
|
||||||
{
|
{
|
||||||
CBufExec *pExec = (*iter);
|
auto pExec = (*iter);
|
||||||
|
|
||||||
if (pExec->GetUserID() != nUserID)
|
if (pExec->GetUserID() != nUserID)
|
||||||
{
|
{
|
||||||
iter++;
|
iter++;
|
||||||
@ -106,14 +123,13 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
|||||||
|
|
||||||
CResourceBuffer *pRes = pExec->GetResource();
|
CResourceBuffer *pRes = pExec->GetResource();
|
||||||
|
|
||||||
// exit the loop if the client is out of the game
|
// Exit the loop if the client is out of the game
|
||||||
// TODO: Check me!
|
|
||||||
if (!pClient->IsConnected())
|
if (!pClient->IsConnected())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// erase all cmdexec because have flag is break
|
// Erase all cmdexec because have flag is break
|
||||||
if (!bBreak)
|
if (!bBreak)
|
||||||
{
|
{
|
||||||
char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash());
|
char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash());
|
||||||
@ -125,7 +141,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
|||||||
bBreak = pRes->IsBreak();
|
bBreak = pRes->IsBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
// erase cmdexec
|
// Erase cmdexec
|
||||||
delete pExec;
|
delete pExec;
|
||||||
iter = m_execList.erase(iter);
|
iter = m_execList.erase(iter);
|
||||||
}
|
}
|
||||||
@ -152,9 +168,9 @@ void CExecMngr::Clear(IGameClient *pClient)
|
|||||||
auto iter = m_execList.begin();
|
auto iter = m_execList.begin();
|
||||||
while (iter != m_execList.end())
|
while (iter != m_execList.end())
|
||||||
{
|
{
|
||||||
CBufExec *pExec = (*iter);
|
auto pExec = (*iter);
|
||||||
|
|
||||||
// erase cmdexec
|
// Erase cmdexec
|
||||||
if (pExec->GetUserID() != nUserID)
|
if (pExec->GetUserID() != nUserID)
|
||||||
{
|
{
|
||||||
iter++;
|
iter++;
|
||||||
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
class CExecMngr
|
class CExecMngr
|
||||||
|
@ -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);
|
|
||||||
}
|
|
26
src/config.h
26
src/config.h
@ -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;
|
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
DLL_FUNCTIONS *g_pFunctionTable;
|
DLL_FUNCTIONS *g_pFunctionTable;
|
||||||
|
|
||||||
extern void ServerDeactivate_Post();
|
|
||||||
|
|
||||||
static DLL_FUNCTIONS gFunctionTable =
|
static DLL_FUNCTIONS gFunctionTable =
|
||||||
{
|
{
|
||||||
NULL, // pfnGameInit
|
NULL, // pfnGameInit
|
||||||
@ -148,7 +164,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
|
Q_memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
|
||||||
g_pFunctionTable = pFunctionTable;
|
g_pFunctionTable = pFunctionTable;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -170,7 +186,7 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
|
Q_memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
|
||||||
g_pFunctionTable = pFunctionTable;
|
g_pFunctionTable = pFunctionTable;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
enginefuncs_t meta_engfuncs_post =
|
enginefuncs_t meta_engfuncs_post =
|
||||||
@ -227,6 +245,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
|
Q_memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
IRehldsApi *g_RehldsApi;
|
IRehldsApi *g_RehldsApi;
|
||||||
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
enum rehlds_ret
|
enum rehlds_ret
|
||||||
|
@ -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 ========================================================
|
* 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
|
||||||
Entity classes exported by Halflife.
|
* 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 "precompiled.h"
|
||||||
|
|
||||||
// From SDK dlls/h_export.cpp:
|
// Holds engine functionality callbacks
|
||||||
|
|
||||||
//! Holds engine functionality callbacks
|
|
||||||
enginefuncs_t g_engfuncs;
|
enginefuncs_t g_engfuncs;
|
||||||
globalvars_t *gpGlobals;
|
globalvars_t *gpGlobals;
|
||||||
|
|
||||||
@ -35,6 +27,6 @@ globalvars_t *gpGlobals;
|
|||||||
// do some setup operations here.
|
// do some setup operations here.
|
||||||
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
|
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;
|
gpGlobals = pGlobals;
|
||||||
}
|
}
|
||||||
|
@ -76,15 +76,17 @@ void AbstractHookChainRegistry::removeHook(void *hookFunc) {
|
|||||||
{
|
{
|
||||||
if (hookFunc == m_Hooks[i])
|
if (hookFunc == m_Hooks[i])
|
||||||
{
|
{
|
||||||
--m_NumHooks;
|
m_NumHooks--;
|
||||||
if (m_NumHooks != i)
|
if (m_NumHooks != i)
|
||||||
{
|
{
|
||||||
Q_memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
|
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]));
|
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
|
else
|
||||||
m_Hooks[i] = NULL;
|
{
|
||||||
|
m_Hooks[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -14,22 +14,26 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 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
|
#pragma once
|
||||||
|
|
||||||
#include "hookchains.h"
|
#include "hookchains.h"
|
||||||
|
|
||||||
const int MAX_HOOKS_IN_CHAIN = 19;
|
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
|
// Implementation for chains in modules
|
||||||
template<typename t_ret, typename ...t_args>
|
template<typename t_ret, typename ...t_args>
|
||||||
class IHookChainImpl: public IHookChain<t_ret, 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)
|
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__);
|
Sys_Error("%s: Non-void HookChain without original function.", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,46 +58,11 @@ public:
|
|||||||
return nexthook(&nextChain, args...);
|
return nexthook(&nextChain, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_OriginalFunc(args...);
|
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual t_ret callOriginal(t_args... args) {
|
virtual t_ret callOriginal(t_args... args) {
|
||||||
return m_OriginalFunc(args...);
|
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
|
||||||
}
|
|
||||||
|
|
||||||
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...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -116,10 +85,10 @@ public:
|
|||||||
AbstractHookChainRegistry();
|
AbstractHookChainRegistry();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename t_ret, typename ...t_args>
|
template <typename t_ret, typename ...t_args>
|
||||||
class IHookChainRegistryImpl : public IHookChainRegistry < t_ret, t_args...>, public AbstractHookChainRegistry {
|
class IHookChainRegistryImpl: public IHookChainRegistry<t_ret, t_args...>, public AbstractHookChainRegistry {
|
||||||
public:
|
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...);
|
typedef t_ret (*origfunc_t)(t_args...);
|
||||||
|
|
||||||
virtual ~IHookChainRegistryImpl() { }
|
virtual ~IHookChainRegistryImpl() { }
|
||||||
@ -136,25 +105,3 @@ public:
|
|||||||
removeHook((void *)hook);
|
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
68
src/main.cpp
68
src/main.cpp
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, NULL };
|
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, nullptr };
|
||||||
cvar_t *pcv_consistency_old = NULL;
|
cvar_t *pcv_consistency_old = nullptr;
|
||||||
|
|
||||||
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
|
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);
|
qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);
|
||||||
@ -13,14 +31,14 @@ bool OnMetaAttach()
|
|||||||
|
|
||||||
g_pResource = new CResourceFile();
|
g_pResource = new CResourceFile();
|
||||||
|
|
||||||
// initialize resource config
|
// Initialize resource environment
|
||||||
g_pResource->Init();
|
g_pResource->Init();
|
||||||
Rechecker_Api_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_");
|
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");
|
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
||||||
|
|
||||||
@ -34,7 +52,7 @@ bool OnMetaAttach()
|
|||||||
}
|
}
|
||||||
else
|
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
|
// 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.
|
// so for engine set it the cvar values is 1.
|
||||||
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
||||||
@ -50,13 +68,13 @@ bool OnMetaAttach()
|
|||||||
|
|
||||||
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, "1");
|
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();
|
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 (var == pcv_consistency_old)
|
||||||
{
|
{
|
||||||
if (prev != NULL)
|
if (prev)
|
||||||
prev->next = var->next;
|
prev->next = var->next;
|
||||||
else
|
else
|
||||||
cvar_vars = cvar_vars->next;
|
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_DropClient()->registerHook(&SV_DropClient);
|
||||||
g_RehldsHookchains->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse);
|
g_RehldsHookchains->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse);
|
||||||
g_RehldsHookchains->SV_TransferConsistencyInfo()->registerHook(&SV_TransferConsistencyInfo);
|
g_RehldsHookchains->SV_TransferConsistencyInfo()->registerHook(&SV_TransferConsistencyInfo);
|
||||||
@ -74,7 +92,7 @@ bool OnMetaAttach()
|
|||||||
SV_AddResource = g_RehldsFuncs->SV_AddResource;
|
SV_AddResource = g_RehldsFuncs->SV_AddResource;
|
||||||
SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList;
|
SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList;
|
||||||
|
|
||||||
// go to attach
|
// Go to attach
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,19 +100,19 @@ void OnMetaDetach()
|
|||||||
{
|
{
|
||||||
cvar_t *pcv_mp_consistency = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
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;
|
const char *tempName = pcv_consistency_old->name;
|
||||||
pcv_consistency_old->name = cv_mp_consistency.name;
|
pcv_consistency_old->name = cv_mp_consistency.name;
|
||||||
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, pcv_mp_consistency->string);
|
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, pcv_mp_consistency->string);
|
||||||
pcv_mp_consistency->name = tempName;
|
pcv_mp_consistency->name = tempName;
|
||||||
|
|
||||||
// restore old cvar mp_consistency
|
// Restore old cvar mp_consistency
|
||||||
cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars();
|
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 (var == pcv_mp_consistency)
|
||||||
{
|
{
|
||||||
if (prev != NULL)
|
if (prev)
|
||||||
prev->next = pcv_consistency_old;
|
prev->next = pcv_consistency_old;
|
||||||
else
|
else
|
||||||
cvar_vars = pcv_consistency_old;
|
cvar_vars = pcv_consistency_old;
|
||||||
@ -102,7 +120,7 @@ void OnMetaDetach()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear
|
// Clear
|
||||||
Exec.Clear();
|
Exec.Clear();
|
||||||
delete g_pResource;
|
delete g_pResource;
|
||||||
|
|
||||||
@ -117,7 +135,7 @@ void OnMetaDetach()
|
|||||||
|
|
||||||
void ServerDeactivate_Post()
|
void ServerDeactivate_Post()
|
||||||
{
|
{
|
||||||
// clear
|
// Clear
|
||||||
Exec.Clear();
|
Exec.Clear();
|
||||||
g_pResource->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)
|
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);
|
Exec.Clear(pClient);
|
||||||
|
|
||||||
// clear temporary files of response
|
// Clear temporary files of response
|
||||||
g_pResource->Clear(pClient);
|
g_pResource->Clear(pClient);
|
||||||
|
|
||||||
// call next hook
|
// Call next hook
|
||||||
chain->callNext(pClient, crash, string);
|
chain->callNext(pClient, crash, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,10 +158,10 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain)
|
|||||||
{
|
{
|
||||||
g_pResource->LoadResources();
|
g_pResource->LoadResources();
|
||||||
|
|
||||||
// add to the resource
|
// Add to the resource
|
||||||
int nConsistency = g_pResource->CreateResourceList();
|
int nConsistency = g_pResource->CreateResourceList();
|
||||||
|
|
||||||
// returns the total number of consistency files
|
// Returns the total number of consistency files
|
||||||
return chain->callNext() + nConsistency;
|
return chain->callNext() + nConsistency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +170,7 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
|
|||||||
if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash))
|
if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash))
|
||||||
return false;
|
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);
|
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);
|
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);
|
Exec.ExecuteCommand(pClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +197,7 @@ const int clc_fileconsistency = 7;
|
|||||||
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode)
|
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode)
|
||||||
{
|
{
|
||||||
if (opcode == clc_fileconsistency) {
|
if (opcode == clc_fileconsistency) {
|
||||||
// clear temporary files of response
|
// Clear temporary files of response
|
||||||
g_pResource->Clear(cl);
|
g_pResource->Clear(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
src/main.h
19
src/main.h
@ -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
|
#pragma once
|
||||||
|
|
||||||
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string);
|
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);
|
int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain);
|
||||||
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain);
|
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain);
|
||||||
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode);
|
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 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);
|
extern qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
plugin_info_t Plugin_info =
|
plugin_info_t Plugin_info =
|
||||||
{
|
{
|
||||||
META_INTERFACE_VERSION,
|
META_INTERFACE_VERSION,
|
||||||
"Rechecker",
|
"Rechecker",
|
||||||
"2.4",
|
"2.5",
|
||||||
__DATE__,
|
__DATE__,
|
||||||
"s1lent",
|
"s1lent",
|
||||||
"http://www.dedicated-server.ru/",
|
"http://www.dedicated-server.ru/",
|
||||||
@ -41,12 +59,11 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
|
|
||||||
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
@ -24,7 +42,6 @@
|
|||||||
#include "rechecker_api_impl.h"
|
#include "rechecker_api_impl.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "task.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "cmdexec.h"
|
#include "cmdexec.h"
|
||||||
|
|
||||||
|
@ -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"
|
#include "interface.cpp"
|
||||||
|
@ -14,17 +14,8 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 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
|
#pragma once
|
||||||
|
|
||||||
#include "hookchains.h"
|
#include "hookchains.h"
|
||||||
@ -45,16 +36,16 @@ enum ResourceType_e
|
|||||||
class IResourceBuffer;
|
class IResourceBuffer;
|
||||||
|
|
||||||
// FileConsistencyProcess hook
|
// FileConsistencyProcess hook
|
||||||
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
|
typedef IHookChain<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
|
||||||
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
|
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
|
||||||
|
|
||||||
// CmdExec hook
|
// CmdExec hook
|
||||||
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
|
typedef IHookChain<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
|
||||||
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
|
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
|
||||||
|
|
||||||
// FileConsistencyFinal hook
|
// FileConsistencyFinal hook
|
||||||
typedef IVoidHookChain<IGameClient *> IRecheckerHook_FileConsistencyFinal;
|
typedef IHookChain<void, IGameClient *> IRecheckerHook_FileConsistencyFinal;
|
||||||
typedef IVoidHookChainRegistry<IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
|
typedef IHookChainRegistry<void, IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
|
||||||
|
|
||||||
class IRecheckerHookchains {
|
class IRecheckerHookchains {
|
||||||
protected:
|
protected:
|
||||||
|
@ -14,17 +14,8 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
CRecheckerApi g_RecheckerApi;
|
CRecheckerApi g_RecheckerApi;
|
||||||
|
@ -14,30 +14,21 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 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
|
#pragma once
|
||||||
|
|
||||||
// FileConsistencyProcess hook
|
// FileConsistencyProcess hook
|
||||||
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
|
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
|
||||||
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
|
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
|
||||||
|
|
||||||
// CmdExec hook
|
// CmdExec hook
|
||||||
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
|
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
|
||||||
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
|
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
|
||||||
|
|
||||||
// FileConsistencyFinal hook
|
// FileConsistencyFinal hook
|
||||||
typedef IVoidHookChainImpl<IGameClient *> CRecheckerHook_FileConsistencyFinal;
|
typedef IHookChainImpl<void, IGameClient *> CRecheckerHook_FileConsistencyFinal;
|
||||||
typedef IVoidHookChainRegistryImpl<IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
|
typedef IHookChainRegistryImpl<void, IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
|
||||||
|
|
||||||
class CRecheckerHookchains: public IRecheckerHookchains {
|
class CRecheckerHookchains: public IRecheckerHookchains {
|
||||||
public:
|
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)
|
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];
|
this->filename = new char [Q_strlen(filename) + 1];
|
||||||
strcpy(this->filename, filename);
|
Q_strcpy(this->filename, filename);
|
||||||
|
|
||||||
this->flag = flag;
|
this->flag = flag;
|
||||||
this->hash = hash;
|
this->hash = hash;
|
||||||
|
229
src/resource.cpp
229
src/resource.cpp
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
CResourceFile *g_pResource = nullptr;
|
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 cv_rch_log = { "rch_log", "0", 0, 0.0f, nullptr };
|
||||||
cvar_t *pcv_rch_log = nullptr;
|
cvar_t *pcv_rch_log = nullptr;
|
||||||
|
|
||||||
const char *szTypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" };
|
|
||||||
|
|
||||||
CResourceFile::CResourceFile() :
|
CResourceFile::CResourceFile() :
|
||||||
m_resourceList(),
|
m_resourceList(),
|
||||||
m_responseList(),
|
m_responseList(),
|
||||||
@ -16,6 +32,8 @@ CResourceFile::CResourceFile() :
|
|||||||
{
|
{
|
||||||
m_PathDir[0] = '\0';
|
m_PathDir[0] = '\0';
|
||||||
m_LogFilePath[0] = '\0';
|
m_LogFilePath[0] = '\0';
|
||||||
|
|
||||||
|
Q_memset(&m_HeadResource, 0, sizeof(m_HeadResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
CResourceFile::~CResourceFile()
|
CResourceFile::~CResourceFile()
|
||||||
@ -25,20 +43,22 @@ CResourceFile::~CResourceFile()
|
|||||||
|
|
||||||
int CResourceFile::CreateResourceList()
|
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();
|
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)
|
for (auto res : m_resourceList)
|
||||||
{
|
{
|
||||||
// prevent duplicate of filenames
|
// Prevent duplicate of filenames
|
||||||
// check if filename is been marked so do not add the resource again
|
// Check if filename is been marked so do not add the resource again
|
||||||
if (!res->IsDuplicate())
|
if (!res->IsDuplicate())
|
||||||
{
|
{
|
||||||
// check limit resource
|
// Check limit resource
|
||||||
if (g_RehldsServerData->GetResourcesNum() >= RESOURCE_MAX_COUNT)
|
if (g_RehldsServerData->GetResourcesNum() >= RESOURCE_MAX_COUNT)
|
||||||
{
|
{
|
||||||
if (res->IsAddEx()) {
|
if (res->IsAddEx()) {
|
||||||
@ -50,7 +70,7 @@ int CResourceFile::CreateResourceList()
|
|||||||
break;
|
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
|
// https://github.com/dreamstalker/rehlds/blob/beaeb65/rehlds/engine/sv_user.cpp#L374
|
||||||
if (nCustomConsistency + m_ConsistencyNum >= MAX_RANGE_CONSISTENCY)
|
if (nCustomConsistency + m_ConsistencyNum >= MAX_RANGE_CONSISTENCY)
|
||||||
{
|
{
|
||||||
@ -63,13 +83,21 @@ int CResourceFile::CreateResourceList()
|
|||||||
break;
|
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, nIndex++);
|
||||||
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, startIndex++);
|
|
||||||
nCustomConsistency++;
|
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++)
|
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
|
||||||
{
|
{
|
||||||
sortList.push_back(*g_RehldsServerData->GetResource(i));
|
sortList.push_back(*g_RehldsServerData->GetResource(i));
|
||||||
@ -78,7 +106,7 @@ int CResourceFile::CreateResourceList()
|
|||||||
// Start a first resource list
|
// Start a first resource list
|
||||||
g_RehldsServerData->SetResourcesNum(0);
|
g_RehldsServerData->SetResourcesNum(0);
|
||||||
|
|
||||||
// sort
|
// Sorting
|
||||||
std::sort(sortList.begin(), sortList.end(), [](const resource_t &a, const resource_t &b)
|
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);
|
bool a_cons = (a.ucFlags & RES_CHECKFILE) || SV_FileInConsistencyList(a.szFileName, nullptr);
|
||||||
@ -93,6 +121,9 @@ int CResourceFile::CreateResourceList()
|
|||||||
return a.nIndex < b.nIndex;
|
return a.nIndex < b.nIndex;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Insert to front head resource
|
||||||
|
sortList.insert(sortList.begin(), m_HeadResource);
|
||||||
|
|
||||||
for (auto& res : sortList)
|
for (auto& res : sortList)
|
||||||
{
|
{
|
||||||
// Add new resource in the own order
|
// Add new resource in the own order
|
||||||
@ -107,47 +138,60 @@ void CResourceFile::ComputeConsistencyFiles()
|
|||||||
{
|
{
|
||||||
m_ConsistencyNum = 0;
|
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);
|
auto res = g_RehldsServerData->GetResource(i);
|
||||||
if (res->ucFlags == (RES_CUSTOM | RES_REQUESTED | RES_UNK_6) || (res->ucFlags & RES_CHECKFILE))
|
if (res->ucFlags == (RES_CUSTOM | RES_REQUESTED | RES_UNK_6) || (res->ucFlags & RES_CHECKFILE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (SV_FileInConsistencyList(res->szFileName, nullptr))
|
if (!SV_FileInConsistencyList(res->szFileName, nullptr))
|
||||||
++m_ConsistencyNum;
|
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)
|
void CResourceFile::Clear(IGameClient *pClient)
|
||||||
{
|
{
|
||||||
if (pClient)
|
if (pClient)
|
||||||
{
|
{
|
||||||
// remove each entries by pClient
|
// Remove each entries by pClient
|
||||||
auto nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
auto nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
||||||
auto iter = m_responseList.begin();
|
auto iter = m_responseList.begin();
|
||||||
while (iter != m_responseList.end())
|
while (iter != m_responseList.end())
|
||||||
{
|
{
|
||||||
CResponseBuffer *pFiles = (*iter);
|
auto pFiles = (*iter);
|
||||||
|
|
||||||
// erase cmdexec
|
// Erase cmdexec
|
||||||
if (pFiles->GetUserID() == nUserID)
|
if (pFiles->GetUserID() != nUserID)
|
||||||
{
|
{
|
||||||
delete pFiles;
|
|
||||||
iter = m_responseList.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
iter++;
|
iter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pFiles;
|
||||||
|
iter = m_responseList.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PrevHash = 0;
|
m_PrevHash = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove all
|
// Remove all
|
||||||
m_PrevHash = 0;
|
m_PrevHash = 0;
|
||||||
m_ConsistencyNum = 0;
|
m_ConsistencyNum = 0;
|
||||||
|
|
||||||
// clear resources
|
// Clear resources
|
||||||
for (auto it : m_resourceList)
|
for (auto it : m_resourceList)
|
||||||
delete it;
|
delete it;
|
||||||
|
|
||||||
@ -190,10 +234,10 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
|
|||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
strcat(string, "\n");
|
Q_strlcat(string, "\n");
|
||||||
|
|
||||||
td = time(nullptr);
|
td = time(nullptr);
|
||||||
lt = localtime(&td);
|
lt = localtime(&td);
|
||||||
@ -202,7 +246,7 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
|
|||||||
|
|
||||||
if (!bFirst)
|
if (!bFirst)
|
||||||
{
|
{
|
||||||
file = strrchr(m_LogFilePath, '/');
|
file = Q_strrchr(m_LogFilePath, '/');
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
file = "<null>";
|
file = "<null>";
|
||||||
|
|
||||||
@ -239,23 +283,20 @@ void CResourceFile::Init()
|
|||||||
char *pos;
|
char *pos;
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
|
|
||||||
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
|
Q_strlcpy(path, GET_PLUGIN_PATH(PLID));
|
||||||
path[sizeof(path) - 1] = '\0';
|
pos = Q_strrchr(path, '/');
|
||||||
|
|
||||||
pos = strrchr(path, '/');
|
|
||||||
|
|
||||||
if (*pos == '\0')
|
if (*pos == '\0')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*(pos + 1) = '\0';
|
*(pos + 1) = '\0';
|
||||||
|
|
||||||
strncpy(m_LogFilePath, path, sizeof(m_LogFilePath) - 1);
|
Q_strlcpy(m_LogFilePath, path);
|
||||||
m_LogFilePath[sizeof(m_LogFilePath) - 1] = '\0';
|
Q_strlcat(m_LogFilePath, "logs/");
|
||||||
strcat(m_LogFilePath, "logs/");
|
|
||||||
CreateDirectory(m_LogFilePath);
|
CreateDirectory(m_LogFilePath);
|
||||||
|
|
||||||
// resources.ini
|
// 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);
|
g_engfuncs.pfnCvar_RegisterVariable(&cv_rch_log);
|
||||||
pcv_rch_log = g_engfuncs.pfnCVarGetPointer(cv_rch_log.name);
|
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)
|
inline bool invalidchar(const char c)
|
||||||
{
|
{
|
||||||
// to check for invalid characters
|
// To check for invalid characters
|
||||||
return (c == '\\' || c == '/' || c == ':'
|
return (c == '\\' || c == '/' || c == ':'
|
||||||
|| c == '*' || c == '?'
|
|| c == '*' || c == '?'
|
||||||
|| c == '"' || c == '<'
|
|| c == '"' || c == '<'
|
||||||
@ -278,7 +319,7 @@ inline bool invalidchar(const char c)
|
|||||||
|
|
||||||
bool IsValidFilename(char *psrc, char &pchar)
|
bool IsValidFilename(char *psrc, char &pchar)
|
||||||
{
|
{
|
||||||
char *pch = strrchr(psrc, '/');
|
char *pch = Q_strrchr(psrc, '/');
|
||||||
if (!pch)
|
if (!pch)
|
||||||
pch = psrc;
|
pch = psrc;
|
||||||
|
|
||||||
@ -296,16 +337,16 @@ bool IsValidFilename(char *psrc, char &pchar)
|
|||||||
|
|
||||||
bool IsFileHasExtension(char *psrc)
|
bool IsFileHasExtension(char *psrc)
|
||||||
{
|
{
|
||||||
// find the extension filename
|
// Find the extension filename
|
||||||
char *pch = strrchr(psrc, '.');
|
char *pch = Q_strrchr(psrc, '.');
|
||||||
if (!pch)
|
if (!pch)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// the size extension
|
// The size extension
|
||||||
if (strlen(&pch[1]) <= 0)
|
if (Q_strlen(&pch[1]) <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return strchr(pch, '/') == nullptr;
|
return Q_strchr(pch, '/') == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceFile::LogPrepare()
|
void CResourceFile::LogPrepare()
|
||||||
@ -318,14 +359,14 @@ void CResourceFile::LogPrepare()
|
|||||||
td = time(nullptr);
|
td = time(nullptr);
|
||||||
lt = localtime(&td);
|
lt = localtime(&td);
|
||||||
|
|
||||||
// remove path to log file
|
// Remove path to log file
|
||||||
if ((pos = strrchr(m_LogFilePath, '/')) != nullptr)
|
if ((pos = Q_strrchr(m_LogFilePath, '/')))
|
||||||
{
|
{
|
||||||
*(pos + 1) = '\0';
|
*(pos + 1) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
strftime(dateFile, sizeof(dateFile), "L_%d_%m_%Y.log", lt);
|
strftime(dateFile, sizeof(dateFile), "L_%d_%m_%Y.log", lt);
|
||||||
strcat(m_LogFilePath, dateFile);
|
Q_strlcat(m_LogFilePath, dateFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceFile::LoadResources()
|
void CResourceFile::LoadResources()
|
||||||
@ -335,7 +376,6 @@ void CResourceFile::LoadResources()
|
|||||||
uint8 hash[16];
|
uint8 hash[16];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int argc;
|
int argc;
|
||||||
int len;
|
|
||||||
ResourceType_e flag;
|
ResourceType_e flag;
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
char cmdBufExec[MAX_PATH];
|
char cmdBufExec[MAX_PATH];
|
||||||
@ -352,7 +392,7 @@ void CResourceFile::LoadResources()
|
|||||||
|
|
||||||
while (!feof(fp) && fgets(line, sizeof(line), fp))
|
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)
|
if ((byte)line[0] == 0xEFu && (byte)line[1] == 0xBBu && (byte)line[2] == 0xBFu)
|
||||||
pos = &line[3];
|
pos = &line[3];
|
||||||
else
|
else
|
||||||
@ -369,38 +409,33 @@ void CResourceFile::LoadResources()
|
|||||||
bBreak = false;
|
bBreak = false;
|
||||||
flag = RES_TYPE_NONE;
|
flag = RES_TYPE_NONE;
|
||||||
|
|
||||||
memset(hash, 0, sizeof(hash));
|
Q_memset(hash, 0, sizeof(hash));
|
||||||
|
|
||||||
while (pToken && argc <= MAX_PARSE_ARGUMENT)
|
while (pToken && argc <= MAX_PARSE_ARGUMENT)
|
||||||
{
|
{
|
||||||
len = strlen(pToken);
|
|
||||||
|
|
||||||
switch (argc)
|
switch (argc)
|
||||||
{
|
{
|
||||||
case ARG_TYPE_FILE_NAME:
|
case ARG_TYPE_FILE_NAME:
|
||||||
{
|
{
|
||||||
strncpy(filename, pToken, len);
|
Q_strlcpy(filename, pToken);
|
||||||
filename[len] = '\0';
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARG_TYPE_FILE_HASH:
|
case ARG_TYPE_FILE_HASH:
|
||||||
{
|
{
|
||||||
uint8 pbuf[33];
|
uint8 pbuf[33];
|
||||||
|
Q_strlcpy(pbuf, pToken);
|
||||||
|
|
||||||
strncpy((char *)pbuf, pToken, len);
|
if (Q_stricmp((const char *)pbuf, "UNKNOWN") == 0)
|
||||||
pbuf[len] = '\0';
|
|
||||||
|
|
||||||
if (_stricmp((const char *)pbuf, "UNKNOWN") == 0)
|
|
||||||
{
|
{
|
||||||
flag = RES_TYPE_HASH_ANY;
|
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;
|
flag = RES_TYPE_MISSING;
|
||||||
}
|
}
|
||||||
else
|
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]);
|
hash[i] = hexbyte(&pbuf[i * 2]);
|
||||||
|
|
||||||
flag = RES_TYPE_EXISTS;
|
flag = RES_TYPE_EXISTS;
|
||||||
@ -409,33 +444,32 @@ void CResourceFile::LoadResources()
|
|||||||
}
|
}
|
||||||
case ARG_TYPE_CMD_EXEC:
|
case ARG_TYPE_CMD_EXEC:
|
||||||
{
|
{
|
||||||
strncpy(cmdBufExec, pToken, len);
|
Q_strlcpy(cmdBufExec, pToken);
|
||||||
cmdBufExec[len] = '\0';
|
|
||||||
|
|
||||||
if (_stricmp(cmdBufExec, "IGNORE") == 0)
|
if (Q_stricmp(cmdBufExec, "IGNORE") == 0)
|
||||||
{
|
{
|
||||||
flag = RES_TYPE_IGNORE;
|
flag = RES_TYPE_IGNORE;
|
||||||
cmdBufExec[0] = '\0';
|
cmdBufExec[0] = '\0';
|
||||||
}
|
}
|
||||||
else if (_stricmp(cmdBufExec, "BREAK") == 0)
|
else if (Q_stricmp(cmdBufExec, "BREAK") == 0)
|
||||||
{
|
{
|
||||||
bBreak = true;
|
bBreak = true;
|
||||||
cmdBufExec[0] = '\0';
|
cmdBufExec[0] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// replface \' to "
|
// Replace \' to "
|
||||||
StringReplace(cmdBufExec, "'", "\"");
|
StringReplace(cmdBufExec, "'", "\"");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARG_TYPE_FLAG:
|
case ARG_TYPE_FLAG:
|
||||||
{
|
{
|
||||||
if (_stricmp(pToken, "IGNORE") == 0)
|
if (Q_stricmp(pToken, "IGNORE") == 0)
|
||||||
{
|
{
|
||||||
flag = RES_TYPE_IGNORE;
|
flag = RES_TYPE_IGNORE;
|
||||||
}
|
}
|
||||||
else if (_stricmp(pToken, "BREAK") == 0)
|
else if (Q_stricmp(pToken, "BREAK") == 0)
|
||||||
{
|
{
|
||||||
bBreak = true;
|
bBreak = true;
|
||||||
}
|
}
|
||||||
@ -449,19 +483,19 @@ void CResourceFile::LoadResources()
|
|||||||
|
|
||||||
if (++argc == ARG_TYPE_FLAG && pToken == nullptr)
|
if (++argc == ARG_TYPE_FLAG && pToken == nullptr)
|
||||||
{
|
{
|
||||||
// go to next argument
|
// Go to next argument
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_PRINT_FAILED(str, ...)\
|
#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;
|
continue;
|
||||||
|
|
||||||
if (argc >= MAX_PARSE_ARGUMENT)
|
if (argc >= MAX_PARSE_ARGUMENT)
|
||||||
{
|
{
|
||||||
char pchar;
|
char pchar = '?';
|
||||||
if (strlen(filename) <= 0)
|
if (Q_strlen(filename) <= 0)
|
||||||
{
|
{
|
||||||
LOG_PRINT_FAILED("path to filename is empty on line %d\n", cline);
|
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);
|
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);
|
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')
|
if (*rpos == '\0')
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// skip spaces at the beginning
|
// Skip spaces at the beginning
|
||||||
while (*rpos != '\0' && isspace(*rpos))
|
while (*rpos != '\0' && isspace(*rpos))
|
||||||
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);
|
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)
|
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();
|
nRes->SetDuplicate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -593,7 +627,7 @@ void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceB
|
|||||||
// Fire query to callback's
|
// Fire query to callback's
|
||||||
for (auto query : g_QueryFiles)
|
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;
|
continue;
|
||||||
|
|
||||||
if (query->flag == typeFind) {
|
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);
|
Exec.Add(pSenderClient, pRes, hash);
|
||||||
g_pResource->PrintLog(pSenderClient, pRes, typeFind, 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;
|
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)",
|
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());
|
pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash), res->IsAddEx());
|
||||||
}
|
}
|
||||||
|
|
||||||
IResourceBuffer *CResourceFile::GetResourceFile(const char *filename)
|
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)
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -650,7 +684,7 @@ IResponseBuffer *CResourceFile::GetResponseFile(IGameClient *pClient, const char
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_stricmp(res->GetFileName(), filename) == 0) {
|
if (Q_stricmp(res->GetFileName(), filename) == 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -665,7 +699,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
|||||||
std::vector<CResourceBuffer *> tempResourceList;
|
std::vector<CResourceBuffer *> tempResourceList;
|
||||||
|
|
||||||
if (resource->type != t_decal
|
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
|
// to be sure not bypass the decals
|
||||||
{
|
{
|
||||||
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
||||||
@ -673,16 +707,28 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// strange thing
|
// Strange thing
|
||||||
// if this happened when missing all the files from client
|
// if this happened when missing all the files from client
|
||||||
if (!m_PrevHash)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto res : m_resourceList)
|
for (auto res : m_resourceList)
|
||||||
{
|
{
|
||||||
if (strcmp(resource->szFileName, res->GetFileName()) != 0)
|
if (Q_strcmp(resource->szFileName, res->GetFileName()) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
typeFind = res->GetFileFlag();
|
typeFind = res->GetFileFlag();
|
||||||
@ -704,7 +750,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
|||||||
case RES_TYPE_HASH_ANY:
|
case RES_TYPE_HASH_ANY:
|
||||||
for (auto temp : tempResourceList)
|
for (auto temp : tempResourceList)
|
||||||
{
|
{
|
||||||
if (_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
|
if (Q_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (temp->GetFileHash() == hash)
|
if (temp->GetFileHash() == hash)
|
||||||
@ -731,6 +777,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
|||||||
|
|
||||||
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
||||||
m_PrevHash = hash;
|
m_PrevHash = hash;
|
||||||
|
|
||||||
return !bHandled;
|
return !bHandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -738,11 +785,11 @@ const char *CResourceFile::DuplicateString(const char *str)
|
|||||||
{
|
{
|
||||||
for (auto string : m_StringsCache)
|
for (auto string : m_StringsCache)
|
||||||
{
|
{
|
||||||
if (!strcmp(string, str))
|
if (!Q_strcmp(string, str))
|
||||||
return string;
|
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);
|
m_StringsCache.push_back(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -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
|
#pragma once
|
||||||
|
|
||||||
#define FILE_INI_RESOURCES "resources.ini"
|
const int MAX_CMD_LENGTH = 128;
|
||||||
#define MAX_CMD_LENGTH 128
|
const int MAX_RANGE_CONSISTENCY = 1024;
|
||||||
#define MAX_RANGE_CONSISTENCY 1024
|
|
||||||
|
|
||||||
#define RESOURCE_INDEX_BITS 12
|
const int RESOURCE_INDEX_BITS = 12;
|
||||||
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
|
const int RESOURCE_MAX_COUNT = BIT(RESOURCE_INDEX_BITS);
|
||||||
|
|
||||||
|
constexpr char *FILE_INI_RESOURCES = "resources.ini";
|
||||||
|
|
||||||
enum flag_type_log
|
enum flag_type_log
|
||||||
{
|
{
|
||||||
@ -98,6 +117,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// for temporary files of responses
|
// for temporary files of responses
|
||||||
|
void AddHeadResource();
|
||||||
void AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash);
|
void AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash);
|
||||||
void LogPrepare();
|
void LogPrepare();
|
||||||
|
|
||||||
@ -111,14 +131,18 @@ private:
|
|||||||
typedef std::vector<CResourceBuffer *> ResourceList;
|
typedef std::vector<CResourceBuffer *> ResourceList;
|
||||||
typedef std::vector<CResponseBuffer *> ResponseList;
|
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;
|
ResourceList m_resourceList;
|
||||||
ResponseList m_responseList;
|
ResponseList m_responseList;
|
||||||
|
|
||||||
|
resource_t m_HeadResource;
|
||||||
int m_ConsistencyNum;
|
int m_ConsistencyNum;
|
||||||
uint32 m_PrevHash;
|
uint32 m_PrevHash;
|
||||||
|
|
||||||
char m_PathDir[MAX_PATH];
|
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;
|
typedef std::vector<const char *> StringList;
|
||||||
static StringList m_StringsCache;
|
static StringList m_StringsCache;
|
||||||
|
@ -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"
|
#include "precompiled.h"
|
||||||
|
|
||||||
void UTIL_Printf(const char *fmt, ...)
|
void UTIL_Printf(const char *fmt, ...)
|
||||||
@ -6,7 +24,7 @@ void UTIL_Printf(const char *fmt, ...)
|
|||||||
static char string[1024];
|
static char string[1024];
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
// Print to server console
|
// Print to server console
|
||||||
@ -19,7 +37,7 @@ void UTIL_LogPrintf(const char *fmt, ...)
|
|||||||
static char string[1024];
|
static char string[1024];
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
// Print to log
|
// Print to log
|
||||||
@ -32,7 +50,7 @@ char *UTIL_VarArgs(const char *format, ...)
|
|||||||
static char string[1024];
|
static char string[1024];
|
||||||
|
|
||||||
va_start(argptr, format);
|
va_start(argptr, format);
|
||||||
vsnprintf(string, sizeof(string), format, argptr);
|
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
@ -44,7 +62,7 @@ void NORETURN Sys_Error(const char *error, ...)
|
|||||||
static char text[1024];
|
static char text[1024];
|
||||||
|
|
||||||
va_start(argptr, error);
|
va_start(argptr, error);
|
||||||
vsnprintf(text, ARRAYSIZE(text), error, argptr);
|
Q_vsnprintf(text, ARRAYSIZE(text), error, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -57,6 +75,7 @@ void NORETURN Sys_Error(const char *error, ...)
|
|||||||
UTIL_Printf("FATAL ERROR (shutting down): %s\n", text);
|
UTIL_Printf("FATAL ERROR (shutting down): %s\n", text);
|
||||||
|
|
||||||
//TerminateProcess(GetCurrentProcess(), 1);
|
//TerminateProcess(GetCurrentProcess(), 1);
|
||||||
*((int*)NULL) = 0;
|
int *null = 0;
|
||||||
while (true);
|
*null = 0;
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
75
src/task.cpp
75
src/task.cpp
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
39
src/task.h
39
src/task.h
@ -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();
|
|
Loading…
x
Reference in New Issue
Block a user