Start working.

Implemented CBufExec.
This commit is contained in:
s1lentq 2015-11-09 00:38:31 +06:00
parent f2f11dc3ae
commit 6e4dbe9da7
16 changed files with 602 additions and 208 deletions

View File

@ -141,9 +141,9 @@ typedef IVoidHookChainRegistry<edict_t *, int, const char *, float, float, int,
typedef IVoidHookChain<IGameClient *, char *, size_t, sizebuf_t *, IGameClient *> IRehldsHook_SV_WriteFullClientUpdate; typedef IVoidHookChain<IGameClient *, char *, size_t, sizebuf_t *, IGameClient *> IRehldsHook_SV_WriteFullClientUpdate;
typedef IVoidHookChainRegistry<IGameClient *, char *, size_t, sizebuf_t *, IGameClient *> IRehldsHookRegistry_SV_WriteFullClientUpdate; typedef IVoidHookChainRegistry<IGameClient *, char *, size_t, sizebuf_t *, IGameClient *> IRehldsHookRegistry_SV_WriteFullClientUpdate;
//SV_GenericFileConsistencyResponce hook //SV_CheckConsistencyResponce hook
typedef IVoidHookChain<IGameClient *, resource_t *, uint32> IRehldsHook_GenericFileConsistencyResponce; typedef IHookChain<bool, IGameClient *, resource_t *, uint32> IRehldsHook_SV_CheckConsistencyResponce;
typedef IVoidHookChainRegistry<IGameClient *, resource_t *, uint32> IRehldsHookRegistry_GenericFileConsistencyResponce; typedef IHookChainRegistry<bool, IGameClient *, resource_t *, uint32> IRehldsHookRegistry_SV_CheckConsistencyResponce;
class IRehldsHookchains { class IRehldsHookchains {
public: public:
@ -175,7 +175,7 @@ public:
virtual IRehldsHookRegistry_PF_Remove_I* PF_Remove_I() = 0; virtual IRehldsHookRegistry_PF_Remove_I* PF_Remove_I() = 0;
virtual IRehldsHookRegistry_PF_BuildSoundMsg_I* PF_BuildSoundMsg_I() = 0; virtual IRehldsHookRegistry_PF_BuildSoundMsg_I* PF_BuildSoundMsg_I() = 0;
virtual IRehldsHookRegistry_SV_WriteFullClientUpdate* SV_WriteFullClientUpdate() = 0; virtual IRehldsHookRegistry_SV_WriteFullClientUpdate* SV_WriteFullClientUpdate() = 0;
virtual IRehldsHookRegistry_GenericFileConsistencyResponce* GenericFileConsistencyResponce() = 0; virtual IRehldsHookRegistry_SV_CheckConsistencyResponce* SV_CheckConsistencyResponce() = 0;
}; };
struct RehldsFuncs_t { struct RehldsFuncs_t {
@ -211,6 +211,7 @@ struct RehldsFuncs_t {
void*(*SZ_GetSpace)(sizebuf_t *buf, int length); void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
cvar_t*(*GetCvarVars)(); cvar_t*(*GetCvarVars)();
int (*SV_GetChallenge)(const netadr_t& adr); int (*SV_GetChallenge)(const netadr_t& adr);
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
}; };
class IRehldsApi { class IRehldsApi {
@ -222,7 +223,6 @@ public:
virtual const RehldsFuncs_t* GetFuncs() = 0; virtual const RehldsFuncs_t* GetFuncs() = 0;
virtual IRehldsHookchains* GetHookchains() = 0; virtual IRehldsHookchains* GetHookchains() = 0;
virtual IRehldsServerStatic* GetServerStatic() = 0; virtual IRehldsServerStatic* GetServerStatic() = 0;
virtual IRehldsServer* GetServer() = 0;
virtual IRehldsServerData* GetServerData() = 0; virtual IRehldsServerData* GetServerData() = 0;
virtual IRehldsFlightRecorder* GetFlightRecorder() = 0; virtual IRehldsFlightRecorder* GetFlightRecorder() = 0;
}; };

View File

@ -90,18 +90,6 @@ public:
struct client_t; struct client_t;
#endif #endif
class IRehldsServer {
public:
virtual ~IRehldsServer() { }
virtual int GetNumResources() = 0;
virtual int GetNumConsistency() = 0;
virtual void SetNumConsistency(int iValue) = 0;
virtual void SetNumResources(int iValue) = 0;
virtual resource_t *GetResourceList() = 0;
virtual struct consistency_s *GetConsistencyList() = 0;
};
class IRehldsServerStatic { class IRehldsServerStatic {
public: public:
virtual ~IRehldsServerStatic() { } virtual ~IRehldsServerStatic() { }
@ -125,4 +113,6 @@ public:
virtual sizebuf_t* GetReliableDatagram() = 0; virtual sizebuf_t* GetReliableDatagram() = 0;
virtual void SetModelName(const char* modelname) = 0; virtual void SetModelName(const char* modelname) = 0;
virtual void SetConsistencyNum(int num) = 0;
virtual int GetConsistencyNum() = 0;
}; };

View File

@ -163,6 +163,7 @@
<ClInclude Include="..\pm_shared\pm_shared.h" /> <ClInclude Include="..\pm_shared\pm_shared.h" />
<ClInclude Include="..\public\FileSystem.h" /> <ClInclude Include="..\public\FileSystem.h" />
<ClInclude Include="..\public\interface.h" /> <ClInclude Include="..\public\interface.h" />
<ClInclude Include="..\src\cmdexec.h" />
<ClInclude Include="..\src\config.h" /> <ClInclude Include="..\src\config.h" />
<ClInclude Include="..\src\engine_rehlds.h" /> <ClInclude Include="..\src\engine_rehlds.h" />
<ClInclude Include="..\src\main.h" /> <ClInclude Include="..\src\main.h" />
@ -173,6 +174,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\public\interface.cpp" /> <ClCompile Include="..\public\interface.cpp" />
<ClCompile Include="..\src\cmdexec.cpp" />
<ClCompile Include="..\src\config.cpp" /> <ClCompile Include="..\src\config.cpp" />
<ClCompile Include="..\src\dllapi.cpp" /> <ClCompile Include="..\src\dllapi.cpp" />
<ClCompile Include="..\src\engine_api.cpp" /> <ClCompile Include="..\src\engine_api.cpp" />

View File

@ -461,6 +461,7 @@
<ClInclude Include="..\src\precompiled.h" /> <ClInclude Include="..\src\precompiled.h" />
<ClInclude Include="..\src\engine_rehlds.h" /> <ClInclude Include="..\src\engine_rehlds.h" />
<ClInclude Include="..\src\config.h" /> <ClInclude Include="..\src\config.h" />
<ClInclude Include="..\src\cmdexec.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\common\parsemsg.cpp"> <ClCompile Include="..\common\parsemsg.cpp">
@ -478,6 +479,7 @@
<ClCompile Include="..\src\precompiled.cpp" /> <ClCompile Include="..\src\precompiled.cpp" />
<ClCompile Include="..\src\sdk_util.cpp" /> <ClCompile Include="..\src\sdk_util.cpp" />
<ClCompile Include="..\src\config.cpp" /> <ClCompile Include="..\src\config.cpp" />
<ClCompile Include="..\src\cmdexec.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="sdk"> <Filter Include="sdk">

110
src/cmdexec.cpp Normal file
View File

@ -0,0 +1,110 @@
#include "precompiled.h"
CBufExec CmdExec;
CBufExecNew::CBufExecNew(IGameClient *pClient, CResourceCheckerNew *pResource)
{
m_pClient = pClient;
m_pResource = pResource;
}
CBufExecNew::~CBufExecNew()
{
;
}
void CBufExec::AddElement(IGameClient *pClient, CResourceCheckerNew *pResource)
{
m_vector.push_back(new CBufExecNew(pClient, pResource));
}
void StringReplace(char *src, const char *strold, const char *strnew)
{
if (strnew == NULL) {
return;
}
char *p = src;
int oldLen = strlen(strold), newLen = strlen(strnew);
while ((p = strstr(p, strold)) != NULL)
{
if (oldLen != newLen)
memmove(p + newLen, p + oldLen, strlen(p) - oldLen + 1);
memcpy(p, strnew, newLen);
p += newLen;
}
}
char *GetExecCmdPrepare(IGameClient *pClient, CResourceCheckerNew *pResource)
{
int len;
const netadr_t *net;
static char string[256];
strncpy(string, pResource->GetCmdExec(), sizeof(string) - 1);
string[sizeof(string) - 1] = '\0';
net = pClient->GetNetChan()->GetRemoteAdr();
// replace of templates for identification
StringReplace(string, "[name]", pClient->GetName());
StringReplace(string, "[userid]", UTIL_VarArgs("#%u", g_engfuncs.pfnGetPlayerUserId(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]));
// replace key values
StringReplace(string, "[file_name]", pResource->GetFileName());
StringReplace(string, "[file_hash]", UTIL_VarArgs("%x", pResource->GetHashFile()));
len = strlen(string);
if (len < sizeof(string) - 2) {
strcat(string, "\n");
}
else
string[len - 1] = '\n';
return string;
}
void CBufExec::Exec(IGameClient *pClient)
{
CBufExecVectorIt it = m_vector.begin();
while (it != m_vector.end())
{
CBufExecNew *exc = (*it);
if (exc->GetGameClient() != pClient) {
it++;
continue;
}
// exit the loop if the client is out of the game
// TODO: Check me!
if (!pClient->IsConnected()) {
break;
}
char *cmdExec = GetExecCmdPrepare(pClient, exc->GetResource());
if (cmdExec != NULL && cmdExec[0] != '\0') {
// execute cmd
SERVER_COMMAND(cmdExec);
// erase cmd exec
delete exc;
it = m_vector.erase(it);
}
else
it++;
}
}
void CBufExec::Clear()
{
m_vector.clear();
}

35
src/cmdexec.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include <vector>
class CBufExecNew
{
public:
CBufExecNew(IGameClient *pClient, CResourceCheckerNew *pResource);
~CBufExecNew();
IGameClient *GetGameClient() { return m_pClient; };
CResourceCheckerNew *GetResource() { return m_pResource; };
private:
IGameClient *m_pClient;
CResourceCheckerNew *m_pResource;
};
typedef std::vector<CBufExecNew *> CBufExecVector;
typedef CBufExecVector::iterator CBufExecVectorIt;
class CBufExec
{
public:
void AddElement(IGameClient *pClient, CResourceCheckerNew *pResource);
void Exec(IGameClient *pClient);
void Clear();
private:
CBufExecVector m_vector;
};
extern CBufExec CmdExec;
extern void StringReplace(char *src, const char *strold, const char *strnew);

View File

@ -2,6 +2,38 @@
CConfig Config; CConfig Config;
void CConfig::AddResource()
{
ResourceCheckerVectorIt it = m_vector.begin();
int nConsistency = g_RehldsServerData->GetConsistencyNum();
while (it != m_vector.end())
{
CResourceCheckerNew *pRes = (*it);
// prevent duplicate of filenames
// check if filename is been marked so do not add the resource again
if (pRes->GetMark() != true) {
#ifdef _DEBUG
printf(__FUNCTION__ " :: (%s)(%s)\n", pRes->GetFileName(), pRes->GetCmdExec());
#endif // _DEBUG
SV_AddResource(t_decal, pRes->GetFileName(), 0, RES_CHECKFILE, 4095);
nConsistency++;
}
it++;
}
g_RehldsServerData->SetConsistencyNum(nConsistency);
}
void CConfig::ClearResources()
{
m_PreHash = 0;
// clear resources
m_vector.clear();
}
void CConfig::Init() void CConfig::Init()
{ {
char *pos; char *pos;
@ -22,8 +54,11 @@ void CConfig::Init()
// resources.ini // resources.ini
snprintf(m_szPathResourcesDir, sizeof(m_szPathResourcesDir) - 1, "%s" FILE_INI_RESOURCES, path); snprintf(m_szPathResourcesDir, sizeof(m_szPathResourcesDir) - 1, "%s" FILE_INI_RESOURCES, path);
}
ParseConfig(); void CConfig::Load()
{
//ParseConfig();
ParseResources(); ParseResources();
} }
@ -33,7 +68,8 @@ void CConfig::ParseConfig()
if (fp == NULL) if (fp == NULL)
{ {
UTIL_LogPrintf(__FUNCTION__ ": can't find path to " FILE_INI_CONFIG); UTIL_Printf(__FUNCTION__ ": can't find path to " FILE_INI_CONFIG "\n");
return;
} }
// soon coming.. // soon coming..
@ -47,6 +83,50 @@ inline uint8 hexbyte(uint8 *hex)
| (hex[1] > '9' ? toupper(hex[1]) - 'A' + 10 : hex[1] - '0'); | (hex[1] > '9' ? toupper(hex[1]) - 'A' + 10 : hex[1] - '0');
} }
inline bool invalidchar(const char c)
{
// to check for invalid characters
return (c == '\\' || c == '/' || c == ':'
|| c == '*' || c == '?'
|| c == '"' || c == '<'
|| c == '>' || c == '|') != 0;
}
bool FileIsValidChar(char *psrc, char &pchar) {
char *pch = strrchr(psrc, '/');
if (pch == NULL) {
pch = psrc;
}
while (*pch++) {
if (invalidchar(*pch)) {
pchar = *pch;
return false;
}
}
return true;
}
bool FileIsExtension(char *psrc) {
// find the extension filename
char *pch = strrchr(psrc, '.');
if (pch == NULL) {
return false;
}
// the size extension
if (strlen(&pch[1]) <= 0) {
return false;
}
return strchr(pch, '/') == NULL;
}
void CConfig::ParseResources() void CConfig::ParseResources()
{ {
char *pos; char *pos;
@ -54,23 +134,26 @@ void CConfig::ParseResources()
uint8 hash[16]; uint8 hash[16];
FILE *fp; FILE *fp;
int argc; int argc;
flag_type_resources flags = FLAG_TYPE_NONE; int len;
flag_type_resources flag = FLAG_TYPE_NONE;
char filename[MAX_PATH_LENGTH]; char filename[MAX_PATH_LENGTH];
char cmdPunish[MAX_PATH_LENGTH]; char cmdBufExec[MAX_PATH_LENGTH];
int cline = 0;
fp = fopen(m_szPathResourcesDir, "r"); fp = fopen(m_szPathResourcesDir, "r");
if (fp == NULL) if (fp == NULL)
{ {
UTIL_LogPrintf(__FUNCTION__ ": can't find path to " FILE_INI_RESOURCES); m_ConfigFailed = false;
UTIL_Printf(__FUNCTION__ ": can't find path to " FILE_INI_RESOURCES "\n");
return; return;
} }
while (!feof(fp) && fgets(buffer, sizeof(buffer) - 1, fp)) while (!feof(fp) && fgets(buffer, sizeof(buffer) - 1, fp))
{ {
pos = &buffer[0]; pos = buffer;
// TrimSpace(pos); cline++;
if (*pos == '\0' || *pos == ';' || *pos == '\\' || *pos == '/' || *pos == '#') if (*pos == '\0' || *pos == ';' || *pos == '\\' || *pos == '/' || *pos == '#')
continue; continue;
@ -78,44 +161,48 @@ void CConfig::ParseResources()
const char *pToken = GetNextToken(&pos); const char *pToken = GetNextToken(&pos);
argc = 0; argc = 0;
memset(hash, 0, sizeof(hash)); hash[0] = '\0';
flag = FLAG_TYPE_NONE;
while (pToken != NULL && argc <= MAX_PARSE_ARGUMENT) while (pToken != NULL && argc <= MAX_PARSE_ARGUMENT)
{ {
int iLen = strlen(pToken); len = strlen(pToken);
switch (argc) switch (argc)
{ {
case ARG_TYPE_FILE_NAME: case ARG_TYPE_FILE_NAME:
{ {
strncpy(filename, pToken, iLen + 1); strncpy(filename, pToken, len + 1);
filename[iLen + 1] = '\0'; filename[len + 1] = '\0';
break; break;
} }
case ARG_TYPE_FILE_HASH: case ARG_TYPE_FILE_HASH:
{ {
uint8 pbuf[33]; uint8 pbuf[33];
strncpy((char *)pbuf, pToken, iLen); strncpy((char *)pbuf, pToken, len);
pbuf[iLen] = '\0'; pbuf[len] = '\0';
for (int i = 0; i < sizeof(pbuf) / 2; i++) if (_stricmp((const char *)pbuf, "UNKNOWN") == 0) {
hash[i] = hexbyte(&pbuf[i * 2]); flag = FLAG_TYPE_HASH_ANY;
}
else
{
for (int i = 0; i < sizeof(pbuf) / 2; i++)
hash[i] = hexbyte(&pbuf[i * 2]);
flag = (*(uint32 *)&hash[0] != 0x00000000) ? FLAG_TYPE_EXISTS : FLAG_TYPE_MISSGIN;
}
break; break;
} }
case ARG_TYPE_CMD_PUNISH: case ARG_TYPE_CMD_EXEC:
{ {
strncpy(cmdPunish, pToken, iLen + 1); strncpy(cmdBufExec, pToken, len + 1);
cmdPunish[iLen + 1] = '\0'; cmdBufExec[len + 1] = '\0';
// replface \' to " // replface \' to "
StringReplace(cmdPunish, "'", "\""); StringReplace(cmdBufExec, "'", "\"");
break;
}
case ARG_TYPE_FILE_FLAGS:
{
// TODO: Implement me flags
break; break;
} }
default: default:
@ -127,7 +214,34 @@ void CConfig::ParseResources()
} }
if (argc >= MAX_PARSE_ARGUMENT) { if (argc >= MAX_PARSE_ARGUMENT) {
AddElement(filename, cmdPunish, flags, *(uint32 *)&hash[0]);
char pchar;
if (strlen(filename) <= 0) {
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; path to filename is empty on line %d\n", cline);
continue;
}
else if (!FileIsExtension(filename)) {
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; filename has no extension on line %d\n", cline);
continue;
}
else if (!FileIsValidChar(filename, pchar)) {
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; filename has invalid character '%c' on line %d\n", pchar, cline);
continue;
}
else if (flag == FLAG_TYPE_NONE) {
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; parsing hash failed on line %d\n", cline);
continue;
}
else if (strlen(cmdBufExec) <= 0) {
UTIL_Printf(__FUNCTION__ ": Failed to load \"" FILE_INI_RESOURCES "\"; command line is empty on line %d\n", cline);
continue;
}
AddElement(filename, cmdBufExec, flag, *(uint32 *)&hash[0]);
} }
} }
@ -140,7 +254,7 @@ const char *CConfig::GetNextToken(char **pbuf)
if (*rpos == '\0') if (*rpos == '\0')
return NULL; return NULL;
//skip spaces at the beginning // skip spaces at the beginning
while (*rpos != 0 && isspace(*rpos)) while (*rpos != 0 && isspace(*rpos))
rpos++; rpos++;
@ -197,7 +311,7 @@ const char *CConfig::GetNextToken(char **pbuf)
return res; return res;
} }
void CConfig::TrimSpace(char *pbuf) void TrimSpace(char *pbuf)
{ {
char *pend = pbuf; char *pend = pbuf;
char *pstart = pbuf; char *pstart = pbuf;
@ -226,65 +340,91 @@ void CConfig::TrimSpace(char *pbuf)
*pend = '\0'; *pend = '\0';
} }
void CConfig::AddElement(char *filename, char *cmdPunish, flag_type_resources flags, uint32 hash) void CConfig::AddElement(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash)
{ {
m_vector.push_back(new CResourceCheckerNew(filename, cmdPunish, flags, hash)); m_vector.push_back(new CResourceCheckerNew(filename, cmdExec, flag, hash));
}
char *CConfig::CommandPunishment(IGameClient *pClient, const char *src) // to mark files which are not required to add to the resource again
{ for (ResourceCheckerVectorIt it = m_vector.begin(); it != m_vector.end(); ++it)
char szIp[16];
edict_t *pEdict;
const netadr_t *net;
static char string[256];
strncpy(string, src, sizeof(string) - 1);
string[sizeof(string) - 1] = '\0';
pEdict = pClient->GetEdict();
net = pClient->GetNetChan()->GetRemoteAdr();
snprintf(szIp, sizeof(szIp), "%i.%i.%i.%i", net->ip[0], net->ip[1], net->ip[2], net->ip[3]);
// replace of templates punishment
StringReplace(string, "[name]", STRING(pEdict->v.netname));
StringReplace(string, "[userid]", UTIL_VarArgs("%u", g_engfuncs.pfnGetPlayerUserId(pEdict)));
StringReplace(string, "[steamid]", UTIL_VarArgs("%s", g_engfuncs.pfnGetPlayerAuthId(pEdict)));
StringReplace(string, "[ip]", szIp);
//SERVER_COMMAND(UTIL_VarArgs("%s\n", string));
return string;
}
void CConfig::StringReplace(char *src, const char *strold, const char *strnew)
{
char *p = src;
int oldLen = strlen(strold), newLen = strlen(strnew);
while ((p = strstr(p, strold)) != NULL)
{ {
if (oldLen != newLen) CResourceCheckerNew *pRes = (*it);
memmove(p + newLen, p + oldLen, strlen(p) - oldLen + 1);
memcpy(p, strnew, newLen); // do not check the last element
p += newLen; if (pRes == m_vector.back())
continue;
if (_stricmp(pRes->GetFileName(), filename) == 0) {
// set be marked
pRes->SetMark();
}
} }
} }
CResourceCheckerNew::CResourceCheckerNew(char *filename, char *cmdPunish, flag_type_resources flags, uint32 hash) bool CConfig::FileConsistencyResponce(IGameClient *pSenderClient, resource_t *resource, uint32 hash)
{
bool bCheckeFiles = false;
find_type_e typeFind = FIND_TYPE_NONE;
for (ResourceCheckerVectorIt it = m_vector.begin(); it != m_vector.end(); ++it)
{
CResourceCheckerNew *pRes = (*it);
if (strcmp(resource->szFileName, pRes->GetFileName()) != 0)
continue;
bCheckeFiles = true;
switch (pRes->GetFlagFile())
{
case FLAG_TYPE_EXISTS:
if (m_PreHash != hash && pRes->GetHashFile() == hash) {
typeFind = FIND_TYPE_ON_HASH;
}
break;
case FLAG_TYPE_MISSGIN:
if (m_PreHash == hash) {
typeFind = FIND_TYPE_MISSING;
}
break;
case FLAG_TYPE_HASH_ANY:
if (m_PreHash != hash) {
typeFind = FIND_TYPE_ANY_HASH;
}
break;
default:
typeFind = FIND_TYPE_NONE;
break;
}
if (typeFind != FIND_TYPE_NONE) {
// push exec cmd
CmdExec.AddElement(pSenderClient, pRes);
#ifdef _DEBUG
printf("* (%s)(%s)(%x)\n", pRes->GetFileName(), pRes->GetCmdExec(), pRes->GetHashFile());
#endif // _DEBUG
}
}
m_PreHash = hash;
return !bCheckeFiles;
}
CResourceCheckerNew::CResourceCheckerNew(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash)
{ {
int iLenFile = strlen(filename); int iLenFile = strlen(filename);
int iLenPunish = strlen(cmdPunish); int iLenExec = strlen(cmdExec);
m_FileName = new char[iLenFile + 1]; m_FileName = new char[iLenFile + 1];
m_Punishment = new char[iLenPunish + 1]; m_CmdExec = new char[iLenExec + 1];
strncpy(m_FileName, filename, iLenFile); strncpy(m_FileName, filename, iLenFile);
strncpy(m_Punishment, cmdPunish, iLenPunish); strncpy(m_CmdExec, cmdExec, iLenExec);
m_FileName[iLenFile] = '\0'; m_FileName[iLenFile] = '\0';
m_Punishment[iLenPunish] = '\0'; m_CmdExec[iLenExec] = '\0';
m_Mark = false;
m_Flags = flags; m_Flag = flag;
m_HashFile = hash; m_HashFile = hash;
} }
@ -292,5 +432,5 @@ CResourceCheckerNew::~CResourceCheckerNew()
{ {
// free me // free me
delete[] m_FileName, delete[] m_FileName,
m_Punishment; m_CmdExec;
} }

View File

@ -5,44 +5,60 @@
#define FILE_INI_CONFIG "config.ini" #define FILE_INI_CONFIG "config.ini"
#define FILE_INI_RESOURCES "resources.ini" #define FILE_INI_RESOURCES "resources.ini"
#define MAX_PARSE_ARGUMENT 3
//#ifdef MAX_PATH //#ifdef MAX_PATH
//#define MAX_PATH 260 //#define MAX_PATH 260
//#endif // MAX_PATH //#endif // MAX_PATH
#define MAX_CLIENTS 32
#define MAX_CMD_LENGTH 128 #define MAX_CMD_LENGTH 128
#define MAX_PATH_LENGTH 260 #define MAX_PATH_LENGTH 260
enum enum find_type_e
{
FIND_TYPE_NONE = 0,
FIND_TYPE_ON_HASH,
FIND_TYPE_ANY_HASH,
FIND_TYPE_MISSING
};
enum arg_type_e
{ {
ARG_TYPE_FILE_NAME = 0, ARG_TYPE_FILE_NAME = 0,
ARG_TYPE_FILE_HASH, ARG_TYPE_FILE_HASH,
ARG_TYPE_CMD_PUNISH, ARG_TYPE_CMD_EXEC,
ARG_TYPE_FILE_FLAGS,
MAX_PARSE_ARGUMENT,
}; };
typedef enum enum flag_type_resources
{ {
FLAG_TYPE_NONE = 0, FLAG_TYPE_NONE = 0,
FLAG_TYPE_EXISTS = (1<<0), FLAG_TYPE_EXISTS,
FLAG_TYPE_MISSGIN = (1<<1), FLAG_TYPE_MISSGIN,
FLAG_TYPE_HASH_ANY = (1<<2), FLAG_TYPE_HASH_ANY,
};
} flag_type_resources;
class CResourceCheckerNew class CResourceCheckerNew
{ {
public: public:
//CResourceCheckerNew(void); CResourceCheckerNew(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash);
CResourceCheckerNew(char *filename, char *cmdPunish, flag_type_resources flags, uint32 hash);
~CResourceCheckerNew(); ~CResourceCheckerNew();
uint32 m_HashFile; uint32 GetHashFile() { return m_HashFile; };
flag_type_resources m_Flags; flag_type_resources GetFlagFile() { return m_Flag; };
char *m_FileName;//[MAX_PATH_LENGTH]; char *GetFileName() { return m_FileName; };
char *m_Punishment;//[MAX_CMD_LENGTH]; char *GetCmdExec() { return m_CmdExec; };
bool GetMark() { return m_Mark; };
void SetMark() { m_Mark = true; };
private:
uint32 m_HashFile;
flag_type_resources m_Flag;
char *m_FileName;
char *m_CmdExec;
bool m_Mark;
}; };
typedef std::vector<CResourceCheckerNew *> ResourceCheckerVector; typedef std::vector<CResourceCheckerNew *> ResourceCheckerVector;
@ -52,24 +68,30 @@ class CConfig
{ {
public: public:
void Init(); void Init();
char *CommandPunishment(IGameClient *pClient, const char *src); void Load();
ResourceCheckerVector *GetVector() { return &m_vector; };
void AddResource();
void ClearResources();
bool FileConsistencyResponce(IGameClient *pSenderClient, resource_t *resource, uint32 hash);
bool IsConfigLoaded() { return !m_ConfigFailed; };
private: private:
void ParseConfig(); void ParseConfig();
void ParseResources(); void ParseResources();
void AddElement(char *filename, char *cmdPunish, flag_type_resources flags, uint32 hash); void AddElement(char *filename, char *cmdExec, flag_type_resources flag, uint32 hash);
// parse // parse
const char *GetNextToken(char **pbuf); const char *GetNextToken(char **pbuf);
void TrimSpace(char *pbuf);
void StringReplace(char *src, const char *strold, const char *strnew);
private: private:
ResourceCheckerVector m_vector; ResourceCheckerVector m_vector;
uint32 m_PreHash;
bool m_ConfigFailed;
char m_szPathConfirDir[MAX_PATH_LENGTH]; char m_szPathConfirDir[MAX_PATH_LENGTH];
char m_szPathResourcesDir[MAX_PATH_LENGTH]; char m_szPathResourcesDir[MAX_PATH_LENGTH];
}; };
extern CConfig Config; extern CConfig Config;
extern void UTIL_Printf(char *fmt, ...);

View File

@ -2,10 +2,12 @@
DLL_FUNCTIONS *g_pFunctionTable; DLL_FUNCTIONS *g_pFunctionTable;
extern qboolean ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]); extern qboolean ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]);
extern void ServerDeactivate_Post();
extern void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax); extern void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax);
extern void ClientPutInServer_Post(edict_t *pEntity);
static DLL_FUNCTIONS gFunctionTable_Post = static DLL_FUNCTIONS gFunctionTable =
{ {
NULL, // pfnGameInit NULL, // pfnGameInit
NULL, // pfnSpawn NULL, // pfnSpawn
@ -25,13 +27,13 @@ static DLL_FUNCTIONS gFunctionTable_Post =
NULL, // pfnRestoreGlobalState NULL, // pfnRestoreGlobalState
NULL, // pfnResetGlobalState NULL, // pfnResetGlobalState
&ClientConnect_Post, // pfnClientConnect NULL, // pfnClientConnect
NULL, // pfnClientDisconnect NULL, // pfnClientDisconnect
NULL, // pfnClientKill NULL, // pfnClientKill
NULL, // pfnClientPutInServer NULL, // pfnClientPutInServer
NULL, // pfnClientCommand NULL, // pfnClientCommand
NULL, // pfnClientUserInfoChanged NULL, // pfnClientUserInfoChanged
ServerActivate_Post, // pfnServerActivate NULL, // pfnServerActivate
NULL, // pfnServerDeactivate NULL, // pfnServerDeactivate
NULL, // pfnPlayerPreThink NULL, // pfnPlayerPreThink
@ -69,6 +71,92 @@ static DLL_FUNCTIONS gFunctionTable_Post =
NULL, // pfnAllowLagCompensation NULL, // pfnAllowLagCompensation
}; };
static DLL_FUNCTIONS gFunctionTable_Post =
{
NULL, // pfnGameInit
NULL, // pfnSpawn
NULL, // pfnThink
NULL, // pfnUse
NULL, // pfnTouch
NULL, // pfnBlocked
NULL, // pfnKeyValue
NULL, // pfnSave
NULL, // pfnRestore
NULL, // pfnSetAbsBox
NULL, // pfnSaveWriteFields
NULL, // pfnSaveReadFields
NULL, // pfnSaveGlobalState
NULL, // pfnRestoreGlobalState
NULL, // pfnResetGlobalState
&ClientConnect_Post, // pfnClientConnect
NULL, // pfnClientDisconnect
NULL, // pfnClientKill
&ClientPutInServer_Post, // pfnClientPutInServer
NULL, // pfnClientCommand
NULL, // pfnClientUserInfoChanged
&ServerActivate_Post, // pfnServerActivate
&ServerDeactivate_Post, // pfnServerDeactivate
NULL, // pfnPlayerPreThink
NULL, // pfnPlayerPostThink
NULL, // pfnStartFrame
NULL, // pfnParmsNewLevel
NULL, // pfnParmsChangeLevel
NULL, // pfnGetGameDescription
NULL, // pfnPlayerCustomization
NULL, // pfnSpectatorConnect
NULL, // pfnSpectatorDisconnect
NULL, // pfnSpectatorThink
NULL, // pfnSys_Error
NULL, // pfnPM_Move
NULL, // pfnPM_Init
NULL, // pfnPM_FindTextureType
NULL, // pfnSetupVisibility
NULL, // pfnUpdateClientData
NULL, // pfnAddToFullPack
NULL, // pfnCreateBaseline
NULL, // pfnRegisterEncoders
NULL, // pfnGetWeaponData
NULL, // pfnCmdStart
NULL, // pfnCmdEnd
NULL, // pfnConnectionlessPacket
NULL, // pfnGetHullBounds
NULL, // pfnCreateInstancedBaselines
NULL, // pfnInconsistentFile
NULL, // pfnAllowLagCompensation
};
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
if (!pFunctionTable)
{
ALERT(at_logged, __FUNCTION__ " called with null pFunctionTable");
return FALSE;
}
else if (*interfaceVersion != INTERFACE_VERSION)
{
ALERT(at_logged, __FUNCTION__ " version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
//! Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = INTERFACE_VERSION;
return FALSE;
}
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
g_pFunctionTable = pFunctionTable;
return TRUE;
}
C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{ {
if (!pFunctionTable) if (!pFunctionTable)
@ -90,4 +178,3 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
return TRUE; return TRUE;
} }

