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 "maintypes.h"
|
||||
#include "regamedll_common.h"
|
||||
#include "strtools.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
template<typename t_ret, typename ...t_args>
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <functional>
|
||||
|
||||
#ifdef _WIN32 // WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#include <wsipx.h> // for support IPX
|
||||
@ -102,12 +103,15 @@
|
||||
#ifndef CDECL
|
||||
#define CDECL __cdecl
|
||||
#endif
|
||||
#define FASTCALL __fastcall
|
||||
#define STDCALL __stdcall
|
||||
#define HIDDEN
|
||||
#define FORCEINLINE __forceinline
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#define ALIGN16 __declspec(align(16))
|
||||
#define NORETURN __declspec(noreturn)
|
||||
#define FORCE_STACK_ALIGN
|
||||
#define FUNC_TARGET(x)
|
||||
|
||||
#define __builtin_bswap16 _byteswap_ushort
|
||||
#define __builtin_bswap32 _byteswap_ulong
|
||||
@ -146,18 +150,24 @@
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned int UNINT32;
|
||||
|
||||
#define FASTCALL
|
||||
#define CDECL __attribute__ ((cdecl))
|
||||
#define STDCALL __attribute__ ((stdcall))
|
||||
#define HIDDEN __attribute__((visibility("hidden")))
|
||||
#define FORCEINLINE inline
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#define ALIGN16 __attribute__((aligned(16)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
|
||||
|
||||
#if defined __INTEL_COMPILER
|
||||
#define FUNC_TARGET(x)
|
||||
|
||||
#define __builtin_bswap16 _bswap16
|
||||
#define __builtin_bswap32 _bswap
|
||||
#define __builtin_bswap64 _bswap64
|
||||
#else
|
||||
#define FUNC_TARGET(x) __attribute__((target(x)))
|
||||
#endif // __INTEL_COMPILER
|
||||
|
||||
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
|
||||
|
@ -166,6 +166,7 @@
|
||||
<ClInclude Include="..\public\rechecker_interfaces.h" />
|
||||
<ClInclude Include="..\src\cmdexec.h" />
|
||||
<ClInclude Include="..\src\hookchains_impl.h" />
|
||||
<ClInclude Include="..\src\rechecker_api.h" />
|
||||
<ClInclude Include="..\src\rechecker_api_impl.h" />
|
||||
<ClInclude Include="..\src\resource.h" />
|
||||
<ClInclude Include="..\src\engine_rehlds.h" />
|
||||
|
@ -467,6 +467,7 @@
|
||||
<ClInclude Include="..\public\rechecker_interfaces.h">
|
||||
<Filter>public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\rechecker_api.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\parsemsg.cpp">
|
||||
|
@ -145,9 +145,12 @@ inline char *_strlwr(char *start)
|
||||
#endif // #if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS)
|
||||
|
||||
// a safe variant of strcpy that truncates the result to fit in the destination buffer
|
||||
template <size_t size>
|
||||
char *Q_strlcpy(char (&dest)[size], const char *src) {
|
||||
Q_strncpy(dest, src, size - 1);
|
||||
template <typename T, size_t size>
|
||||
T *Q_strlcpy(T (&dest)[size], const char *src)
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(char), "invalid size of type != sizeof(char)");
|
||||
|
||||
Q_strncpy((char *)dest, src, size - 1);
|
||||
dest[size - 1] = '\0';
|
||||
return dest;
|
||||
}
|
||||
@ -160,9 +163,11 @@ inline char *Q_strnlcpy(char *dest, const char *src, size_t n) {
|
||||
|
||||
// safely concatenate two strings.
|
||||
// a variant of strcat that truncates the result to fit in the destination buffer
|
||||
template <size_t size>
|
||||
size_t Q_strlcat(char (&dest)[size], const char *src)
|
||||
template <typename T, size_t size>
|
||||
size_t Q_strlcat(T (&dest)[size], const char *src)
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(char), "invalid size of type != sizeof(char)");
|
||||
|
||||
size_t srclen; // Length of source string
|
||||
size_t dstlen; // Length of destination string
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
CExecMngr Exec;
|
||||
@ -26,14 +44,15 @@ void StringReplace(char *src, const char *strold, const char *strnew)
|
||||
return;
|
||||
|
||||
char *p = src;
|
||||
int oldLen = strlen(strold), newLen = strlen(strnew);
|
||||
int oldLen = Q_strlen(strold), newLen = Q_strlen(strnew);
|
||||
|
||||
while ((p = strstr(p, strold)) != nullptr)
|
||||
while ((p = Q_strstr(p, strold)))
|
||||
{
|
||||
if (oldLen != newLen)
|
||||
memmove(p + newLen, p + oldLen, strlen(p) - oldLen + 1);
|
||||
if (oldLen != newLen) {
|
||||
Q_memmove(p + newLen, p + oldLen, Q_strlen(p) - oldLen + 1);
|
||||
}
|
||||
|
||||
memcpy(p, strnew, newLen);
|
||||
Q_memcpy(p, strnew, newLen);
|
||||
p += newLen;
|
||||
}
|
||||
}
|
||||
@ -45,22 +64,21 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
|
||||
const netadr_t *net;
|
||||
static char string[256];
|
||||
|
||||
// check cmdexec is empty
|
||||
// Check cmdexec is empty
|
||||
if (!pResource->GetCmdExec())
|
||||
return nullptr;
|
||||
|
||||
strncpy(string, pResource->GetCmdExec(), sizeof(string) - 1);
|
||||
string[sizeof(string) - 1] = '\0';
|
||||
Q_strlcpy(string, pResource->GetCmdExec());
|
||||
|
||||
net = pClient->GetNetChan()->GetRemoteAdr();
|
||||
nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
||||
|
||||
// replace key values
|
||||
// Replace key values
|
||||
StringReplace(string, "[file_name]", pResource->GetFileName());
|
||||
StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", responseHash));
|
||||
StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", _byteswap_ulong(responseHash)));
|
||||
|
||||
// replace of templates for identification
|
||||
// Replace of templates for identification
|
||||
StringReplace(string, "[userid]", UTIL_VarArgs("#%u", nUserID));
|
||||
StringReplace(string, "[steamid]", UTIL_VarArgs("%s", g_engfuncs.pfnGetPlayerAuthId(pClient->GetEdict())));
|
||||
StringReplace(string, "[ip]", UTIL_VarArgs("%i.%i.%i.%i", net->ip[0], net->ip[1], net->ip[2], net->ip[3]));
|
||||
@ -70,7 +88,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
|
||||
{
|
||||
g_pResource->Log(LOG_NORMAL, " -> ExecuteCMD: (%s), for (#%u)(%s)", string, nUserID, pClient->GetName());
|
||||
|
||||
len = strlen(string);
|
||||
len = Q_strlen(string);
|
||||
|
||||
if (len < sizeof(string) - 2)
|
||||
strcat(string, "\n");
|
||||
@ -83,7 +101,7 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32
|
||||
|
||||
bool haveAtLeastOneExecuted = false;
|
||||
void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cmdExec, uint32 responseHash) {
|
||||
// execute cmdexec
|
||||
// Execute cmdexec
|
||||
SERVER_COMMAND(cmdExec);
|
||||
haveAtLeastOneExecuted = true;
|
||||
}
|
||||
@ -96,8 +114,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
||||
|
||||
while (iter != m_execList.end())
|
||||
{
|
||||
CBufExec *pExec = (*iter);
|
||||
|
||||
auto pExec = (*iter);
|
||||
if (pExec->GetUserID() != nUserID)
|
||||
{
|
||||
iter++;
|
||||
@ -106,14 +123,13 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
||||
|
||||
CResourceBuffer *pRes = pExec->GetResource();
|
||||
|
||||
// exit the loop if the client is out of the game
|
||||
// TODO: Check me!
|
||||
// Exit the loop if the client is out of the game
|
||||
if (!pClient->IsConnected())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// erase all cmdexec because have flag is break
|
||||
// Erase all cmdexec because have flag is break
|
||||
if (!bBreak)
|
||||
{
|
||||
char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash());
|
||||
@ -125,7 +141,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient)
|
||||
bBreak = pRes->IsBreak();
|
||||
}
|
||||
|
||||
// erase cmdexec
|
||||
// Erase cmdexec
|
||||
delete pExec;
|
||||
iter = m_execList.erase(iter);
|
||||
}
|
||||
@ -152,9 +168,9 @@ void CExecMngr::Clear(IGameClient *pClient)
|
||||
auto iter = m_execList.begin();
|
||||
while (iter != m_execList.end())
|
||||
{
|
||||
CBufExec *pExec = (*iter);
|
||||
auto pExec = (*iter);
|
||||
|
||||
// erase cmdexec
|
||||
// Erase cmdexec
|
||||
if (pExec->GetUserID() != nUserID)
|
||||
{
|
||||
iter++;
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CExecMngr
|
||||
|
@ -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"
|
||||
|
||||
DLL_FUNCTIONS *g_pFunctionTable;
|
||||
|
||||
extern void ServerDeactivate_Post();
|
||||
|
||||
static DLL_FUNCTIONS gFunctionTable =
|
||||
{
|
||||
NULL, // pfnGameInit
|
||||
@ -148,7 +164,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
|
||||
Q_memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
|
||||
g_pFunctionTable = pFunctionTable;
|
||||
|
||||
return TRUE;
|
||||
@ -170,7 +186,7 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
|
||||
Q_memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
|
||||
g_pFunctionTable = pFunctionTable;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
enginefuncs_t meta_engfuncs_post =
|
||||
@ -227,6 +245,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
|
||||
Q_memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
IRehldsApi *g_RehldsApi;
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum rehlds_ret
|
||||
|
@ -1,32 +1,24 @@
|
||||
// From SDK dlls/h_export.cpp:
|
||||
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
/*
|
||||
|
||||
===== h_export.cpp ========================================================
|
||||
|
||||
Entity classes exported by Halflife.
|
||||
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
// From SDK dlls/h_export.cpp:
|
||||
|
||||
//! Holds engine functionality callbacks
|
||||
// Holds engine functionality callbacks
|
||||
enginefuncs_t g_engfuncs;
|
||||
globalvars_t *gpGlobals;
|
||||
|
||||
@ -35,6 +27,6 @@ globalvars_t *gpGlobals;
|
||||
// do some setup operations here.
|
||||
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
|
||||
{
|
||||
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
|
||||
Q_memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
|
||||
gpGlobals = pGlobals;
|
||||
}
|
||||
|
@ -76,15 +76,17 @@ void AbstractHookChainRegistry::removeHook(void *hookFunc) {
|
||||
{
|
||||
if (hookFunc == m_Hooks[i])
|
||||
{
|
||||
--m_NumHooks;
|
||||
m_NumHooks--;
|
||||
if (m_NumHooks != i)
|
||||
{
|
||||
Q_memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
|
||||
Q_memmove(&m_Priorities[i], &m_Priorities[i + 1], (m_NumHooks - i) * sizeof(m_Priorities[0]));
|
||||
m_Hooks[m_NumHooks] = NULL;
|
||||
m_Hooks[m_NumHooks] = nullptr;
|
||||
}
|
||||
else
|
||||
m_Hooks[i] = NULL;
|
||||
{
|
||||
m_Hooks[i] = nullptr;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -14,22 +14,26 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hookchains.h"
|
||||
|
||||
const int MAX_HOOKS_IN_CHAIN = 19;
|
||||
|
||||
template <typename t_ret, typename t_class, typename ...t_args>
|
||||
bool is_void(t_ret (t_class::*)(t_args...)) { return false; }
|
||||
|
||||
template <typename t_ret, typename ...t_args>
|
||||
bool is_void(t_ret (*)(t_args...)) { return false; }
|
||||
|
||||
template <typename t_class, typename ...t_args>
|
||||
bool is_void(void (t_class::*)(t_args...)) { return true; }
|
||||
|
||||
template <typename ...t_args>
|
||||
bool is_void(void (*)(t_args...)) { return true; }
|
||||
|
||||
// Implementation for chains in modules
|
||||
template<typename t_ret, typename ...t_args>
|
||||
class IHookChainImpl: public IHookChain<t_ret, t_args...> {
|
||||
@ -39,7 +43,7 @@ public:
|
||||
|
||||
IHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig)
|
||||
{
|
||||
if (orig == NULL)
|
||||
if (!orig && !is_void(orig))
|
||||
Sys_Error("%s: Non-void HookChain without original function.", __func__);
|
||||
}
|
||||
|
||||
@ -54,46 +58,11 @@ public:
|
||||
return nexthook(&nextChain, args...);
|
||||
}
|
||||
|
||||
return m_OriginalFunc(args...);
|
||||
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
|
||||
}
|
||||
|
||||
virtual t_ret callOriginal(t_args... args) {
|
||||
return m_OriginalFunc(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
void **m_Hooks;
|
||||
origfunc_t m_OriginalFunc;
|
||||
};
|
||||
|
||||
// Implementation for void chains in modules
|
||||
template<typename ...t_args>
|
||||
class IVoidHookChainImpl: public IVoidHookChain<t_args...> {
|
||||
public:
|
||||
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
|
||||
typedef void (*origfunc_t)(t_args...);
|
||||
|
||||
IVoidHookChainImpl(void **hooks, origfunc_t orig) : m_Hooks(hooks), m_OriginalFunc(orig) {}
|
||||
virtual ~IVoidHookChainImpl() {}
|
||||
|
||||
virtual void callNext(t_args... args) {
|
||||
hookfunc_t nexthook = (hookfunc_t)m_Hooks[0];
|
||||
|
||||
if (nexthook)
|
||||
{
|
||||
IVoidHookChainImpl nextChain(m_Hooks + 1, m_OriginalFunc);
|
||||
nexthook(&nextChain, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_OriginalFunc)
|
||||
m_OriginalFunc(args...);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void callOriginal(t_args... args) {
|
||||
if (m_OriginalFunc)
|
||||
m_OriginalFunc(args...);
|
||||
return m_OriginalFunc ? m_OriginalFunc(args...) : t_ret();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -116,10 +85,10 @@ public:
|
||||
AbstractHookChainRegistry();
|
||||
};
|
||||
|
||||
template<typename t_ret, typename ...t_args>
|
||||
class IHookChainRegistryImpl : public IHookChainRegistry < t_ret, t_args...>, public AbstractHookChainRegistry {
|
||||
template <typename t_ret, typename ...t_args>
|
||||
class IHookChainRegistryImpl: public IHookChainRegistry<t_ret, t_args...>, public AbstractHookChainRegistry {
|
||||
public:
|
||||
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...> *, t_args...);
|
||||
typedef t_ret (*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
|
||||
typedef t_ret (*origfunc_t)(t_args...);
|
||||
|
||||
virtual ~IHookChainRegistryImpl() { }
|
||||
@ -136,25 +105,3 @@ public:
|
||||
removeHook((void *)hook);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ...t_args>
|
||||
class IVoidHookChainRegistryImpl: public IVoidHookChainRegistry <t_args...>, public AbstractHookChainRegistry {
|
||||
public:
|
||||
typedef void (*hookfunc_t)(IVoidHookChain<t_args...> *, t_args...);
|
||||
typedef void (*origfunc_t)(t_args...);
|
||||
|
||||
virtual ~IVoidHookChainRegistryImpl() { }
|
||||
|
||||
void callChain(origfunc_t origFunc, t_args... args) {
|
||||
IVoidHookChainImpl<t_args...> chain(m_Hooks, origFunc);
|
||||
chain.callNext(args...);
|
||||
}
|
||||
|
||||
virtual void registerHook(hookfunc_t hook, int priority) {
|
||||
addHook((void *)hook, priority);
|
||||
}
|
||||
|
||||
virtual void unregisterHook(hookfunc_t hook) {
|
||||
removeHook((void *)hook);
|
||||
}
|
||||
};
|
||||
|
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"
|
||||
|
||||
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, NULL };
|
||||
cvar_t *pcv_consistency_old = NULL;
|
||||
cvar_t cv_mp_consistency = { "mp_consistency", "0", 0, 0.0f, nullptr };
|
||||
cvar_t *pcv_consistency_old = nullptr;
|
||||
|
||||
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
|
||||
qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);
|
||||
@ -13,14 +31,14 @@ bool OnMetaAttach()
|
||||
|
||||
g_pResource = new CResourceFile();
|
||||
|
||||
// initialize resource config
|
||||
// Initialize resource environment
|
||||
g_pResource->Init();
|
||||
Rechecker_Api_Init();
|
||||
|
||||
// if have already registered take it
|
||||
// If have already registered take it
|
||||
cvar_t *pcv_consistency_prev = g_engfuncs.pfnCVarGetPointer("mp_consistency_");
|
||||
|
||||
if (pcv_consistency_prev != NULL)
|
||||
if (pcv_consistency_prev)
|
||||
{
|
||||
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
||||
|
||||
@ -34,7 +52,7 @@ bool OnMetaAttach()
|
||||
}
|
||||
else
|
||||
{
|
||||
// set force cvar on own value and replacement of original
|
||||
// Set force cvar on own value and replacement of original
|
||||
// NOTE: in gamedll used this cvar not through a pointer thus we create own cvar for gamedll with default values
|
||||
// so for engine set it the cvar values is 1.
|
||||
pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
||||
@ -50,13 +68,13 @@ bool OnMetaAttach()
|
||||
|
||||
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, "1");
|
||||
|
||||
// to remove the old cvar of cvars list
|
||||
// To remove the old cvar of cvars list
|
||||
cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars();
|
||||
for (cvar_t *var = cvar_vars, *prev = NULL; var != NULL; prev = var, var = var->next)
|
||||
for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next)
|
||||
{
|
||||
if (var == pcv_consistency_old)
|
||||
{
|
||||
if (prev != NULL)
|
||||
if (prev)
|
||||
prev->next = var->next;
|
||||
else
|
||||
cvar_vars = cvar_vars->next;
|
||||
@ -64,7 +82,7 @@ bool OnMetaAttach()
|
||||
}
|
||||
}
|
||||
|
||||
// register function from ReHLDS API
|
||||
// Register function from ReHLDS API
|
||||
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient);
|
||||
g_RehldsHookchains->SV_CheckConsistencyResponse()->registerHook(&SV_CheckConsistencyResponse);
|
||||
g_RehldsHookchains->SV_TransferConsistencyInfo()->registerHook(&SV_TransferConsistencyInfo);
|
||||
@ -74,7 +92,7 @@ bool OnMetaAttach()
|
||||
SV_AddResource = g_RehldsFuncs->SV_AddResource;
|
||||
SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList;
|
||||
|
||||
// go to attach
|
||||
// Go to attach
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -82,19 +100,19 @@ void OnMetaDetach()
|
||||
{
|
||||
cvar_t *pcv_mp_consistency = g_engfuncs.pfnCVarGetPointer("mp_consistency");
|
||||
|
||||
// to restore the pointer address of a string
|
||||
// To restore the pointer address of a string
|
||||
const char *tempName = pcv_consistency_old->name;
|
||||
pcv_consistency_old->name = cv_mp_consistency.name;
|
||||
g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, pcv_mp_consistency->string);
|
||||
pcv_mp_consistency->name = tempName;
|
||||
|
||||
// restore old cvar mp_consistency
|
||||
// Restore old cvar mp_consistency
|
||||
cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars();
|
||||
for (cvar_t *var = cvar_vars, *prev = NULL; var != NULL; prev = var, var = var->next)
|
||||
for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next)
|
||||
{
|
||||
if (var == pcv_mp_consistency)
|
||||
{
|
||||
if (prev != NULL)
|
||||
if (prev)
|
||||
prev->next = pcv_consistency_old;
|
||||
else
|
||||
cvar_vars = pcv_consistency_old;
|
||||
@ -102,7 +120,7 @@ void OnMetaDetach()
|
||||
}
|
||||
}
|
||||
|
||||
// clear
|
||||
// Clear
|
||||
Exec.Clear();
|
||||
delete g_pResource;
|
||||
|
||||
@ -117,7 +135,7 @@ void OnMetaDetach()
|
||||
|
||||
void ServerDeactivate_Post()
|
||||
{
|
||||
// clear
|
||||
// Clear
|
||||
Exec.Clear();
|
||||
g_pResource->Clear();
|
||||
|
||||
@ -126,13 +144,13 @@ void ServerDeactivate_Post()
|
||||
|
||||
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string)
|
||||
{
|
||||
// clear buffer cmdexec the client when was disconnected up to perform cmdexec
|
||||
// Clear buffer cmdexec the client when was disconnected up to perform cmdexec
|
||||
Exec.Clear(pClient);
|
||||
|
||||
// clear temporary files of response
|
||||
// Clear temporary files of response
|
||||
g_pResource->Clear(pClient);
|
||||
|
||||
// call next hook
|
||||
// Call next hook
|
||||
chain->callNext(pClient, crash, string);
|
||||
}
|
||||
|
||||
@ -140,10 +158,10 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain)
|
||||
{
|
||||
g_pResource->LoadResources();
|
||||
|
||||
// add to the resource
|
||||
// Add to the resource
|
||||
int nConsistency = g_pResource->CreateResourceList();
|
||||
|
||||
// returns the total number of consistency files
|
||||
// Returns the total number of consistency files
|
||||
return chain->callNext() + nConsistency;
|
||||
}
|
||||
|
||||
@ -152,7 +170,7 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
|
||||
if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash))
|
||||
return false;
|
||||
|
||||
// call next hook and take return of values from original func
|
||||
// Call next hook and take return of values from original func
|
||||
return chain->callNext(pSenderClient, resource, hash);
|
||||
}
|
||||
|
||||
@ -171,7 +189,7 @@ void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain)
|
||||
g_RecheckerHookchains.m_FileConsistencyFinal.callChain(nullptr, pClient);
|
||||
}
|
||||
|
||||
// client is connected to putinserver, go execute cmd out buffer
|
||||
// Client is connected to putinserver, go execute cmd out buffer
|
||||
Exec.ExecuteCommand(pClient);
|
||||
}
|
||||
|
||||
@ -179,7 +197,7 @@ const int clc_fileconsistency = 7;
|
||||
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode)
|
||||
{
|
||||
if (opcode == clc_fileconsistency) {
|
||||
// clear temporary files of response
|
||||
// Clear temporary files of response
|
||||
g_pResource->Clear(cl);
|
||||
}
|
||||
|
||||
|
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
|
||||
|
||||
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string);
|
||||
@ -5,6 +23,7 @@ bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain,
|
||||
int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain);
|
||||
void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain);
|
||||
void HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *cl, int8 opcode);
|
||||
void ServerDeactivate_Post();
|
||||
|
||||
extern void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
|
||||
extern qboolean (*SV_FileInConsistencyList)(const char *filename, consistency_t **ppconsist);
|
||||
|
@ -1,10 +1,28 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
plugin_info_t Plugin_info =
|
||||
{
|
||||
META_INTERFACE_VERSION,
|
||||
"Rechecker",
|
||||
"2.4",
|
||||
"2.5",
|
||||
__DATE__,
|
||||
"s1lent",
|
||||
"http://www.dedicated-server.ru/",
|
||||
@ -41,12 +59,11 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
|
||||
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
|
||||
|
||||
GET_HOOK_TABLES(PLID, NULL, &gMetaEntityInterface, NULL);
|
||||
GET_HOOK_TABLES(PLID, nullptr, &gMetaEntityInterface, nullptr);
|
||||
|
||||
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
|
||||
Q_memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "basetypes.h"
|
||||
@ -24,7 +42,6 @@
|
||||
#include "rechecker_api_impl.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "task.h"
|
||||
#include "resource.h"
|
||||
#include "cmdexec.h"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -14,17 +14,8 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hookchains.h"
|
||||
@ -45,16 +36,16 @@ enum ResourceType_e
|
||||
class IResourceBuffer;
|
||||
|
||||
// FileConsistencyProcess hook
|
||||
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
|
||||
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
|
||||
typedef IHookChain<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
|
||||
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHookRegistry_FileConsistencyProcess;
|
||||
|
||||
// CmdExec hook
|
||||
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
|
||||
typedef IVoidHookChainRegistry<IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
|
||||
typedef IHookChain<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHook_CmdExec;
|
||||
typedef IHookChainRegistry<void, IGameClient *, IResourceBuffer *, char *, uint32> IRecheckerHookRegistry_CmdExec;
|
||||
|
||||
// FileConsistencyFinal hook
|
||||
typedef IVoidHookChain<IGameClient *> IRecheckerHook_FileConsistencyFinal;
|
||||
typedef IVoidHookChainRegistry<IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
|
||||
typedef IHookChain<void, IGameClient *> IRecheckerHook_FileConsistencyFinal;
|
||||
typedef IHookChainRegistry<void, IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
|
||||
|
||||
class IRecheckerHookchains {
|
||||
protected:
|
||||
|
@ -14,17 +14,8 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
CRecheckerApi g_RecheckerApi;
|
||||
|
@ -14,30 +14,21 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// FileConsistencyProcess hook
|
||||
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
|
||||
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
|
||||
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHook_FileConsistencyProcess;
|
||||
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, ResourceType_e, uint32> CRecheckerHookRegistry_FileConsistencyProcess;
|
||||
|
||||
// CmdExec hook
|
||||
typedef IVoidHookChainImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
|
||||
typedef IVoidHookChainRegistryImpl<IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
|
||||
typedef IHookChainImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHook_CmdExec;
|
||||
typedef IHookChainRegistryImpl<void, IGameClient *, IResourceBuffer *, char *, uint32> CRecheckerHookRegistry_CmdExec;
|
||||
|
||||
// FileConsistencyFinal hook
|
||||
typedef IVoidHookChainImpl<IGameClient *> CRecheckerHook_FileConsistencyFinal;
|
||||
typedef IVoidHookChainRegistryImpl<IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
|
||||
typedef IHookChainImpl<void, IGameClient *> CRecheckerHook_FileConsistencyFinal;
|
||||
typedef IHookChainRegistryImpl<void, IGameClient *> CRecheckerHookRegistry_FileConsistencyFinal;
|
||||
|
||||
class CRecheckerHookchains: public IRecheckerHookchains {
|
||||
public:
|
||||
@ -91,8 +82,8 @@ struct query_file_t
|
||||
|
||||
inline query_file_t::query_file_t(const char *filename, const ResourceType_e flag, uint32 hash, query_func_t func, int uniqueId)
|
||||
{
|
||||
this->filename = new char [strlen(filename) + 1];
|
||||
strcpy(this->filename, filename);
|
||||
this->filename = new char [Q_strlen(filename) + 1];
|
||||
Q_strcpy(this->filename, filename);
|
||||
|
||||
this->flag = flag;
|
||||
this->hash = hash;
|
||||
|
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"
|
||||
|
||||
CResourceFile *g_pResource = nullptr;
|
||||
@ -6,8 +24,6 @@ CResourceFile::StringList CResourceFile::m_StringsCache;
|
||||
cvar_t cv_rch_log = { "rch_log", "0", 0, 0.0f, nullptr };
|
||||
cvar_t *pcv_rch_log = nullptr;
|
||||
|
||||
const char *szTypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" };
|
||||
|
||||
CResourceFile::CResourceFile() :
|
||||
m_resourceList(),
|
||||
m_responseList(),
|
||||
@ -16,6 +32,8 @@ CResourceFile::CResourceFile() :
|
||||
{
|
||||
m_PathDir[0] = '\0';
|
||||
m_LogFilePath[0] = '\0';
|
||||
|
||||
Q_memset(&m_HeadResource, 0, sizeof(m_HeadResource));
|
||||
}
|
||||
|
||||
CResourceFile::~CResourceFile()
|
||||
@ -25,20 +43,22 @@ CResourceFile::~CResourceFile()
|
||||
|
||||
int CResourceFile::CreateResourceList()
|
||||
{
|
||||
// max value of 12 bits
|
||||
// we need to go over the threshold
|
||||
int startIndex = (1 << RESOURCE_INDEX_BITS) - 1;
|
||||
int nCustomConsistency = 0;
|
||||
|
||||
ComputeConsistencyFiles();
|
||||
AddHeadResource();
|
||||
|
||||
// Max value of 12 bits,
|
||||
// we need to hit over the threshold
|
||||
int nIndex = m_HeadResource.nIndex + 1;
|
||||
int nCustomConsistency = 1;
|
||||
|
||||
std::vector<resource_t> sortList;
|
||||
for (auto res : m_resourceList)
|
||||
{
|
||||
// prevent duplicate of filenames
|
||||
// check if filename is been marked so do not add the resource again
|
||||
// Prevent duplicate of filenames
|
||||
// Check if filename is been marked so do not add the resource again
|
||||
if (!res->IsDuplicate())
|
||||
{
|
||||
// check limit resource
|
||||
// Check limit resource
|
||||
if (g_RehldsServerData->GetResourcesNum() >= RESOURCE_MAX_COUNT)
|
||||
{
|
||||
if (res->IsAddEx()) {
|
||||
@ -50,7 +70,7 @@ int CResourceFile::CreateResourceList()
|
||||
break;
|
||||
}
|
||||
|
||||
// not allow to add a resource if the index is larger than 1024 or we will get Bad file data.
|
||||
// Not allow to add a resource if the index is larger than 1024 or we will get Bad file data.
|
||||
// https://github.com/dreamstalker/rehlds/blob/beaeb65/rehlds/engine/sv_user.cpp#L374
|
||||
if (nCustomConsistency + m_ConsistencyNum >= MAX_RANGE_CONSISTENCY)
|
||||
{
|
||||
@ -63,13 +83,21 @@ int CResourceFile::CreateResourceList()
|
||||
break;
|
||||
}
|
||||
|
||||
Log(LOG_DETAILED, "%s -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), res->GetCmdExec(), res->GetFileHash(), szTypeNames[ res->GetFileFlag() ], res->IsAddEx());
|
||||
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, startIndex++);
|
||||
SV_AddResource(t_decal, res->GetFileName(), 0, RES_CHECKFILE, nIndex++);
|
||||
nCustomConsistency++;
|
||||
}
|
||||
|
||||
auto pszCmdExec = res->GetCmdExec();
|
||||
if (pszCmdExec[0] != '\0')
|
||||
{
|
||||
Log(LOG_DETAILED, "%s -> file: (%s), cmdexec: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), pszCmdExec, res->GetFileHash(), m_TypeNames[res->GetFileFlag()], res->IsAddEx());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(LOG_DETAILED, "%s -> file: (%s), hash: (%x), typeFind: (%s), ex: (%d)", __func__, res->GetFileName(), res->GetFileHash(), m_TypeNames[res->GetFileFlag()], res->IsAddEx());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<resource_t> sortList;
|
||||
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
|
||||
{
|
||||
sortList.push_back(*g_RehldsServerData->GetResource(i));
|
||||
@ -78,7 +106,7 @@ int CResourceFile::CreateResourceList()
|
||||
// Start a first resource list
|
||||
g_RehldsServerData->SetResourcesNum(0);
|
||||
|
||||
// sort
|
||||
// Sorting
|
||||
std::sort(sortList.begin(), sortList.end(), [](const resource_t &a, const resource_t &b)
|
||||
{
|
||||
bool a_cons = (a.ucFlags & RES_CHECKFILE) || SV_FileInConsistencyList(a.szFileName, nullptr);
|
||||
@ -93,6 +121,9 @@ int CResourceFile::CreateResourceList()
|
||||
return a.nIndex < b.nIndex;
|
||||
});
|
||||
|
||||
// Insert to front head resource
|
||||
sortList.insert(sortList.begin(), m_HeadResource);
|
||||
|
||||
for (auto& res : sortList)
|
||||
{
|
||||
// Add new resource in the own order
|
||||
@ -107,47 +138,60 @@ void CResourceFile::ComputeConsistencyFiles()
|
||||
{
|
||||
m_ConsistencyNum = 0;
|
||||
|
||||
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); ++i)
|
||||
for (int i = 0; i < g_RehldsServerData->GetResourcesNum(); i++)
|
||||
{
|
||||
auto res = g_RehldsServerData->GetResource(i);
|
||||
if (res->ucFlags == (RES_CUSTOM | RES_REQUESTED | RES_UNK_6) || (res->ucFlags & RES_CHECKFILE))
|
||||
continue;
|
||||
|
||||
if (SV_FileInConsistencyList(res->szFileName, nullptr))
|
||||
++m_ConsistencyNum;
|
||||
if (!SV_FileInConsistencyList(res->szFileName, nullptr))
|
||||
continue;
|
||||
|
||||
m_ConsistencyNum++;
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceFile::AddHeadResource()
|
||||
{
|
||||
Q_strlcpy(m_HeadResource.szFileName, m_HeadFileName);
|
||||
|
||||
m_HeadResource.type = t_decal;
|
||||
m_HeadResource.ucFlags = RES_CHECKFILE;
|
||||
m_HeadResource.nDownloadSize = 0;
|
||||
m_HeadResource.nIndex = RESOURCE_MAX_COUNT - 1;
|
||||
}
|
||||
|
||||
void CResourceFile::Clear(IGameClient *pClient)
|
||||
{
|
||||
if (pClient)
|
||||
{
|
||||
// remove each entries by pClient
|
||||
// Remove each entries by pClient
|
||||
auto nUserID = g_engfuncs.pfnGetPlayerUserId(pClient->GetEdict());
|
||||
auto iter = m_responseList.begin();
|
||||
while (iter != m_responseList.end())
|
||||
{
|
||||
CResponseBuffer *pFiles = (*iter);
|
||||
auto pFiles = (*iter);
|
||||
|
||||
// erase cmdexec
|
||||
if (pFiles->GetUserID() == nUserID)
|
||||
// Erase cmdexec
|
||||
if (pFiles->GetUserID() != nUserID)
|
||||
{
|
||||
delete pFiles;
|
||||
iter = m_responseList.erase(iter);
|
||||
}
|
||||
else
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
|
||||
delete pFiles;
|
||||
iter = m_responseList.erase(iter);
|
||||
}
|
||||
|
||||
m_PrevHash = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// remove all
|
||||
// Remove all
|
||||
m_PrevHash = 0;
|
||||
m_ConsistencyNum = 0;
|
||||
|
||||
// clear resources
|
||||
// Clear resources
|
||||
for (auto it : m_resourceList)
|
||||
delete it;
|
||||
|
||||
@ -190,10 +234,10 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
strcat(string, "\n");
|
||||
Q_strlcat(string, "\n");
|
||||
|
||||
td = time(nullptr);
|
||||
lt = localtime(&td);
|
||||
@ -202,7 +246,7 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...)
|
||||
|
||||
if (!bFirst)
|
||||
{
|
||||
file = strrchr(m_LogFilePath, '/');
|
||||
file = Q_strrchr(m_LogFilePath, '/');
|
||||
if (file == nullptr)
|
||||
file = "<null>";
|
||||
|
||||
@ -239,23 +283,20 @@ void CResourceFile::Init()
|
||||
char *pos;
|
||||
char path[MAX_PATH];
|
||||
|
||||
strncpy(path, GET_PLUGIN_PATH(PLID), sizeof(path) - 1);
|
||||
path[sizeof(path) - 1] = '\0';
|
||||
|
||||
pos = strrchr(path, '/');
|
||||
Q_strlcpy(path, GET_PLUGIN_PATH(PLID));
|
||||
pos = Q_strrchr(path, '/');
|
||||
|
||||
if (*pos == '\0')
|
||||
return;
|
||||
|
||||
*(pos + 1) = '\0';
|
||||
|
||||
strncpy(m_LogFilePath, path, sizeof(m_LogFilePath) - 1);
|
||||
m_LogFilePath[sizeof(m_LogFilePath) - 1] = '\0';
|
||||
strcat(m_LogFilePath, "logs/");
|
||||
Q_strlcpy(m_LogFilePath, path);
|
||||
Q_strlcat(m_LogFilePath, "logs/");
|
||||
CreateDirectory(m_LogFilePath);
|
||||
|
||||
// resources.ini
|
||||
snprintf(m_PathDir, sizeof(m_PathDir), "%s" FILE_INI_RESOURCES, path);
|
||||
Q_snprintf(m_PathDir, sizeof(m_PathDir), "%s%s", path, FILE_INI_RESOURCES);
|
||||
|
||||
g_engfuncs.pfnCvar_RegisterVariable(&cv_rch_log);
|
||||
pcv_rch_log = g_engfuncs.pfnCVarGetPointer(cv_rch_log.name);
|
||||
@ -269,7 +310,7 @@ inline uint8 hexbyte(uint8 *hex)
|
||||
|
||||
inline bool invalidchar(const char c)
|
||||
{
|
||||
// to check for invalid characters
|
||||
// To check for invalid characters
|
||||
return (c == '\\' || c == '/' || c == ':'
|
||||
|| c == '*' || c == '?'
|
||||
|| c == '"' || c == '<'
|
||||
@ -278,7 +319,7 @@ inline bool invalidchar(const char c)
|
||||
|
||||
bool IsValidFilename(char *psrc, char &pchar)
|
||||
{
|
||||
char *pch = strrchr(psrc, '/');
|
||||
char *pch = Q_strrchr(psrc, '/');
|
||||
if (!pch)
|
||||
pch = psrc;
|
||||
|
||||
@ -296,16 +337,16 @@ bool IsValidFilename(char *psrc, char &pchar)
|
||||
|
||||
bool IsFileHasExtension(char *psrc)
|
||||
{
|
||||
// find the extension filename
|
||||
char *pch = strrchr(psrc, '.');
|
||||
// Find the extension filename
|
||||
char *pch = Q_strrchr(psrc, '.');
|
||||
if (!pch)
|
||||
return false;
|
||||
|
||||
// the size extension
|
||||
if (strlen(&pch[1]) <= 0)
|
||||
// The size extension
|
||||
if (Q_strlen(&pch[1]) <= 0)
|
||||
return false;
|
||||
|
||||
return strchr(pch, '/') == nullptr;
|
||||
return Q_strchr(pch, '/') == nullptr;
|
||||
}
|
||||
|
||||
void CResourceFile::LogPrepare()
|
||||
@ -318,14 +359,14 @@ void CResourceFile::LogPrepare()
|
||||
td = time(nullptr);
|
||||
lt = localtime(&td);
|
||||
|
||||
// remove path to log file
|
||||
if ((pos = strrchr(m_LogFilePath, '/')) != nullptr)
|
||||
// Remove path to log file
|
||||
if ((pos = Q_strrchr(m_LogFilePath, '/')))
|
||||
{
|
||||
*(pos + 1) = '\0';
|
||||
}
|
||||
|
||||
strftime(dateFile, sizeof(dateFile), "L_%d_%m_%Y.log", lt);
|
||||
strcat(m_LogFilePath, dateFile);
|
||||
Q_strlcat(m_LogFilePath, dateFile);
|
||||
}
|
||||
|
||||
void CResourceFile::LoadResources()
|
||||
@ -335,7 +376,6 @@ void CResourceFile::LoadResources()
|
||||
uint8 hash[16];
|
||||
FILE *fp;
|
||||
int argc;
|
||||
int len;
|
||||
ResourceType_e flag;
|
||||
char filename[MAX_PATH];
|
||||
char cmdBufExec[MAX_PATH];
|
||||
@ -352,7 +392,7 @@ void CResourceFile::LoadResources()
|
||||
|
||||
while (!feof(fp) && fgets(line, sizeof(line), fp))
|
||||
{
|
||||
// skip bytes BOM signature
|
||||
// Skip bytes BOM signature
|
||||
if ((byte)line[0] == 0xEFu && (byte)line[1] == 0xBBu && (byte)line[2] == 0xBFu)
|
||||
pos = &line[3];
|
||||
else
|
||||
@ -369,38 +409,33 @@ void CResourceFile::LoadResources()
|
||||
bBreak = false;
|
||||
flag = RES_TYPE_NONE;
|
||||
|
||||
memset(hash, 0, sizeof(hash));
|
||||
Q_memset(hash, 0, sizeof(hash));
|
||||
|
||||
while (pToken && argc <= MAX_PARSE_ARGUMENT)
|
||||
{
|
||||
len = strlen(pToken);
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case ARG_TYPE_FILE_NAME:
|
||||
{
|
||||
strncpy(filename, pToken, len);
|
||||
filename[len] = '\0';
|
||||
Q_strlcpy(filename, pToken);
|
||||
break;
|
||||
}
|
||||
case ARG_TYPE_FILE_HASH:
|
||||
{
|
||||
uint8 pbuf[33];
|
||||
Q_strlcpy(pbuf, pToken);
|
||||
|
||||
strncpy((char *)pbuf, pToken, len);
|
||||
pbuf[len] = '\0';
|
||||
|
||||
if (_stricmp((const char *)pbuf, "UNKNOWN") == 0)
|
||||
if (Q_stricmp((const char *)pbuf, "UNKNOWN") == 0)
|
||||
{
|
||||
flag = RES_TYPE_HASH_ANY;
|
||||
}
|
||||
else if (_stricmp((const char *)pbuf, "MISSING") == 0)
|
||||
else if (Q_stricmp((const char *)pbuf, "MISSING") == 0)
|
||||
{
|
||||
flag = RES_TYPE_MISSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < sizeof(pbuf) / 2; ++i)
|
||||
for (int i = 0; i < sizeof(pbuf) / 2; i++)
|
||||
hash[i] = hexbyte(&pbuf[i * 2]);
|
||||
|
||||
flag = RES_TYPE_EXISTS;
|
||||
@ -409,33 +444,32 @@ void CResourceFile::LoadResources()
|
||||
}
|
||||
case ARG_TYPE_CMD_EXEC:
|
||||
{
|
||||
strncpy(cmdBufExec, pToken, len);
|
||||
cmdBufExec[len] = '\0';
|
||||
Q_strlcpy(cmdBufExec, pToken);
|
||||
|
||||
if (_stricmp(cmdBufExec, "IGNORE") == 0)
|
||||
if (Q_stricmp(cmdBufExec, "IGNORE") == 0)
|
||||
{
|
||||
flag = RES_TYPE_IGNORE;
|
||||
cmdBufExec[0] = '\0';
|
||||
}
|
||||
else if (_stricmp(cmdBufExec, "BREAK") == 0)
|
||||
else if (Q_stricmp(cmdBufExec, "BREAK") == 0)
|
||||
{
|
||||
bBreak = true;
|
||||
cmdBufExec[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
// replface \' to "
|
||||
// Replace \' to "
|
||||
StringReplace(cmdBufExec, "'", "\"");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARG_TYPE_FLAG:
|
||||
{
|
||||
if (_stricmp(pToken, "IGNORE") == 0)
|
||||
if (Q_stricmp(pToken, "IGNORE") == 0)
|
||||
{
|
||||
flag = RES_TYPE_IGNORE;
|
||||
}
|
||||
else if (_stricmp(pToken, "BREAK") == 0)
|
||||
else if (Q_stricmp(pToken, "BREAK") == 0)
|
||||
{
|
||||
bBreak = true;
|
||||
}
|
||||
@ -449,19 +483,19 @@ void CResourceFile::LoadResources()
|
||||
|
||||
if (++argc == ARG_TYPE_FLAG && pToken == nullptr)
|
||||
{
|
||||
// go to next argument
|
||||
// Go to next argument
|
||||
argc++;
|
||||
}
|
||||
}
|
||||
|
||||
#define LOG_PRINT_FAILED(str, ...)\
|
||||
UTIL_Printf("%s: Failed to load \"" FILE_INI_RESOURCES "\"; %s", __func__, str, __VA_ARGS__);\
|
||||
UTIL_Printf("%s: Failed to load \"%s\"; " str "", __func__, FILE_INI_RESOURCES, __VA_ARGS__);\
|
||||
continue;
|
||||
|
||||
if (argc >= MAX_PARSE_ARGUMENT)
|
||||
{
|
||||
char pchar;
|
||||
if (strlen(filename) <= 0)
|
||||
char pchar = '?';
|
||||
if (Q_strlen(filename) <= 0)
|
||||
{
|
||||
LOG_PRINT_FAILED("path to filename is empty on line %d\n", cline);
|
||||
}
|
||||
@ -477,7 +511,7 @@ void CResourceFile::LoadResources()
|
||||
{
|
||||
LOG_PRINT_FAILED("parsing hash failed on line %d\n", cline);
|
||||
}
|
||||
else if (strlen(cmdBufExec) <= 0 && (flag != RES_TYPE_IGNORE && !bBreak))
|
||||
else if (Q_strlen(cmdBufExec) <= 0 && (flag != RES_TYPE_IGNORE && !bBreak))
|
||||
{
|
||||
LOG_PRINT_FAILED("parsing command line is empty on line %d\n", cline);
|
||||
}
|
||||
@ -500,7 +534,7 @@ const char *CResourceFile::GetNextToken(char **pbuf)
|
||||
if (*rpos == '\0')
|
||||
return nullptr;
|
||||
|
||||
// skip spaces at the beginning
|
||||
// Skip spaces at the beginning
|
||||
while (*rpos != '\0' && isspace(*rpos))
|
||||
rpos++;
|
||||
|
||||
@ -563,12 +597,12 @@ CResourceBuffer *CResourceFile::Add(const char *filename, char *cmdExec, Resourc
|
||||
{
|
||||
auto nRes = new CResourceBuffer(filename, cmdExec, flag, hash, line, bBreak);
|
||||
|
||||
// to mark files which are not required to add to the resource again
|
||||
// To mark files which are not required to add to the resource again
|
||||
for (auto res : m_resourceList)
|
||||
{
|
||||
if (_stricmp(res->GetFileName(), filename) == 0)
|
||||
if (Q_stricmp(res->GetFileName(), filename) == 0)
|
||||
{
|
||||
// resource name already registered
|
||||
// Resource name already registered
|
||||
nRes->SetDuplicate();
|
||||
break;
|
||||
}
|
||||
@ -593,7 +627,7 @@ void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceB
|
||||
// Fire query to callback's
|
||||
for (auto query : g_QueryFiles)
|
||||
{
|
||||
if (!res->IsAddEx() || strcmp(query->filename, pRes->GetFileName()) != 0)
|
||||
if (!res->IsAddEx() || Q_strcmp(query->filename, pRes->GetFileName()) != 0)
|
||||
continue;
|
||||
|
||||
if (query->flag == typeFind) {
|
||||
@ -601,7 +635,7 @@ void EXT_FUNC FileConsistencyProcess_hook(IGameClient *pSenderClient, IResourceB
|
||||
}
|
||||
}
|
||||
|
||||
// push exec cmd
|
||||
// Push exec cmd
|
||||
Exec.Add(pSenderClient, pRes, hash);
|
||||
g_pResource->PrintLog(pSenderClient, pRes, typeFind, hash);
|
||||
}
|
||||
@ -610,18 +644,18 @@ void CResourceFile::PrintLog(IGameClient *pSenderClient, CResourceBuffer *res, R
|
||||
{
|
||||
flag_type_log type = (typeFind == RES_TYPE_IGNORE) ? LOG_DETAILED : LOG_NORMAL;
|
||||
Log(type, " -> file: (%s), exphash: (%x), got: (%x), typeFind: (%s), prevhash: (%x), (#%u)(%s), prevfile: (%s), findathash: (%s), md5hex: (%x), ex: (%d)",
|
||||
res->GetFileName(), res->GetFileHash(), hash, szTypeNames[ typeFind ], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()),
|
||||
res->GetFileName(), res->GetFileHash(), hash, m_TypeNames[typeFind], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()),
|
||||
pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash), res->IsAddEx());
|
||||
}
|
||||
|
||||
IResourceBuffer *CResourceFile::GetResourceFile(const char *filename)
|
||||
{
|
||||
// to mark files which are not required to add to the resource again
|
||||
// To mark files which are not required to add to the resource again
|
||||
for (auto res : m_resourceList)
|
||||
{
|
||||
if (_stricmp(res->GetFileName(), filename) == 0)
|
||||
if (Q_stricmp(res->GetFileName(), filename) == 0)
|
||||
{
|
||||
// resource name already have, return its;
|
||||
// Resource name already have, return its;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -650,7 +684,7 @@ IResponseBuffer *CResourceFile::GetResponseFile(IGameClient *pClient, const char
|
||||
break;
|
||||
}
|
||||
|
||||
if (_stricmp(res->GetFileName(), filename) == 0) {
|
||||
if (Q_stricmp(res->GetFileName(), filename) == 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -665,7 +699,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
||||
std::vector<CResourceBuffer *> tempResourceList;
|
||||
|
||||
if (resource->type != t_decal
|
||||
|| resource->nIndex < 4095) // if by some miracle the decals will have the flag RES_CHECKFILE
|
||||
|| resource->nIndex < 4095) // If by some miracle the decals will have the flag RES_CHECKFILE
|
||||
// to be sure not bypass the decals
|
||||
{
|
||||
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
||||
@ -673,16 +707,28 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
||||
return true;
|
||||
}
|
||||
|
||||
// strange thing
|
||||
// Strange thing
|
||||
// if this happened when missing all the files from client
|
||||
if (!m_PrevHash)
|
||||
{
|
||||
// Received a head file
|
||||
if (!Q_stricmp(resource->szFileName, m_HeadFileName))
|
||||
{
|
||||
if (hash == 0) {
|
||||
Log(LOG_DETAILED, "WARNING: %s received unwanted hash: (%x)\n", m_HeadFileName, hash);
|
||||
}
|
||||
|
||||
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
||||
m_PrevHash = hash;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto res : m_resourceList)
|
||||
{
|
||||
if (strcmp(resource->szFileName, res->GetFileName()) != 0)
|
||||
if (Q_strcmp(resource->szFileName, res->GetFileName()) != 0)
|
||||
continue;
|
||||
|
||||
typeFind = res->GetFileFlag();
|
||||
@ -704,7 +750,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
||||
case RES_TYPE_HASH_ANY:
|
||||
for (auto temp : tempResourceList)
|
||||
{
|
||||
if (_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
|
||||
if (Q_stricmp(temp->GetFileName(), res->GetFileName()) != 0)
|
||||
continue;
|
||||
|
||||
if (temp->GetFileHash() == hash)
|
||||
@ -731,6 +777,7 @@ bool CResourceFile::FileConsistencyResponse(IGameClient *pSenderClient, resource
|
||||
|
||||
AddFileResponse(pSenderClient, resource->szFileName, hash);
|
||||
m_PrevHash = hash;
|
||||
|
||||
return !bHandled;
|
||||
}
|
||||
|
||||
@ -738,11 +785,11 @@ const char *CResourceFile::DuplicateString(const char *str)
|
||||
{
|
||||
for (auto string : m_StringsCache)
|
||||
{
|
||||
if (!strcmp(string, str))
|
||||
if (!Q_strcmp(string, str))
|
||||
return string;
|
||||
}
|
||||
|
||||
const char *s = strcpy(new char[strlen(str) + 1], str);
|
||||
const char *s = Q_strcpy(new char[Q_strlen(str) + 1], str);
|
||||
m_StringsCache.push_back(s);
|
||||
return s;
|
||||
}
|
||||
|
@ -1,11 +1,30 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FILE_INI_RESOURCES "resources.ini"
|
||||
#define MAX_CMD_LENGTH 128
|
||||
#define MAX_RANGE_CONSISTENCY 1024
|
||||
const int MAX_CMD_LENGTH = 128;
|
||||
const int MAX_RANGE_CONSISTENCY = 1024;
|
||||
|
||||
#define RESOURCE_INDEX_BITS 12
|
||||
#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS)
|
||||
const int RESOURCE_INDEX_BITS = 12;
|
||||
const int RESOURCE_MAX_COUNT = BIT(RESOURCE_INDEX_BITS);
|
||||
|
||||
constexpr char *FILE_INI_RESOURCES = "resources.ini";
|
||||
|
||||
enum flag_type_log
|
||||
{
|
||||
@ -98,6 +117,7 @@ private:
|
||||
|
||||
private:
|
||||
// for temporary files of responses
|
||||
void AddHeadResource();
|
||||
void AddFileResponse(IGameClient *pSenderClient, char *filename, uint32 hash);
|
||||
void LogPrepare();
|
||||
|
||||
@ -111,14 +131,18 @@ private:
|
||||
typedef std::vector<CResourceBuffer *> ResourceList;
|
||||
typedef std::vector<CResponseBuffer *> ResponseList;
|
||||
|
||||
static constexpr char *m_TypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" };
|
||||
static constexpr char *m_HeadFileName = "delta.lst";
|
||||
|
||||
ResourceList m_resourceList;
|
||||
ResponseList m_responseList;
|
||||
|
||||
resource_t m_HeadResource;
|
||||
int m_ConsistencyNum;
|
||||
uint32 m_PrevHash;
|
||||
|
||||
char m_PathDir[MAX_PATH];
|
||||
char m_LogFilePath[MAX_PATH]; // log data
|
||||
char m_LogFilePath[MAX_PATH]; // Log data
|
||||
|
||||
typedef std::vector<const char *> StringList;
|
||||
static StringList m_StringsCache;
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
void UTIL_Printf(const char *fmt, ...)
|
||||
@ -6,7 +24,7 @@ void UTIL_Printf(const char *fmt, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
// Print to server console
|
||||
@ -19,7 +37,7 @@ void UTIL_LogPrintf(const char *fmt, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
// Print to log
|
||||
@ -32,7 +50,7 @@ char *UTIL_VarArgs(const char *format, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, format);
|
||||
vsnprintf(string, sizeof(string), format, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string;
|
||||
@ -44,7 +62,7 @@ void NORETURN Sys_Error(const char *error, ...)
|
||||
static char text[1024];
|
||||
|
||||
va_start(argptr, error);
|
||||
vsnprintf(text, ARRAYSIZE(text), error, argptr);
|
||||
Q_vsnprintf(text, ARRAYSIZE(text), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -57,6 +75,7 @@ void NORETURN Sys_Error(const char *error, ...)
|
||||
UTIL_Printf("FATAL ERROR (shutting down): %s\n", text);
|
||||
|
||||
//TerminateProcess(GetCurrentProcess(), 1);
|
||||
*((int*)NULL) = 0;
|
||||
while (true);
|
||||
int *null = 0;
|
||||
*null = 0;
|
||||
exit(-1);
|
||||
}
|
||||
|
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