From 07c95aac2486c8deb25ffe735ee722f1dd19f4de Mon Sep 17 00:00:00 2001 From: s1lentq Date: Mon, 9 Nov 2020 02:03:56 +0700 Subject: [PATCH] Implemented CMakeLists.txt Get rid of fake mp_consistency and do it right via ReHLDS API --- .gitignore | 1 + CMakeLists.txt | 90 ++++++++++++++++++++++++++++++++++ Makefile | 47 ------------------ common/ObjectList.h | 18 +++---- common/cvardef.h | 19 +++++-- compile.sh | 7 +++ dist/resources.ini | 1 + engine/pr_dlls.h | 51 +++++++++++++++++++ engine/rehlds_api.h | 84 ++++++++++++++++++++++++++++++- engine/rehlds_interfaces.h | 5 ++ metamod/log_meta.h | 14 +++--- metamod/osdep.h | 6 +-- metamod/plinfo.h | 14 +++--- msvc/rechecker.vcxproj | 3 ++ msvc/rechecker.vcxproj.filters | 4 ++ src/bswap.h | 31 ++++++++++++ src/cmdexec.cpp | 5 +- src/main.cpp | 81 ++++-------------------------- src/main.h | 2 + src/meta_api.cpp | 2 +- src/resource.cpp | 18 ++++--- src/resource.h | 10 ++-- version_script.lds | 9 ++++ 23 files changed, 356 insertions(+), 166 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 Makefile create mode 100644 compile.sh create mode 100644 engine/pr_dlls.h create mode 100644 src/bswap.h create mode 100644 version_script.lds diff --git a/.gitignore b/.gitignore index aee68f6..442fdeb 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ **/PublishPath*.txt **/Server*.bat **/publish* +**/build* **/*.log diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..933ce01 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 3.1) +project(rechecker CXX) + +option(DEBUG "Build debug application." OFF) +option(USE_INTEL_COMPILER "Use the Intel compiler." OFF) +option(USE_CLANG_COMPILER "Use the Clang compiler." OFF) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if (USE_INTEL_COMPILER) + set(CMAKE_C_COMPILER "/opt/intel/bin/icc") + set(CMAKE_CXX_COMPILER "/opt/intel/bin/icpc") +elseif (USE_CLANG_COMPILER) + set(CMAKE_C_COMPILER "/usr/bin/clang") + set(CMAKE_CXX_COMPILER "/usr/bin/clang++") +endif() + +if (USE_INTEL_COMPILER OR USE_CLANG_COMPILER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fasm-blocks") +endif() + +if (DEBUG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g3 -ggdb -O3 -Wall -ffunction-sections -fdata-sections") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g0 -O3 -fvisibility=hidden -fvisibility-inlines-hidden -fno-rtti -ffunction-sections -fdata-sections") +endif() + +if (USE_INTEL_COMPILER) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel -no-intel-extensions") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-invalid-offsetof") + + if (USE_CLANG_COMPILER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedef -Wno-unused-private-field") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs -Wno-sign-compare -Wno-strict-aliasing -Wno-unused-but-set-variable") + endif() +endif() + +if (NOT DEBUG) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s -Wl,--version-script=${PROJECT_SOURCE_DIR}/version_script.lds") +endif() + +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ldl -static-libgcc -static-libstdc++ -Wl,-gc-sections") + +set(PROJECT_SRC_DIR + "${PROJECT_SOURCE_DIR}/" + "${PROJECT_SOURCE_DIR}/src" +) + +set(PROJECT_PUBLIC_DIR + "${PROJECT_SOURCE_DIR}/public" + "${PROJECT_SOURCE_DIR}/dlls" + "${PROJECT_SOURCE_DIR}/engine" + "${PROJECT_SOURCE_DIR}/common" + "${PROJECT_SOURCE_DIR}/pm_shared" + "${PROJECT_SOURCE_DIR}/metamod" +) + +set(RECHECKER_SRCS + "src/main.cpp" + "src/meta_api.cpp" + "src/dllapi.cpp" + "src/cmdexec.cpp" + "src/engine_rehlds.cpp" + "src/h_export.cpp" + "src/resource.cpp" + "src/sdk_util.cpp" + "src/hookchains_impl.cpp" + "src/rechecker_api_impl.cpp" + "public/interface.cpp" +) + +include_directories( + ${PROJECT_SRC_DIR} + ${PROJECT_PUBLIC_DIR} +) + +add_definitions( + -DNDEBUG + -Dlinux + -D__linux__ + -D_vsnprintf=vsnprintf + -D_mkdir=mkdir + -D_stricmp=strcasecmp +) + +add_library(rechecker_mm_i386 SHARED ${RECHECKER_SRCS}) +set_target_properties(rechecker_mm_i386 PROPERTIES PREFIX "" COMPILE_FLAGS "-m32" LINK_FLAGS "-m32" POSITION_INDEPENDENT_CODE ON) diff --git a/Makefile b/Makefile deleted file mode 100644 index 925dec7..0000000 --- a/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -NAME = rechecker -COMPILER = /opt/intel/bin/icpc -BIN_SUFFIX = i386 - -OBJECTS = src/main.cpp src/meta_api.cpp src/dllapi.cpp src/cmdexec.cpp \ - src/engine_rehlds.cpp src/h_export.cpp src/resource.cpp \ - src/sdk_util.cpp src/hookchains_impl.cpp src/rechecker_api_impl.cpp public/interface.cpp - -LINK = -lm -ldl -static-intel -static-libgcc -no-intel-extensions -fno-exceptions -OPT_FLAGS = -m32 -O3 -msse3 -fPIC -ipo -no-prec-div -fp-model fast=2 -funroll-loops -fomit-frame-pointer -fno-stack-protector - -INCLUDE = -I. -Isrc -Icommon -Idlls -Iengine -Ipm_shared -Ipublic -Imetamod - -BIN_DIR = Release -CFLAGS = $(OPT_FLAGS) - -CFLAGS += -g0 -fvisibility=hidden -DNOMINMAX -fvisibility-inlines-hidden\ - -DNDEBUG -Dlinux -D__linux__ -std=c++11 -shared -wd147,274 -fasm-blocks\ - -Qoption,cpp,--treat_func_as_string_literal_cpp -fno-rtti\ - -D_byteswap_ulong=_bswap -D_vsnprintf=vsnprintf -D_mkdir=mkdir -D_stricmp=strcasecmp - -OBJ_LINUX := $(OBJECTS:%.c=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.c - $(COMPILER) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - mkdir -p $(BIN_DIR)/sdk - - $(MAKE) $(NAME) && strip -x $(BIN_DIR)/$(NAME)_mm_$(BIN_SUFFIX).so - -$(NAME): $(OBJ_LINUX) - $(COMPILER) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -o$(BIN_DIR)/$(NAME)_mm_$(BIN_SUFFIX).so - -check: - cppcheck $(INCLUDE) --quiet --max-configs=100 -D__linux__ -DNDEBUG -DHAVE_STDINT_H . - -debug: - $(MAKE) all DEBUG=false - -default: all - -clean: - rm -rf Release/sdk/*.o - rm -rf Release/*.o - rm -rf Release/$(NAME)_mm_$(BIN_SUFFIX).so diff --git a/common/ObjectList.h b/common/ObjectList.h index d351ac3..aa023f8 100644 --- a/common/ObjectList.h +++ b/common/ObjectList.h @@ -32,24 +32,24 @@ class ObjectList: public IObjectContainer { public: - void Init(); - bool Add(void *newObject); - void *GetFirst(); - void *GetNext(); + EXT_FUNC void Init(); + EXT_FUNC bool Add(void *newObject); + EXT_FUNC void *GetFirst(); + EXT_FUNC void *GetNext(); ObjectList(); virtual ~ObjectList(); - void Clear(bool freeElementsMemory = false); - int CountElements(); + EXT_FUNC void Clear(bool freeElementsMemory = false); + EXT_FUNC int CountElements(); void *RemoveTail(); void *RemoveHead(); bool AddTail(void *newObject); bool AddHead(void *newObject); - bool Remove(void *object); - bool Contains(void *object); - bool IsEmpty(); + EXT_FUNC bool Remove(void *object); + EXT_FUNC bool Contains(void *object); + EXT_FUNC bool IsEmpty(); typedef struct element_s { struct element_s *prev; // pointer to the last element or NULL diff --git a/common/cvardef.h b/common/cvardef.h index cc3a222..1fa225a 100644 --- a/common/cvardef.h +++ b/common/cvardef.h @@ -1,9 +1,9 @@ /*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* +* 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 @@ -30,10 +30,21 @@ typedef struct cvar_s { const char *name; - char *string; + const char *string; int flags; float value; struct cvar_s *next; } cvar_t; +using cvar_callback_t = void (*)(const char *pszNewValue); + +struct cvar_listener_t +{ + cvar_listener_t(const char *var_name, cvar_callback_t handler) : + func(handler), name(var_name) {} + + cvar_callback_t func; + const char *name; +}; + #endif // CVARDEF_H diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..c75a2ee --- /dev/null +++ b/compile.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm -rf build +mkdir build +cd build +cmake ../ $* +make diff --git a/dist/resources.ini b/dist/resources.ini index 534fdd1..7d9b901 100644 --- a/dist/resources.ini +++ b/dist/resources.ini @@ -3,6 +3,7 @@ # -> Template keys from CMD exec # [name] - nickname client # [ip] - IP address client +# [id] - Index client # [userid] - userid client # [steamid] - SteamID client # diff --git a/engine/pr_dlls.h b/engine/pr_dlls.h new file mode 100644 index 0000000..d7b72c1 --- /dev/null +++ b/engine/pr_dlls.h @@ -0,0 +1,51 @@ +/* +* +* 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 + +#include "maintypes.h" +#include "eiface.h" + +const int MAX_EXTENSION_DLL = 50; + +typedef struct functiontable_s +{ + uint32 pFunction; + char *pFunctionName; +} functiontable_t; + +typedef struct extensiondll_s +{ + void *lDLLHandle; + functiontable_t *functionTable; + int functionCount; +} extensiondll_t; + +typedef void(*ENTITYINIT)(struct entvars_s *); +typedef void(*DISPATCHFUNCTION)(struct entvars_s *, void *); +typedef void(*FIELDIOFUNCTION)(SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int); diff --git a/engine/rehlds_api.h b/engine/rehlds_api.h index f0c1559..3d717cc 100644 --- a/engine/rehlds_api.h +++ b/engine/rehlds_api.h @@ -26,6 +26,7 @@ * */ #pragma once + #include "archtypes.h" #include "cmd_rehlds.h" #include "rehlds_interfaces.h" @@ -33,9 +34,11 @@ #include "FlightRecorder.h" #include "interface.h" #include "model.h" +#include "ObjectList.h" +#include "pr_dlls.h" #define REHLDS_API_VERSION_MAJOR 3 -#define REHLDS_API_VERSION_MINOR 0 +#define REHLDS_API_VERSION_MINOR 8 //Steam_NotifyClientConnect hook typedef IHookChain IRehldsHook_Steam_NotifyClientConnect; @@ -189,6 +192,22 @@ typedef IHookChainRegistry IRehldsHook_SV_EmitSound2; typedef IHookChainRegistry IRehldsHookRegistry_SV_EmitSound2; +//CreateFakeClient hook +typedef IHookChain IRehldsHook_CreateFakeClient; +typedef IHookChainRegistry IRehldsHookRegistry_CreateFakeClient; + +//SV_CheckConnectionLessRateLimits +typedef IHookChain IRehldsHook_SV_CheckConnectionLessRateLimits; +typedef IHookChainRegistry IRehldsHookRegistry_SV_CheckConnectionLessRateLimits; + +//SV_Frame hook +typedef IVoidHookChain<> IRehldsHook_SV_Frame; +typedef IVoidHookChainRegistry<> IRehldsHookRegistry_SV_Frame; + +//SV_ShouldSendConsistencyList hook +typedef IHookChain IRehldsHook_SV_ShouldSendConsistencyList; +typedef IHookChainRegistry IRehldsHookRegistry_SV_ShouldSendConsistencyList; + class IRehldsHookchains { public: virtual ~IRehldsHookchains() { } @@ -231,6 +250,10 @@ public: virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f() = 0; virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities() = 0; virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2() = 0; + virtual IRehldsHookRegistry_CreateFakeClient* CreateFakeClient() = 0; + virtual IRehldsHookRegistry_SV_CheckConnectionLessRateLimits* SV_CheckConnectionLessRateLimits() = 0; + virtual IRehldsHookRegistry_SV_Frame* SV_Frame() = 0; + virtual IRehldsHookRegistry_SV_ShouldSendConsistencyList* SV_ShouldSendConsistencyList() = 0; }; struct RehldsFuncs_t { @@ -282,6 +305,65 @@ struct RehldsFuncs_t { bool(*SV_EmitSound2)(edict_t *entity, IGameClient *receiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin); void(*SV_UpdateUserInfo)(IGameClient *pGameClient); bool(*StripUnprintableAndSpace)(char *pch); + void(*Cmd_RemoveCmd)(const char *cmd_name); + void(*GetCommandMatches)(const char *string, ObjectList *pMatchList); + bool(*AddExtDll)(void *hModule); + void(*AddCvarListener)(const char *var_name, cvar_callback_t func); + void(*RemoveExtDll)(void *hModule); + void(*RemoveCvarListener)(const char *var_name, cvar_callback_t func); + ENTITYINIT(*GetEntityInit)(char *pszClassName); + + // Read functions + int(*MSG_ReadChar)(); + int(*MSG_ReadByte)(); + int(*MSG_ReadLong)(); + float(*MSG_ReadFloat)(); + char*(*MSG_ReadString)(); + char*(*MSG_ReadStringLine)(); + float(*MSG_ReadAngle)(); + float(*MSG_ReadHiresAngle)(); + void(*MSG_ReadUsercmd)(struct usercmd_s *to, struct usercmd_s *from); + float(*MSG_ReadCoord)(); + void(*MSG_ReadVec3Coord)(sizebuf_t *sb, vec3_t fa); + + // Read bit functions + bool(*MSG_IsBitReading)(); + void(*MSG_StartBitReading)(sizebuf_t *buf); + void(*MSG_EndBitReading)(sizebuf_t *buf); + uint32(*MSG_PeekBits)(int numbits); + int(*MSG_ReadOneBit)(); + uint32(*MSG_ReadBits)(int numbits); + int(*MSG_ReadSBits)(int numbits); + float(*MSG_ReadBitCoord)(); + void(*MSG_ReadBitVec3Coord)(vec_t *fa); + float(*MSG_ReadBitAngle)(int numbits); + int(*MSG_ReadBitData)(void *dest, int length); + char*(*MSG_ReadBitString)(); + int(*MSG_CurrentBit)(); + + // Write functions + void(*MSG_WriteLong)(sizebuf_t *sb, int c); + void(*MSG_WriteFloat)(sizebuf_t *sb, float f); + void(*MSG_WriteAngle)(sizebuf_t *sb, float f); + void(*MSG_WriteHiresAngle)(sizebuf_t *sb, float f); + void(*MSG_WriteUsercmd)(sizebuf_t *sb, struct usercmd_s *to, struct usercmd_s *from); + void(*MSG_WriteCoord)(sizebuf_t *sb, float f); + void(*MSG_WriteVec3Coord)(sizebuf_t *sb, const vec3_t fa); + + // Write bit functions + bool(*MSG_IsBitWriting)(); + void(*MSG_WriteOneBit)(int nValue); + void(*MSG_WriteSBits)(uint32 data, int numbits); + void(*MSG_WriteBitCoord)(float f); + void(*MSG_WriteBitAngle)(float fAngle, int numbits); + void(*MSG_WriteBitData)(void *src, int length); + void(*MSG_WriteBitString)(const char *p); + void(*SZ_Write)(sizebuf_t *buf, const void *data, int length); + void(*SZ_Print)(sizebuf_t *buf, const char *data); + void(*SZ_Clear)(sizebuf_t *buf); + void(*MSG_BeginReading)(); + double(*GetHostFrameTime)(); + struct cmd_function_s *(*GetFirstCmdFunctionHandle)(); }; class IRehldsApi { diff --git a/engine/rehlds_interfaces.h b/engine/rehlds_interfaces.h index e2b909f..bfea10c 100644 --- a/engine/rehlds_interfaces.h +++ b/engine/rehlds_interfaces.h @@ -73,6 +73,9 @@ public: virtual bool GetLoopback() = 0; virtual struct usercmd_s *GetLastCmd() = 0; + virtual bool IsProxy() = 0; + virtual void SetProxy(bool proxy) = 0; + // this must be the last virtual function in class #ifdef REHLDS_SELF virtual client_t* GetClient() = 0; @@ -104,6 +107,7 @@ public: virtual IGameClient* GetClient(int id) = 0; virtual client_t* GetClient_t(int id) = 0; virtual int GetIndexOfClient_t(client_t* client) = 0; + virtual int GetMaxClientsLimit() = 0; }; class IRehldsServerData { @@ -129,4 +133,5 @@ public: virtual void SetName(const char* name) = 0; virtual class ISteamGameServer *GetSteamGameServer() = 0; virtual struct netadr_s *GetNetFrom() = 0; + virtual double GetOldTime() = 0; }; diff --git a/metamod/log_meta.h b/metamod/log_meta.h index ec47c6d..99cf7fe 100644 --- a/metamod/log_meta.h +++ b/metamod/log_meta.h @@ -86,13 +86,13 @@ extern cvar_t meta_debug; // server.cfg. // NOTE: META_DEV has now been mostly obsoleted in the code. -void META_CONS(char *fmt, ...); -void META_DEV(char *fmt, ...); -void META_INFO(char *fmt, ...); -void META_WARNING(char *fmt, ...); -void META_ERROR(char *fmt, ...); -void META_LOG(char *fmt, ...); -void META_CLIENT(edict_t *pEntity, char *fmt, ...); +void META_CONS(const char *fmt, ...); +void META_DEV(const char *fmt, ...); +void META_INFO(const char *fmt, ...); +void META_WARNING(const char *fmt, ...); +void META_ERROR(const char *fmt, ...); +void META_LOG(const char *fmt, ...); +void META_CLIENT(edict_t *pEntity, const char *fmt, ...); void flush_ALERT_buffer(void); diff --git a/metamod/osdep.h b/metamod/osdep.h index e11a8b7..c9fc002 100644 --- a/metamod/osdep.h +++ b/metamod/osdep.h @@ -133,7 +133,7 @@ extern mBOOL dlclose_handle_invalid; dlclose_handle_invalid = mFALSE; return(dlclose(handle)); } - inline char* DLERROR(void) { + inline const char* DLERROR(void) { if (dlclose_handle_invalid) return("Invalid handle."); return(dlerror()); @@ -159,8 +159,8 @@ extern mBOOL dlclose_handle_invalid; } // Windows doesn't provide a function corresponding to dlerror(), so // we make our own. - char *str_GetLastError(void); - inline char* DLERROR(void) { + const char *str_GetLastError(void); + inline const char* DLERROR(void) { if (dlclose_handle_invalid) return("Invalid handle."); return(str_GetLastError()); diff --git a/metamod/plinfo.h b/metamod/plinfo.h index 9e5b744..2ec8686 100644 --- a/metamod/plinfo.h +++ b/metamod/plinfo.h @@ -60,13 +60,13 @@ typedef enum { // Information plugin provides about itself. typedef struct { - char *ifvers; // meta_interface version - char *name; // full name of plugin - char *version; // version - char *date; // date - char *author; // author name/email - char *url; // URL - char *logtag; // log message prefix (unused right now) + const char *ifvers; // meta_interface version + const char *name; // full name of plugin + const char *version; // version + const char *date; // date + const char *author; // author name/email + const char *url; // URL + const char *logtag; // log message prefix (unused right now) PLUG_LOADTIME loadable; // when loadable PLUG_LOADTIME unloadable; // when unloadable } plugin_info_t; diff --git a/msvc/rechecker.vcxproj b/msvc/rechecker.vcxproj index 1047e49..2454b0a 100644 --- a/msvc/rechecker.vcxproj +++ b/msvc/rechecker.vcxproj @@ -37,6 +37,7 @@ + @@ -164,6 +165,7 @@ + @@ -206,6 +208,7 @@ {9A72E8DC-7667-46C1-899D-1E8B939564D2} Win32Proj rechecker + 7.0 diff --git a/msvc/rechecker.vcxproj.filters b/msvc/rechecker.vcxproj.filters index 2edb222..f8d4d34 100644 --- a/msvc/rechecker.vcxproj.filters +++ b/msvc/rechecker.vcxproj.filters @@ -468,6 +468,10 @@ public + + sdk\common + + diff --git a/src/bswap.h b/src/bswap.h new file mode 100644 index 0000000..50c181a --- /dev/null +++ b/src/bswap.h @@ -0,0 +1,31 @@ +/* +* +* 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 + +#ifdef _MSC_VER + +#include +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#else + +#include + +#endif diff --git a/src/cmdexec.cpp b/src/cmdexec.cpp index 36630c3..b7bb002 100644 --- a/src/cmdexec.cpp +++ b/src/cmdexec.cpp @@ -76,9 +76,10 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32 // 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))); + StringReplace(string, "[file_md5hash]", UTIL_VarArgs("%x", bswap_32(responseHash))); // Replace of templates for identification + StringReplace(string, "[id]", UTIL_VarArgs("%i", pClient->GetId() + 1)); 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])); @@ -135,7 +136,7 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient) char *cmdExec = GetExecCmdPrepare(pClient, pRes, pExec->GetClientHash()); if (cmdExec && cmdExec[0] != '\0') { - g_RecheckerHookchains.m_CmdExec.callChain(CmdExec_hook, pClient, pRes, cmdExec, _byteswap_ulong(pExec->GetClientHash())); + g_RecheckerHookchains.m_CmdExec.callChain(CmdExec_hook, pClient, pRes, cmdExec, bswap_32(pExec->GetClientHash())); } bBreak = pRes->IsBreak(); diff --git a/src/main.cpp b/src/main.cpp index d52600a..9423afe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,9 +18,6 @@ #include "precompiled.h" -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); @@ -35,59 +32,13 @@ bool OnMetaAttach() g_pResource->Init(); Rechecker_Api_Init(); - // If have already registered take it - cvar_t *pcv_consistency_prev = g_engfuncs.pfnCVarGetPointer("mp_consistency_"); - - if (pcv_consistency_prev) - { - pcv_consistency_old = g_engfuncs.pfnCVarGetPointer("mp_consistency"); - - const char *tempName = pcv_consistency_old->name; - pcv_consistency_old->name = pcv_consistency_prev->name; - - pcv_consistency_prev->value = pcv_consistency_old->value; - pcv_consistency_prev->string = pcv_consistency_old->string; - pcv_consistency_prev->flags = pcv_consistency_old->flags; - pcv_consistency_prev->name = tempName; - } - else - { - // 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"); - - cv_mp_consistency.value = pcv_consistency_old->value; - cv_mp_consistency.string = pcv_consistency_old->string; - cv_mp_consistency.flags = pcv_consistency_old->flags; - cv_mp_consistency.name = pcv_consistency_old->name; - - pcv_consistency_old->name = STRING(ALLOC_STRING("mp_consistency_")); - g_engfuncs.pfnCVarRegister(&cv_mp_consistency); - } - - g_engfuncs.pfnCvar_DirectSet(pcv_consistency_old, "1"); - - // To remove the old cvar of cvars list - cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars(); - for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next) - { - if (var == pcv_consistency_old) - { - if (prev) - prev->next = var->next; - else - cvar_vars = cvar_vars->next; - break; - } - } - // 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); g_RehldsHookchains->SV_Spawn_f()->registerHook(&SV_Spawn_f); g_RehldsHookchains->HandleNetCommand()->registerHook(&HandleNetCommand); + g_RehldsHookchains->SV_ShouldSendConsistencyList()->registerHook(&SV_ShouldSendConsistencyList, HC_PRIORITY_DEFAULT + 10); SV_AddResource = g_RehldsFuncs->SV_AddResource; SV_FileInConsistencyList = g_RehldsFuncs->SV_FileInConsistencyList; @@ -101,28 +52,6 @@ void OnMetaDetach() if (!g_RehldsFuncs) return; - cvar_t *pcv_mp_consistency = g_engfuncs.pfnCVarGetPointer("mp_consistency"); - - // 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 - cvar_t *cvar_vars = g_RehldsFuncs->GetCvarVars(); - for (cvar_t *var = cvar_vars, *prev = nullptr; var; prev = var, var = var->next) - { - if (var == pcv_mp_consistency) - { - if (prev) - prev->next = pcv_consistency_old; - else - cvar_vars = pcv_consistency_old; - break; - } - } - // Clear Exec.Clear(); delete g_pResource; @@ -132,6 +61,7 @@ void OnMetaDetach() g_RehldsHookchains->SV_TransferConsistencyInfo()->unregisterHook(&SV_TransferConsistencyInfo); g_RehldsHookchains->SV_Spawn_f()->unregisterHook(&SV_Spawn_f); g_RehldsHookchains->HandleNetCommand()->unregisterHook(&HandleNetCommand); + g_RehldsHookchains->SV_ShouldSendConsistencyList()->unregisterHook(&SV_ShouldSendConsistencyList); ClearQueryFiles_api(); } @@ -168,6 +98,13 @@ int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain) return chain->callNext() + nConsistency; } +bool SV_ShouldSendConsistencyList(IRehldsHook_SV_ShouldSendConsistencyList *chain, IGameClient *client, bool forceConsistency) +{ + return chain->callNext(client, + true // forcing send consistency, even if mp_consistency is disabled + ); +} + bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash) { if (!g_pResource->FileConsistencyResponse(pSenderClient, resource, hash)) diff --git a/src/main.h b/src/main.h index 1207d10..601dc23 100644 --- a/src/main.h +++ b/src/main.h @@ -19,6 +19,7 @@ #pragma once #include "consistency.h" +#include "bswap.h" void UTIL_Printf(const char *fmt, ...); void UTIL_LogPrintf(const char *fmt, ...); @@ -26,6 +27,7 @@ char *UTIL_VarArgs(const char *format, ...); void NORETURN Sys_Error(const char *error, ...); void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *pClient, bool crash, const char *string); +bool SV_ShouldSendConsistencyList(IRehldsHook_SV_ShouldSendConsistencyList *chain, IGameClient *client, bool forceConsistency); bool SV_CheckConsistencyResponse(IRehldsHook_SV_CheckConsistencyResponse *chain, IGameClient *pSenderClient, resource_t *resource, uint32 hash); int SV_TransferConsistencyInfo(IRehldsHook_SV_TransferConsistencyInfo *chain); void SV_Spawn_f(IRehldsHook_SV_Spawn_f *chain); diff --git a/src/meta_api.cpp b/src/meta_api.cpp index 8931645..7c6407c 100644 --- a/src/meta_api.cpp +++ b/src/meta_api.cpp @@ -22,7 +22,7 @@ plugin_info_t Plugin_info = { META_INTERFACE_VERSION, "Rechecker", - "2.6", + "2.7", __DATE__, "s1lent", "http://www.dedicated-server.ru/", diff --git a/src/resource.cpp b/src/resource.cpp index dbf277d..7287da9 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -21,6 +21,9 @@ CResourceFile *g_pResource = nullptr; CResourceFile::StringList CResourceFile::m_StringsCache; +const char *CResourceFile::m_TypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" }; +const char *CResourceFile::m_HeadFileName = "delta.lst"; + cvar_t cv_rch_log = { "rch_log", "0", 0, 0.0f, nullptr }; cvar_t *pcv_rch_log = nullptr; @@ -155,10 +158,10 @@ void CResourceFile::AddHeadResource() { Q_strlcpy(m_HeadResource.szFileName, m_HeadFileName); - m_HeadResource.type = t_decal; - m_HeadResource.ucFlags = RES_CHECKFILE; + m_HeadResource.type = t_decal; + m_HeadResource.ucFlags = RES_CHECKFILE; m_HeadResource.nDownloadSize = 0; - m_HeadResource.nIndex = RESOURCE_MAX_COUNT - 1; + m_HeadResource.nIndex = RESOURCE_MAX_COUNT - 1; } void CResourceFile::Clear(IGameClient *pClient) @@ -211,7 +214,7 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...) FILE *fp; time_t td; tm *lt; - char *file; + const char *file; char dateLog[64]; bool bFirst = false; @@ -219,7 +222,6 @@ void CResourceFile::Log(flag_type_log type, const char *fmt, ...) return; fp = fopen(m_LogFilePath, "r"); - if (fp) { bFirst = true; @@ -593,7 +595,7 @@ const char *CResourceFile::GetNextToken(char **pbuf) return res; } -CResourceBuffer *CResourceFile::Add(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak) +CResourceBuffer *CResourceFile::Add(const char *filename, const char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak) { auto nRes = new CResourceBuffer(filename, cmdExec, flag, hash, line, bBreak); @@ -645,7 +647,7 @@ 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, m_TypeNames[typeFind], m_PrevHash, g_engfuncs.pfnGetPlayerUserId(pSenderClient->GetEdict()), - pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), _byteswap_ulong(hash), res->IsAddEx()); + pSenderClient->GetName(), FindFilenameOfHash(m_PrevHash), FindFilenameOfHash(hash), bswap_32(hash), res->IsAddEx()); } IResourceBuffer *CResourceFile::GetResourceFile(const char *filename) @@ -802,7 +804,7 @@ void CResourceFile::ClearStringsCache() m_StringsCache.clear(); } -CResourceBuffer::CResourceBuffer(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak) +CResourceBuffer::CResourceBuffer(const char *filename, const char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak) { m_FileName = CResourceFile::DuplicateString(filename); m_CmdExec = (cmdExec[0] != '\0') ? CResourceFile::DuplicateString(cmdExec) : nullptr; diff --git a/src/resource.h b/src/resource.h index d3ef0af..c08aea5 100644 --- a/src/resource.h +++ b/src/resource.h @@ -24,7 +24,7 @@ const int MAX_RANGE_CONSISTENCY = 1024; const int RESOURCE_INDEX_BITS = 12; const int RESOURCE_MAX_COUNT = BIT(RESOURCE_INDEX_BITS); -constexpr char *FILE_INI_RESOURCES = "resources.ini"; +constexpr const char *FILE_INI_RESOURCES = "resources.ini"; enum flag_type_log { @@ -47,7 +47,7 @@ enum arg_type_e class CResourceBuffer: public IResourceBuffer { public: - CResourceBuffer(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak); + CResourceBuffer(const char *filename, const char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak); uint32 GetFileHash() const { return m_FileHash; }; ResourceType_e GetFileFlag() const { return m_Flag; }; @@ -131,8 +131,8 @@ private: typedef std::vector ResourceList; typedef std::vector ResponseList; - static constexpr char *m_TypeNames[] = { "none", "exists", "missing", "ignore", "hash_any" }; - static constexpr char *m_HeadFileName = "delta.lst"; + static const char *m_TypeNames[]; + static const char *m_HeadFileName; ResourceList m_resourceList; ResponseList m_responseList; @@ -154,7 +154,7 @@ public: const char *FindFilenameOfHash(uint32 hash); int GetConsistencyNum() const { return m_ConsistencyNum; } uint32 GetPrevHash() const { return m_PrevHash; } - CResourceBuffer *Add(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak); + CResourceBuffer *Add(const char *filename, const char *cmdExec, ResourceType_e flag, uint32 hash, int line, bool bBreak); }; extern CResourceFile *g_pResource; diff --git a/version_script.lds b/version_script.lds new file mode 100644 index 0000000..67a9e50 --- /dev/null +++ b/version_script.lds @@ -0,0 +1,9 @@ +RECHECKER_ABI_1.0 { + global: + GiveFnptrsToDll; + Meta_Attach; + Meta_Detach; + Meta_Query; + local: + *; +};