View File

@ -3,8 +3,8 @@
IRehldsApi *g_RehldsApi; IRehldsApi *g_RehldsApi;
const RehldsFuncs_t *g_RehldsFuncs; const RehldsFuncs_t *g_RehldsFuncs;
IRehldsHookchains *g_RehldsHookchains; IRehldsHookchains *g_RehldsHookchains;
IRehldsServer *g_RehldsSv;
IRehldsServerStatic *g_RehldsSvs; IRehldsServerStatic *g_RehldsSvs;
IRehldsServerData *g_RehldsServerData;
rehlds_ret RehldsApi_Init() rehlds_ret RehldsApi_Init()
{ {
@ -26,7 +26,7 @@ rehlds_ret RehldsApi_Init()
if (!g_RehldsApi) if (!g_RehldsApi)
{ {
UTIL_LogPrintf(__FUNCTION__ " : REHLDS can't find Interface API"); UTIL_LogPrintf(__FUNCTION__ " : REHLDS can't find Interface API\n");
return RETURN_NOT_FOUND; return RETURN_NOT_FOUND;
} }
@ -35,20 +35,20 @@ rehlds_ret RehldsApi_Init()
if (majorVersion != REHLDS_API_VERSION_MAJOR) if (majorVersion != REHLDS_API_VERSION_MAJOR)
{ {
UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api major version mismatch; expected %d, real %d", REHLDS_API_VERSION_MAJOR, majorVersion); UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api major version mismatch; expected %d, real %d\n", REHLDS_API_VERSION_MAJOR, majorVersion);
return RETURN_MAJOR_MISMATCH; return RETURN_MAJOR_MISMATCH;
} }
if (minorVersion < REHLDS_API_VERSION_MINOR) if (minorVersion < REHLDS_API_VERSION_MINOR)
{ {
UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api minor version mismatch; expected at least %d, real %d", REHLDS_API_VERSION_MINOR, minorVersion); UTIL_LogPrintf(__FUNCTION__ " : REHLDS Api minor version mismatch; expected at least %d, real %d\n", REHLDS_API_VERSION_MINOR, minorVersion);
return RETURN_MINOR_MISMATCH; return RETURN_MINOR_MISMATCH;
} }
g_RehldsFuncs = g_RehldsApi->GetFuncs(); g_RehldsFuncs = g_RehldsApi->GetFuncs();
g_RehldsHookchains = g_RehldsApi->GetHookchains(); g_RehldsHookchains = g_RehldsApi->GetHookchains();
g_RehldsSvs = g_RehldsApi->GetServerStatic(); g_RehldsSvs = g_RehldsApi->GetServerStatic();
g_RehldsSv = g_RehldsApi->GetServer(); g_RehldsServerData = g_RehldsApi->GetServerData();
return RETURN_LOAD; return RETURN_LOAD;
} }

View File

@ -1,16 +1,16 @@
#pragma once #pragma once
typedef enum enum rehlds_ret
{ {
RETURN_LOAD, RETURN_LOAD,
RETURN_MINOR_MISMATCH, RETURN_MINOR_MISMATCH,
RETURN_MAJOR_MISMATCH, RETURN_MAJOR_MISMATCH,
RETURN_NOT_FOUND, RETURN_NOT_FOUND,
} rehlds_ret; };
extern IRehldsApi *g_RehldsApi; extern IRehldsApi *g_RehldsApi;
extern IRehldsServer *g_RehldsSv;
extern IRehldsServerStatic *g_RehldsSvs; extern IRehldsServerStatic *g_RehldsSvs;
extern IRehldsServerData *g_RehldsServerData;
extern rehlds_ret RehldsApi_Init(); extern rehlds_ret RehldsApi_Init();

View File

@ -1,106 +1,88 @@
#include "precompiled.h" #include "precompiled.h"
cvar_t *mp_consistency = NULL;
bool g_bInitialized = false; bool g_bInitialized = false;
bool SV_CheckConsistencyResponce(IRehldsHook_SV_CheckConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash);
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
void SV_GenericFileConsistencyResponce(IRehldsHook_GenericFileConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash); bool OnMetaAttach(void)
{
if (RehldsApi_Init() != RETURN_LOAD) {
return false;
}
// register function from ReHLDS API
g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponce()->registerHook(&SV_CheckConsistencyResponce);
SV_AddResource = reinterpret_cast<void (*)(resourcetype_t, const char *, int, unsigned char, int)>(g_RehldsApi->GetFuncs()->SV_AddResource);
// initialize config
Config.Init();
// if is OK go to attach
return Config.IsConfigLoaded();
}
void OnMetaDetach(void) void OnMetaDetach(void)
{ {
g_RehldsApi->GetHookchains()->GenericFileConsistencyResponce()->unregisterHook(&SV_GenericFileConsistencyResponce); g_RehldsApi->GetHookchains()->SV_CheckConsistencyResponce()->unregisterHook(&SV_CheckConsistencyResponce);
// clear
CmdExec.Clear();
Config.ClearResources();
}
void ServerDeactivate_Post()
{
if (g_bInitialized) {
// clear
CmdExec.Clear();
Config.ClearResources();
g_bInitialized = false;
}
SET_META_RESULT(MRES_IGNORED);
} }
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
{ {
g_bInitialized = false; Config.Load();
SET_META_RESULT(MRES_IGNORED); SET_META_RESULT(MRES_IGNORED);
} }
qboolean ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]) void ClientPutInServer_Post(edict_t *pEntity)
{ {
if (g_bInitialized) int nIndex = ENTINDEX(pEntity) - 1;
{
SET_META_RESULT(MRES_IGNORED); if (nIndex < 0 || nIndex >= gpGlobals->maxClients) {
return META_RESULT_ORIG_RET(qboolean); RETURN_META(MRES_IGNORED);
} }
g_bInitialized = true; IGameClient *pClient = g_RehldsApi->GetServerStatic()->GetClient(nIndex);
resource_t *resource = g_RehldsSv->GetResourceList();
int iNumResources = g_RehldsSv->GetNumResources(); if (pClient != NULL) {
int iNumConsistency = g_RehldsSv->GetNumConsistency(); // client is connected to putinserver, go execute cmd out buffer
CmdExec.Exec(pClient);
}
if (iNumResources < 1280) SET_META_RESULT(MRES_IGNORED);
{ }
ResourceCheckerVectorIt it = Config.GetVector()->begin();
while (it != Config.GetVector()->end())
{
strncpy(resource[iNumResources].szFileName, (*it)->m_FileName, 63);
resource[iNumResources].szFileName[63] = '\0';
resource[iNumResources].type = t_decal; qboolean ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128])
resource[iNumResources].nDownloadSize = 0; {
resource[iNumResources].nIndex = 4095; if (!g_bInitialized) {
resource[iNumResources].ucFlags = RES_CHECKFILE; Config.AddResource();
g_bInitialized = true;
iNumResources++;
iNumConsistency++;
g_RehldsSv->SetNumResources(iNumResources);
g_RehldsSv->SetNumConsistency(iNumConsistency);
++it;
}
} }
SET_META_RESULT(MRES_IGNORED); SET_META_RESULT(MRES_IGNORED);
return META_RESULT_ORIG_RET(qboolean); return META_RESULT_ORIG_RET(qboolean);
} }
void SV_GenericFileConsistencyResponce(IRehldsHook_GenericFileConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash) bool SV_CheckConsistencyResponce(IRehldsHook_SV_CheckConsistencyResponce *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash)
{ {
if (resource->type != t_decal) if (resource->type == t_decal) {
{ if (!Config.FileConsistencyResponce(pSenderClient, resource, hash))
chain->callNext(pSenderClient, resource, hash); return false;
return;
} }
*(uint32 *)&resource->rgucMD5_hash[0] = hash; return chain->callNext(pSenderClient, resource, hash);;
int i = 0;
for (ResourceCheckerVectorIt it = Config.GetVector()->begin(); it != Config.GetVector()->end(); ++it, i++)
{
CResourceCheckerNew *pnew = (*it);
if (strcmp(resource->szFileName, pnew->m_FileName) == 0)// && pnew->m_HashFile == hash)
{
#ifdef _DEBUG
printf("filename: %s (%s) | hash: %x | response hash: %x\n", resource->szFileName, pnew->m_FileName, pnew->m_HashFile, hash);
#endif // _DEBUG
break;
}
}
}
bool OnMetaAttach(void)
{
if (RehldsApi_Init() != RETURN_LOAD)
return false;
cvar_t *oldCvar = g_engfuncs.pfnCVarGetPointer("mp_consistency");
cvar_t newCvar = { "mp_consistency", oldCvar->string, oldCvar->flags, oldCvar->value, NULL };
oldCvar->name = "_mp_consistency";
g_engfuncs.pfnCVarRegister(&newCvar);
g_engfuncs.pfnCvar_DirectSet(oldCvar, "1");
mp_consistency = g_engfuncs.pfnCVarGetPointer("mp_consistency");
// register function from ReHLDS API
g_RehldsApi->GetHookchains()->GenericFileConsistencyResponce()->registerHook(&SV_GenericFileConsistencyResponce);
// initialize config
Config.Init();
return true;
} }

View File

@ -1 +1,3 @@
#pragma once #pragma once
extern void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);

View File

@ -9,8 +9,8 @@ plugin_info_t Plugin_info =
"s1lent", "s1lent",
"http://www.dedicated-server.ru/", "http://www.dedicated-server.ru/",
"ReChecker", "ReChecker",
PT_ANYTIME, PT_STARTUP,
PT_ANYTIME, PT_NEVER,
}; };
meta_globals_t *gpMetaGlobals; meta_globals_t *gpMetaGlobals;
@ -42,8 +42,10 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now,META_FUNCTIONS *pFunctionTable,met
{ {
return 0; return 0;
} }
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post; gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS)); memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
return 1; return 1;

View File

@ -1,5 +1,11 @@
#pragma once #pragma once
#ifdef _WIN32 // WINDOWS
#pragma warning(disable : 4005)
#endif // _WIN32
#include <cstring> // strrchr
#include <extdll.h> #include <extdll.h>
#include <enginecallback.h> // ALERT() #include <enginecallback.h> // ALERT()
@ -11,6 +17,7 @@
#include "main.h" #include "main.h"
#include "config.h" #include "config.h"
#include "cmdexec.h"
#include "sdk_util.h" // UTIL_LogPrintf, etc #include "sdk_util.h" // UTIL_LogPrintf, etc
/* <7508> ../engine/consistency.h:9 */ /* <7508> ../engine/consistency.h:9 */

View File

@ -1,5 +1,18 @@
#include "precompiled.h" #include "precompiled.h"
void UTIL_Printf(char *fmt, ...)
{
va_list argptr;
static char string[1024];
va_start(argptr, fmt);
vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr);
// Print to server console
SERVER_PRINT(string);
}
void UTIL_LogPrintf(char *fmt, ...) void UTIL_LogPrintf(char *fmt, ...)
{ {
va_list argptr; va_list argptr;
@ -9,7 +22,7 @@ void UTIL_LogPrintf(char *fmt, ...)
vsnprintf(string, sizeof(string), fmt, argptr); vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr); va_end(argptr);
// Print to server console // Print to log
ALERT(at_logged, "%s", string); ALERT(at_logged, "%s", string);
} }
@ -19,7 +32,7 @@ char *UTIL_VarArgs(char *format, ...)
static char string[1024]; static char string[1024];
va_start(argptr, format); va_start(argptr, format);
vsprintf(string, format, argptr); vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr); va_end(argptr);
return string; return string;