2
0
mirror of https://github.com/rehlds/reapi.git synced 2024-12-29 08:05:36 +03:00

Add support rechecker API

Minor refactoring
This commit is contained in:
s1lent 2017-09-21 23:02:39 +07:00
parent 76cddfd785
commit 61fe805a29
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
39 changed files with 899 additions and 158 deletions

4
getucrtinfo.bat Normal file
View File

@ -0,0 +1,4 @@
@echo off
call "%VS140COMNTOOLS%vcvarsqueryregistry.bat"
echo %UniversalCRTSdkDir%
echo %UCRTVersion%

View File

@ -60,7 +60,7 @@ void setupToolchain(NativeBinarySpec b) {
'_snprintf': 'snprintf'
])
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s'
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s', '-fno-exceptions'
}
ToolchainConfigUtils.apply(project, cfg, b)

View File

@ -19,7 +19,8 @@ enum hooks_tables_e
ht_gamedll,
ht_animating,
ht_player,
ht_gamerules
ht_gamerules,
ht_rechecker
};
enum members_tables_e
@ -42,7 +43,7 @@ enum members_tables_e
};
// Is like FNullEnt
#define is_nullent(%0) (%0 != 0 && is_entity(%0) == false)
#define is_nullent(%0) (%0 == 0 || is_entity(%0) == false)
#define MAX_REGION_RANGE 1024
@ -51,10 +52,14 @@ enum members_tables_e
#include <cssdk_const>
#include <reapi_version>
#include <reapi_engine> // NOTE: only for ReHLDS
#include <reapi_gamedll> // NOTE: only for gamedll Counter-Strike (ReGameDLL_CS)
#include <reapi_addons> // NOTE: 3rd party addons
#include <reapi_version>
// addons
#include <reapi_vtc>
#include <reapi_reunion>
#include <reapi_rechecker>
// hookchain return type
enum
@ -90,7 +95,7 @@ enum HookChain
* @return Returns a hook handle. Use EnableHookChain/DisableHookChain to toggle the forward on or off
*
*/
native HookChain:RegisterHookChain({EngineFunc, GamedllFunc, GamedllFunc_CBaseAnimating, GamedllFunc_CBasePlayer, GamedllFunc_CSGameRules}:function_id, const callback[], post = 0);
native HookChain:RegisterHookChain({EngineFunc, GamedllFunc, GamedllFunc_CBaseAnimating, GamedllFunc_CBasePlayer, GamedllFunc_CSGameRules, ReCheckerFunc}:function_id, const callback[], post = 0);
/*
* Stops a hook from triggering.

View File

@ -1782,7 +1782,7 @@ enum CBasePlayer_Members
m_bHighDamage,
/*
* Description: -
* Description: Slow down the player based on the velocity modifier, applies when the player takes damage.
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
@ -3983,7 +3983,7 @@ enum CCSPlayer_Members
enum CBasePlayerItem_Members
{
/*
* Description: -
* Description: ID of the owner on this item
* Member type: class CBasePlayer *
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
@ -3991,7 +3991,7 @@ enum CBasePlayerItem_Members
m_pPlayer = BEGIN_MEMBER_REGION(baseitem),
/*
* Description: -
* Description: Iterator for linked list of the entities
* Member type: class CBasePlayerItem *
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
@ -3999,7 +3999,7 @@ enum CBasePlayerItem_Members
m_pNext,
/*
* Description: -
* Description: ID of the item
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);

View File

@ -0,0 +1,60 @@
#if defined _reapi_rechecker_included
#endinput
#endif
#define _reapi_rechecker_included
enum ResourceType
{
RES_TYPE_NONE = 0,
RES_TYPE_EXISTS, // to comparison with the specified hash value
RES_TYPE_MISSING, // check it missing file on client
RES_TYPE_IGNORE, // ignore the specified hash value
RES_TYPE_HASH_ANY, // any file with any the hash value
};
enum ReCheckerFunc
{
/*
* Description: -
* Params: (const client, const filename[], const cmd[], const ResourceType:type, const responseHash, bool:isBreak)
*/
RC_FileConsistencyProcess = BEGIN_FUNC_REGION(rechecker),
/*
* Description: -
* Params: (const client)
*/
RC_FileConsistencyFinal,
/*
* Description: -
* Params: (const client, const filename[], const cmd[], const responseHash)
*/
RC_CmdExec,
// [...]
};
/*
* Send request the file for the client to get hash
*
* @param file The file (Can contain a relative path to the file)
* @param function The forward to call
* @param type The request type, can be only RES_TYPE_EXISTS, RES_TYPE_MISSING or RES_TYPE_HASH_ANY
* @param hash Hash of file to request.
*
* @return Returns a hook handle. Use UnRegisterQueryFile to remove the forward
*
*/
native QueryFileHook:RegisterQueryFile(const file[], const function[], const ResourceType:type, const hash = -1);
/*
* Unregister the forward.
* Use the return value from RegisterQueryFile as the parameter here!
*
* @param hook The hook to remove
*
* @return Returns true if the hook is successfully removed, otherwise false
*
*/
native bool:UnRegisterQueryFile(QueryFileHook:hook);

View File

@ -0,0 +1,45 @@
#if defined _reapi_reunion_included
#endinput
#endif
#define _reapi_reunion_included
enum client_auth_type
{
CA_TYPE_NONE = 0,
CA_TYPE_DPROTO,
CA_TYPE_STEAM,
CA_TYPE_STEAMEMU,
CA_TYPE_REVEMU,
CA_TYPE_OLDREVEMU,
CA_TYPE_HLTV,
CA_TYPE_SC2009,
CA_TYPE_AVSMP,
CA_TYPE_SXEI,
CA_TYPE_REVEMU2013,
CA_TYPE_SSE3,
};
/*
* Gets client protocol.
*
* @param index Client index
* @return Client protocol
*/
native REU_GetProtocol(const index);
/*
* Gets client auth type.
*
* @param index Client index
* @return Client auth type
*/
native client_auth_type:REU_GetAuthtype(const index);
/*
* Check if the client is running RevEmu with limited user rights.
*
* @param index Client index
* @return 1/0
*
*/
native bool:REU_IsRevemuWithoutAdminRights(const index);

View File

@ -0,0 +1,68 @@
#if defined _reapi_vtc_included
#endinput
#endif
#define _reapi_vtc_included
/*
* Checks whether the player is talking at the moment.
*
* @param index Client index
* @return true if client is speaking, false otherwise
*
*/
native bool:VTC_IsClientSpeaking(const index);
/*
* Mutes the player.
*
* @param index Client index
* @noreturn
*/
native VTC_MuteClient(const index);
/*
* Unmutes the player.
*
* @param index Client index
* @noreturn
*/
native VTC_UnmuteClient(const index);
/*
* Checks whether the player is muted at the moment.
*
* @param index Client index
* @return true if client is muted, false otherwise
*
*/
native bool:VTC_IsClientMuted(const index);
/*
* Play the audio file via the voice stream.
*
* @param receiver Receiver index
* @param soundFilePath The path to the sound file
*
* @note Usage example:
* VTC_PlaySound(id, "sound/ambience/Opera.wav");
*
* @noreturn
*
*/
native VTC_PlaySound(const receiver, const soundFilePath[]);
/*
* Called when the player started talking.
*
* @param index Client index
* @noreturn
*/
forward VTC_OnClientStartSpeak(const index);
/*
* Called when the player stopped talking.
*
* @param index Client index
* @noreturn
*/
forward VTC_OnClientStopSpeak(const index);

View File

@ -0,0 +1,132 @@
/*
*
* 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 "hookchains.h"
#include "interface.h"
#define RECHECKER_API_VERSION_MAJOR 2
#define RECHECKER_API_VERSION_MINOR 1
enum ResourceType_e
{
RES_TYPE_NONE = 0,
RES_TYPE_EXISTS, // to comparison with the specified hash value
RES_TYPE_MISSING, // check it missing file on client
RES_TYPE_IGNORE, // ignore the specified hash value
RES_TYPE_HASH_ANY, // any file with any the hash value
};
class IResourceBuffer;
// FileConsistencyProcess hook
typedef IVoidHookChain<IGameClient *, IResourceBuffer *, ResourceType_e, uint32> IRecheckerHook_FileConsistencyProcess;
typedef IVoidHookChainRegistry<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;
// FileConsistencyFinal hook
typedef IVoidHookChain<IGameClient *> IRecheckerHook_FileConsistencyFinal;
typedef IVoidHookChainRegistry<IGameClient *> IRecheckerHookRegistry_FileConsistencyFinal;
class IRecheckerHookchains {
protected:
virtual ~IRecheckerHookchains() {}
public:
virtual IRecheckerHookRegistry_FileConsistencyProcess *FileConsistencyProcess() = 0;
virtual IRecheckerHookRegistry_CmdExec *CmdExec() = 0;
virtual IRecheckerHookRegistry_FileConsistencyFinal *FileConsistencyFinal() = 0;
};
class IResourceBuffer {
protected:
virtual ~IResourceBuffer() {}
public:
virtual uint32 GetFileHash() const = 0;
virtual ResourceType_e GetFileFlag() const = 0;
virtual const char *GetFileName() const = 0;
virtual const char *GetCmdExec() const = 0;
virtual int GetLine() const = 0;
virtual bool IsBreak() const = 0; // is have do not check a next files
virtual bool IsDuplicate() const = 0; // it is already have in resourcelist
virtual bool IsAddEx() const = 0; // if it added via API
};
class IResponseBuffer {
protected:
virtual ~IResponseBuffer() {}
public:
virtual int GetUserID() const = 0;
virtual IGameClient *GetGameClient() const = 0;
virtual const char *GetFileName() const = 0;
virtual uint32 GetClientHash() const = 0;
virtual uint32 GetPrevHash() const = 0;
};
class IResourceFile {
protected:
virtual ~IResourceFile() {}
public:
virtual const char *FindFilenameOfHash(uint32 hash) = 0;
virtual int GetConsistencyNum() const = 0;
virtual uint32 GetPrevHash() const = 0;
};
#undef FindResource
using query_func_t = void (*)(IGameClient *pClient, uint32 hash, int uniqueId);
struct RecheckerFuncs_t {
IResourceBuffer *(*AddResource)(const char *filename, char *cmdExec, ResourceType_e flag, uint32 hash, bool bBreak);
IResourceBuffer *(*AddQueryFile)(const char *filename, ResourceType_e flag, uint32 hash, query_func_t callback, int uniqueId);
void (*RemoveQueryFile)(int uniqueId);
void (*ClearQueryFiles)();
IResourceBuffer *(*FindResource)(const char *filename);
IResourceFile *(*GetResource)();
IResponseBuffer *(*GetResponseFile)(IGameClient *pClient, const char *filename);
bool (*IsResourceExists)(IGameClient *pClient, const char *filename, uint32 &hash);
};
class IRecheckerApi {
protected:
virtual ~IRecheckerApi() { }
public:
virtual int GetMajorVersion() = 0;
virtual int GetMinorVersion() = 0;
virtual const RecheckerFuncs_t *GetFuncs() = 0;
virtual IRecheckerHookchains *GetHookchains() = 0;
};

View File

@ -27,6 +27,14 @@ set "hour=%dt:~8,2%"
set "min=%dt:~10,2%"
set "sec=%dt:~12,2%"
::
:: Remove leading zero from MM (e.g 09 > 9)
for /f "tokens=* delims=0" %%I in ("%MM%") do set MM=%%I
::
::
:: Index into array to get month name
::
for /f "tokens=%MM%" %%I in ("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec") do set "month=%%I"
::
@ -143,10 +151,10 @@ IF NOT %errlvl% == "1" (
)
:: append extra string
If NOT "%commitURL%"=="%commitURL:bitbucket.org=%" (
set commitURL=!commitURL!/commit/
) ELSE (
If NOT "!commitURL!"=="!commitURL:bitbucket.org=!" (
set commitURL=!commitURL!/commits/
) ELSE (
set commitURL=!commitURL!/commit/
)
) ELSE (
@ -158,10 +166,10 @@ IF NOT %errlvl% == "1" (
set commitURL=!commitURL::=/!
:: append extra string
If NOT "%commitURL%"=="%commitURL:bitbucket.org=%" (
set commitURL=https://!commitURL!/commit/
) ELSE (
If NOT "!commitURL!"=="!commitURL:bitbucket.org=!" (
set commitURL=https://!commitURL!/commits/
) ELSE (
set commitURL=https://!commitURL!/commit/
)
)
)
@ -243,7 +251,7 @@ echo #define APP_VERSION_STRD "%version_major%.%version_minor%.%version_maintena
echo #define APP_VERSION_FLAGS 0x0L>>"%srcdir%\appversion.h"
echo.>>"%srcdir%\appversion.h"
echo #define APP_COMMIT_DATE "%YYYY%-%DD%-%MM%">>"%srcdir%\appversion.h"
echo #define APP_COMMIT_DATE "%month% %DD% %YYYY%">>"%srcdir%\appversion.h"
echo #define APP_COMMIT_TIME "%hour%:%min%:%sec%">>"%srcdir%\appversion.h"
echo.>>"%srcdir%\appversion.h"

View File

@ -204,16 +204,20 @@
<ClInclude Include="..\src\hook_list.h" />
<ClInclude Include="..\src\main.h" />
<ClInclude Include="..\src\member_list.h" />
<ClInclude Include="..\src\mods\mod_rechecker_api.h" />
<ClInclude Include="..\src\mods\mod_regamedll_api.h" />
<ClInclude Include="..\src\mods\mod_rehlds_api.h" />
<ClInclude Include="..\src\mods\mod_reunion_api.h" />
<ClInclude Include="..\src\mods\mod_vtc_api.h" />
<ClInclude Include="..\src\mods\queryfile_handler.h" />
<ClInclude Include="..\src\natives\natives_common.h" />
<ClInclude Include="..\src\natives\natives_helper.h" />
<ClInclude Include="..\src\natives\natives_hookchains.h" />
<ClInclude Include="..\src\natives\natives_members.h" />
<ClInclude Include="..\src\natives\natives_misc.h" />
<ClInclude Include="..\src\natives\natives_addons.h" />
<ClInclude Include="..\src\natives\natives_rechecker.h" />
<ClInclude Include="..\src\natives\natives_reunion.h" />
<ClInclude Include="..\src\natives\natives_vtc.h" />
<ClInclude Include="..\src\precompiled.h" />
<ClInclude Include="..\src\reapi_utils.h" />
<ClInclude Include="..\src\type_conversion.h" />
@ -247,15 +251,19 @@
</ClCompile>
<ClCompile Include="..\src\main.cpp" />
<ClCompile Include="..\src\meta_api.cpp" />
<ClCompile Include="..\src\mods\mod_rechecker_api.cpp" />
<ClCompile Include="..\src\mods\mod_regamedll_api.cpp" />
<ClCompile Include="..\src\mods\mod_rehlds_api.cpp" />
<ClCompile Include="..\src\mods\mod_reunion_api.cpp" />
<ClCompile Include="..\src\mods\mod_vtc_api.cpp" />
<ClCompile Include="..\src\mods\queryfile_handler.cpp" />
<ClCompile Include="..\src\natives\natives_common.cpp" />
<ClCompile Include="..\src\natives\natives_hookchains.cpp" />
<ClCompile Include="..\src\natives\natives_members.cpp" />
<ClCompile Include="..\src\natives\natives_misc.cpp" />
<ClCompile Include="..\src\natives\natives_addons.cpp" />
<ClCompile Include="..\src\natives\natives_rechecker.cpp" />
<ClCompile Include="..\src\natives\natives_reunion.cpp" />
<ClCompile Include="..\src\natives\natives_vtc.cpp" />
<ClCompile Include="..\src\precompiled.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

View File

@ -651,9 +651,6 @@
<ClInclude Include="..\src\mods\mod_reunion_api.h">
<Filter>src\mods</Filter>
</ClInclude>
<ClInclude Include="..\src\natives\natives_addons.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\include\com_progdefs.h">
<Filter>include</Filter>
</ClInclude>
@ -669,6 +666,21 @@
<ClInclude Include="..\src\natives\natives_common.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\mods\mod_rechecker_api.h">
<Filter>src\mods</Filter>
</ClInclude>
<ClInclude Include="..\src\natives\natives_rechecker.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\natives\natives_reunion.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\natives\natives_vtc.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\mods\queryfile_handler.h">
<Filter>src\mods</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
@ -746,15 +758,27 @@
<ClCompile Include="..\src\mods\mod_reunion_api.cpp">
<Filter>src\mods</Filter>
</ClCompile>
<ClCompile Include="..\src\natives\natives_addons.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\version\version.cpp">
<Filter>version</Filter>
</ClCompile>
<ClCompile Include="..\src\natives\natives_common.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\mods\mod_rechecker_api.cpp">
<Filter>src\mods</Filter>
</ClCompile>
<ClCompile Include="..\src\natives\natives_rechecker.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\natives\natives_reunion.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\natives\natives_vtc.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\mods\queryfile_handler.cpp">
<Filter>src\mods</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\extra\amxmodx\scripting\include\reapi.inc">

View File

@ -164,7 +164,9 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
RegisterNatives_HookChains();
RegisterNatives_Members();
RegisterNatives_Misc();
RegisterNatives_Addons();
RegisterNatives_VTC();
RegisterNatives_Rechecker();
RegisterNatives_Reunion();
RegisterNatives_Common();
return AMXX_OK;

View File

@ -9,10 +9,11 @@ CAPI_Config::CAPI_Config() : m_api_rehlds(false), m_api_regame(false), m_api_vtc
void CAPI_Config::Init()
{
m_api_rehlds = RehldsApi_Init();
m_api_regame = RegamedllApi_Init();
m_api_vtc = VTC_Api_Init();
m_api_reunion = ReunionApi_Init();
m_api_rehlds = RehldsApi_Init();
m_api_regame = RegamedllApi_Init();
m_api_vtc = VTC_Api_Init();
m_api_reunion = ReunionApi_Init();
m_api_rechecker = RecheckerApi_Init();
if (m_api_regame) {
g_ReGameHookchains->InstallGameRules()->registerHook(&InstallGameRules);

View File

@ -12,6 +12,7 @@ public:
bool hasReGameDLL() const { return m_api_regame; }
bool hasVTC() const { return m_api_vtc; }
bool hasReunion() const { return m_api_reunion; }
bool hasRechecker() const { return m_api_rechecker; }
void ServerDeactivate() const;
@ -25,7 +26,7 @@ private:
bool m_api_reunion; // for information about authorization client
//bool m_api_revoice; // for gag #2
//bool m_api_rechecker; // for detection when checking and adding few files
bool m_api_rechecker; // for detection when checking and adding few files
};
extern CAPI_Config api_cfg;

View File

@ -828,3 +828,58 @@ void OnClientStopSpeak(size_t clientIndex)
{
g_amxxapi.ExecuteForward(g_iClientStopSpeak, clientIndex);
}
/*
* ReChecker functions
*/
void FileConsistencyProcess_AMXX(FileConsistencyProcess_t *data, IGameClient *cl, const char *filename, const char *cmd, ResourceType_e type, uint32 responseHash, bool isBreak)
{
int hashCopy = responseHash;
auto original = [data, hashCopy](int _cl, const char *_filename, const char *_cmd, ResourceType_e _type, uint32 _hash, bool _isBreak)
{
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_data, _type, hashCopy);
};
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
responseHash = 0;
}
callVoidForward(RC_FileConsistencyProcess, original, cl->GetId() + 1, filename, cmd, type, responseHash, isBreak);
}
void FileConsistencyProcess(IRecheckerHook_FileConsistencyProcess *chain, IGameClient *cl, IResourceBuffer *res, ResourceType_e typeFind, uint32 responseHash)
{
FileConsistencyProcess_t data(chain, res);
FileConsistencyProcess_AMXX(&data, cl, res->GetFileName(), res->GetCmdExec(), typeFind, responseHash, res->IsBreak());
}
void FileConsistencyFinal(IRecheckerHook_FileConsistencyFinal *chain, IGameClient *cl)
{
auto original = [chain](int _cl)
{
chain->callNext(g_RehldsSvs->GetClient(_cl - 1));
};
callVoidForward(RC_FileConsistencyFinal, original, cl->GetId() + 1);
}
void CmdExec_AMXX(CmdExec_t *data, IGameClient *cl, const char *filename, char *cmd, uint32 responseHash)
{
int hashCopy = responseHash;
auto original = [data, hashCopy](int _cl, const char *_filename, char *_cmd, uint32 _responseHash)
{
data->m_chain->callNext(g_RehldsSvs->GetClient(_cl - 1), data->m_data, _cmd, hashCopy);
};
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == responseHash) {
responseHash = 0;
}
callVoidForward(RC_CmdExec, original, cl->GetId() + 1, filename, cmd, responseHash);
}
void CmdExec(IRecheckerHook_CmdExec *chain, IGameClient *cl, IResourceBuffer *res, char *cmdExec, uint32 responseHash)
{
CmdExec_t data(chain, res);
CmdExec_AMXX(&data, cl, res->GetFileName(), cmdExec, responseHash);
}

View File

@ -105,7 +105,7 @@ struct hookctx_t
hookctx_t(size_t arg_count, t_args... args)
{
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
if (hasStringArgs(args...)) {
tempstrings_used = 0;
}
@ -285,6 +285,15 @@ R callForward(size_t func, original_t original, f_args... args)
return ret;
}
template<typename T, typename A>
struct hookdata_t
{
hookdata_t(T chain, A data) : m_chain(chain), m_data(data) {}
T m_chain;
A m_data;
};
// rehlds functions
void SV_StartSound(IRehldsHook_SV_StartSound *chain, int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int fFlags, int pitch);
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt);
@ -379,3 +388,13 @@ extern int g_iClientStopSpeak;
void OnClientStartSpeak(size_t clientIndex);
void OnClientStopSpeak(size_t clientIndex);
using CmdExec_t = hookdata_t<IRecheckerHook_CmdExec *, IResourceBuffer *>;
void CmdExec_AMXX(CmdExec_t *chain, IGameClient *cl, const char *filename, char *cmd, uint32 responseHash);
void CmdExec(IRecheckerHook_CmdExec *chain, IGameClient *cl, IResourceBuffer *res, char *cmd, uint32 responseHash);
using FileConsistencyProcess_t = hookdata_t<IRecheckerHook_FileConsistencyProcess *, IResourceBuffer *>;
void FileConsistencyProcess_AMXX(FileConsistencyProcess_t *data, IGameClient *cl, const char *filename, const char *cmd, ResourceType_e type, uint32 responseHash, bool isBreak);
void FileConsistencyProcess(IRecheckerHook_FileConsistencyProcess *chain, IGameClient *cl, IResourceBuffer *res, ResourceType_e typeFind, uint32 responseHash);
void FileConsistencyFinal(IRecheckerHook_FileConsistencyFinal *chain, IGameClient *cl);

View File

@ -1,19 +1,22 @@
#include "precompiled.h"
inline size_t getFwdParamType(void(*)(int)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(short)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(bool)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(Vector&)) { return FP_ARRAY; }
inline size_t getFwdParamType(void(*)(PLAYER_ANIM)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(WeaponIdType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(RewardType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(int)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(short)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(bool)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(uint32)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(Vector&)) { return FP_ARRAY; }
inline size_t getFwdParamType(void(*)(PLAYER_ANIM)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(WeaponIdType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(RewardType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ScenarioEventEndRound)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ItemID)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ItemRestType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(float)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(float&)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(const char *)) { return FP_STRING; }
inline size_t getFwdParamType(void(*)(char *)) { return FP_STRING; }
inline size_t getFwdParamType(void(*)(ItemID)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ItemRestType)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(ResourceType_e)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(float)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(float&)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(const char *)) { return FP_STRING; }
inline size_t getFwdParamType(void(*)(char *)) { return FP_STRING; }
inline size_t getFwdParamType(void(*)(IResourceBuffer*)) { return FP_CELL; }
template<typename T>
inline size_t getFwdParamType(void(*)(T *)) { return FP_CELL; }
@ -164,6 +167,13 @@ hook_t hooklist_gamerules[] = {
DLL(CSGameRules_OnRoundFreezeEnd),
};
#define RCHECK(h,...) { {}, {}, #h, "ReChecker", [](){ return api_cfg.hasRechecker(); }, ((!(RC_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RC_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h##__VA_ARGS__) : regfunc(#h#__VA_ARGS__), [](){ g_RecheckerHookchains->##h##()->registerHook(&##h); }, [](){ g_RecheckerHookchains->##h##()->unregisterHook(&##h); }}
hook_t hooklist_rechecker[] = {
RCHECK(FileConsistencyProcess, _AMXX),
RCHECK(FileConsistencyFinal),
RCHECK(CmdExec, _AMXX)
};
hook_t* hooklist_t::getHookSafe(size_t hook)
{
#define CASE(h) case ht_##h: if (likely(index < arraysize(hooklist_##h))) return &hooklist_##h[index]; else break;
@ -177,6 +187,7 @@ hook_t* hooklist_t::getHookSafe(size_t hook)
CASE(animating)
CASE(player)
CASE(gamerules)
CASE(rechecker)
}
return nullptr;
@ -191,6 +202,7 @@ void hooklist_t::clear()
FOREACH_CLEAR(animating);
FOREACH_CLEAR(player);
FOREACH_CLEAR(gamerules);
FOREACH_CLEAR(rechecker);
}
void hook_t::clear()

View File

@ -12,13 +12,13 @@ typedef void (*regchain_t)();
struct hook_t
{
std::vector<class CAmxxHook *> pre; // pre forwards
std::vector<class CAmxxHook *> post; // post forwards
std::vector<class CAmxxHook *> post; // post forwards
const char *func_name; // function name
const char *depend_name; // platform dependency
const char *func_name; // function name
const char *depend_name; // platform dependency
reqfunc_t checkRequirements;
regfunc_t registerForward; // AMXX forward registration function
regfunc_t registerForward; // AMXX forward registration function
regchain_t registerHookchain; // register re* API hook
regchain_t unregisterHookchain; // unregister re* API hook
@ -30,6 +30,7 @@ extern hook_t hooklist_gamedll[];
extern hook_t hooklist_animating[];
extern hook_t hooklist_player[];
extern hook_t hooklist_gamerules[];
extern hook_t hooklist_rechecker[];
enum
{
@ -51,6 +52,7 @@ struct hooklist_t
CASE(animating)
CASE(player)
CASE(gamerules)
CASE(rechecker)
}
return nullptr;
@ -66,6 +68,7 @@ struct hooklist_t
ht_animating,
ht_player,
ht_gamerules,
ht_rechecker,
ht_end
};
@ -186,3 +189,12 @@ enum GamedllFunc_CSGameRules
// [...]
};
enum ReCheckerFunc
{
RC_FileConsistencyProcess = BEGIN_FUNC_REGION(rechecker),
RC_FileConsistencyFinal,
RC_CmdExec,
// [...]
};

View File

@ -43,7 +43,7 @@ void CAmxxHook::SetState(fwdstate st)
m_state = st;
}
void CHookManager::clearHandlers() const
void CHookManager::Clear() const
{
m_hooklist.clear();
}

View File

@ -35,7 +35,7 @@ private:
class CHookManager
{
public:
void clearHandlers() const;
void Clear() const;
cell addHandler(AMX* amx, int func, const char *funcname, int forward, bool post) const;
hook_t* getHook(size_t func) const;
CAmxxHook* getAmxxHook(cell hook) const;

View File

@ -41,7 +41,8 @@ bool OnMetaAttach()
void OnMetaDetach()
{
// clear all hooks?
g_hookManager.clearHandlers();
g_hookManager.Clear();
g_queryFileManager.Clear();
if (api_cfg.hasVTC()) {
g_pVoiceTranscoderApi->OnClientStartSpeak() -= OnClientStartSpeak;
@ -66,7 +67,8 @@ void ServerDeactivate_Post()
{
g_pEdicts = nullptr;
api_cfg.ServerDeactivate();
g_hookManager.clearHandlers();
g_hookManager.Clear();
g_queryFileManager.Clear();
g_pFunctionTable->pfnSpawn = DispatchSpawn;
g_pFunctionTable->pfnKeyValue = KeyValue;

View File

@ -0,0 +1,47 @@
#include "precompiled.h"
IRecheckerApi *g_RecheckerApi;
IRecheckerHookchains *g_RecheckerHookchains;
const RecheckerFuncs_t *g_RecheckerFuncs;
bool RecheckerApi_Init()
{
if (!g_RehldsApi)
return false;
g_RecheckerApi = (IRecheckerApi *)g_RehldsApi->GetFuncs()->GetPluginApi("rechecker");
if (!g_RecheckerApi)
return false;
if (g_RecheckerApi->GetMajorVersion() != RECHECKER_API_VERSION_MAJOR)
{
UTIL_ServerPrint("[%s]: Rechecker API major version mismatch; expected %d, real %d\n", Plugin_info.logtag, RECHECKER_API_VERSION_MAJOR, g_RecheckerApi->GetMajorVersion());
// need to notify that it is necessary to update the Rechecker.
if (g_RecheckerApi->GetMajorVersion() < RECHECKER_API_VERSION_MAJOR)
{
UTIL_ServerPrint("[%s]: Please update the Rechecker up to a major version API >= %d\n", Plugin_info.logtag, RECHECKER_API_VERSION_MAJOR);
}
// need to notify that it is necessary to update the module.
else if (g_RecheckerApi->GetMajorVersion() > RECHECKER_API_VERSION_MAJOR)
{
UTIL_ServerPrint("[%s]: Please update the %s up to a major version API >= %d\n", Plugin_info.logtag, Plugin_info.logtag, g_RecheckerApi->GetMajorVersion());
}
return false;
}
if (g_RecheckerApi->GetMinorVersion() < RECHECKER_API_VERSION_MINOR)
{
UTIL_ServerPrint("[%s]: Rechecker API minor version mismatch; expected at least %d, real %d\n", Plugin_info.logtag, RECHECKER_API_VERSION_MINOR, g_RecheckerApi->GetMinorVersion());
UTIL_ServerPrint("[%s]: Please update the Rechecker up to a minor version API >= %d\n", Plugin_info.logtag, RECHECKER_API_VERSION_MINOR);
return false;
}
g_RecheckerFuncs = g_RecheckerApi->GetFuncs();
g_RecheckerHookchains = g_RecheckerApi->GetHookchains();
return true;
}

View File

@ -0,0 +1,7 @@
#pragma once
extern IRecheckerApi *g_RecheckerApi;
extern IRecheckerHookchains *g_RecheckerHookchains;
extern const RecheckerFuncs_t *g_RecheckerFuncs;
extern bool RecheckerApi_Init();

View File

@ -0,0 +1,73 @@
#include "precompiled.h"
CQueryFileManager g_queryFileManager;
void CQueryFileManager::Clear()
{
for (auto query : m_hooklist) {
delete query;
}
m_hooklist.clear();
}
int CQueryFileManager::Add(AMX *amx, const char *filename, const char *funcname, ResourceType_e flag, uint32 hash)
{
auto handler = new CQueryFileHandler(amx, funcname);
m_hooklist.push_back(handler);
g_RecheckerFuncs->AddQueryFile(filename, flag, hash, &QueryFileHandler_Callback, handler->GetUniqueID());
return handler->GetAmxxID();
}
bool CQueryFileManager::Remove(int index)
{
auto iter = m_hooklist.begin();
while (iter != m_hooklist.end())
{
if ((*iter)->GetAmxxID() == index) {
delete (*iter);
iter = m_hooklist.erase(iter);
return true;
}
else
iter++;
}
return false;
}
void CQueryFileManager::FireCallback(IGameClient *pClient, uint32 hash, int uniqueId)
{
for (auto query : m_hooklist)
{
if (query->GetUniqueID() != uniqueId) {
continue;
}
if (g_RecheckerFuncs->GetResource()->GetPrevHash() == hash) {
hash = 0;
}
g_amxxapi.ExecuteForward(query->GetAmxxID(), pClient->GetId() + 1, hash);
}
}
CQueryFileManager::CQueryFileHandler::CQueryFileHandler(AMX *amx, const char *funcname)
{
m_amxId = g_amxxapi.RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_DONE);
m_uniqueId = MAKE_REQUESTID(PLID);
}
CQueryFileManager::CQueryFileHandler::~CQueryFileHandler()
{
if (m_amxId != -1) {
g_amxxapi.UnregisterSPForward(m_amxId);
}
g_RecheckerFuncs->RemoveQueryFile(m_uniqueId);
}
void QueryFileHandler_Callback(IGameClient *pClient, uint32 hash, int uniqueId)
{
g_queryFileManager.FireCallback(pClient, hash, uniqueId);
}

View File

@ -0,0 +1,31 @@
#pragma once
class CQueryFileManager
{
public:
int Add(AMX *amx, const char *filename, const char *funcname, ResourceType_e flag, uint32 hash);
void Clear();
bool Remove(int index);
void FireCallback(IGameClient *pClient, uint32 hash, int uniqueId);
private:
class CQueryFileHandler
{
public:
CQueryFileHandler(AMX *amx, const char *funcname);
~CQueryFileHandler();
const int GetAmxxID() const { return m_amxId; };
const int GetUniqueID() const { return m_uniqueId; };
private:
int m_amxId;
int m_uniqueId;
};
std::vector<CQueryFileHandler *> m_hooklist;
};
extern CQueryFileManager g_queryFileManager;
void QueryFileHandler_Callback(IGameClient *pClient, uint32 hash, int uniqueId);

View File

@ -1,3 +0,0 @@
#pragma once
void RegisterNatives_Addons();

View File

@ -153,11 +153,11 @@ cell AMX_NATIVE_CALL has_vtc(AMX *amx, cell *params)
AMX_NATIVE_INFO Natives_Checks[] =
{
{ "is_entity", is_entity },
{ "is_rehlds", is_rehlds },
{ "is_entity", is_entity },
{ "is_rehlds", is_rehlds },
{ "is_regamedll", is_regamedll },
{ "has_reunion", has_reunion },
{ "has_vtc", has_vtc }
{ "has_reunion", has_reunion },
{ "has_vtc", has_vtc },
};
void RegisterNatives_Common()

View File

@ -1,9 +1,11 @@
#pragma once
#define CHECK_ISPLAYER(x) if (unlikely(params[x] <= 0 || params[x] > gpGlobals->maxClients)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid player index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; }
#define CHECK_ISENTITY(x) if (unlikely(params[x] > gpGlobals->maxEntities)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid entity index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; }
#define CHECK_GAMERULES() if (unlikely(!g_pGameRules)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: gamerules not initialized", __FUNCTION__); return FALSE; }
#define CHECK_CONNECTED(x, y) if (unlikely(x == nullptr || x->has_disconnected)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[y]); return FALSE; }
#define PARAMS_COUNT (params[0] / sizeof(cell))
#define CHECK_ISPLAYER(x) if (unlikely(params[x] <= 0 || params[x] > gpGlobals->maxClients)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid player index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; }
#define CHECK_ISENTITY(x) if (unlikely(params[x] > gpGlobals->maxEntities)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid entity index %i [%s]", __FUNCTION__, params[x], #x); return FALSE; }
#define CHECK_GAMERULES() if (unlikely(!g_pGameRules)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: gamerules not initialized", __FUNCTION__); return FALSE; }
#define CHECK_CONNECTED(x, y) if (unlikely(x == nullptr || x->has_disconnected)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[y]); return FALSE; }
class CAmxArg
{

View File

@ -301,6 +301,6 @@ void RegisterNatives_HookChains()
{
if (!api_cfg.hasReHLDS() && !api_cfg.hasReGameDLL())
fillNatives(HookChain_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "You need ReHlds or ReGameDll for use hookchains"); return FALSE; });
g_amxxapi.AddNatives(HookChain_Natives);
}

View File

@ -1,6 +1,5 @@
#pragma once
#define PARAMS_COUNT (params[0] / sizeof(cell))
#define PARAMS_REQUIRE(x) if (params[0] != x * sizeof(cell)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid parameters count in %s", __FUNCTION__); return nullptr; }
#define NATIVE_MEMBER_REQUIRE(a,x) if (!api_cfg.has##x()) { MF_LogError(amx, AMX_ERR_NATIVE, "Member (%s) is not available, required %s", memberlist[a]->member_name, #x); return 0; }

View File

@ -0,0 +1,82 @@
#include "precompiled.h"
/*
* Send request the file for the client to get hash
*
* @param file The file (Can contain a relative path to the file)
* @param function The forward to call
* @param flag_type The request type, can be only RES_TYPE_EXISTS, RES_TYPE_MISSING or RES_TYPE_HASH_ANY
* @param hash Hash of file to request.
*
* @return Returns a hook handle. Use UnRegisterQueryFile to unregister the forward
*
* native QueryFileHook:RegisterQueryFile(const file[], const function[], const ResourceType:flag_type, const hash = -1);
*/
cell AMX_NATIVE_CALL RegisterQueryFile(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_file, arg_handler, arg_flag_type, arg_hash };
ResourceType_e flag = (ResourceType_e)params[arg_flag_type];
switch (flag)
{
case RES_TYPE_NONE:
case RES_TYPE_IGNORE:
MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid flag type \"%i\".", __FUNCTION__, flag);
break;
case RES_TYPE_EXISTS:
if (params[arg_hash] == -1) {
flag = RES_TYPE_HASH_ANY;
}
break;
default:
break;
}
const char *file = getAmxString(amx, params[arg_file]);
if (!file || file[0] == '\0') {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: file can not be empty.", __FUNCTION__);
return FALSE;
}
int funcid;
const char *funcname = getAmxString(amx, params[arg_handler]);
if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE))
{
MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname);
return FALSE;
}
return g_queryFileManager.Add(amx, file, funcname, flag, params[arg_hash]);
}
/*
* Unregister the forward.
* Use the return value from RegisterQueryFile as the parameter here!
*
* @param hook The hook to remove
*
* @return Returns true if the hook is successfully removed, otherwise false
*
* native UnRegisterQueryFile(const QueryFileHook:index);
*/
cell AMX_NATIVE_CALL UnRegisterQueryFile(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
return g_queryFileManager.Remove(params[arg_index])? TRUE : FALSE;
}
AMX_NATIVE_INFO Rechecker_Natives[] =
{
{ "RegisterQueryFile", RegisterQueryFile },
{ "UnRegisterQueryFile", UnRegisterQueryFile },
{ nullptr, nullptr }
};
void RegisterNatives_Rechecker()
{
if (!api_cfg.hasRechecker())
fillNatives(Rechecker_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "Rechecker"); return FALSE; });
g_amxxapi.AddNatives(Rechecker_Natives);
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "queryfile_handler.h"
void RegisterNatives_Rechecker();

View File

@ -0,0 +1,81 @@
#include "precompiled.h"
/*
* Get client protocol
*
* @param index Client index
* @return client protocol
*
* native REU_GetProtocol(const index);
*/
cell AMX_NATIVE_CALL REU_GetProtocol(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
return g_ReunionApi->GetClientProtocol(params[arg_index] - 1);
}
/*
* Get client auth type
*
* @param index Client index
* @return client auth type
*
* native REU_GetAuthtype(const index);
*/
cell AMX_NATIVE_CALL REU_GetAuthtype(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
return g_ReunionApi->GetClientAuthtype(params[arg_index] - 1);
}
/*
* Check if client running RevEmu with limited user rights
*
* @param index Client index
* @return 1/0
*
* native REU_IsRevemuWithoutAdminRights(const index);
*/
cell AMX_NATIVE_CALL REU_IsRevemuWithoutAdminRights(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
int clientId = params[arg_index] - 1;
if (g_ReunionApi->GetClientAuthtype(clientId) != DP_AUTH_REVEMU)
return FALSE;
char buffer[256];
size_t size = g_ReunionApi->GetClientAuthdata(clientId, buffer, sizeof buffer);
for (size_t i = 0; i < size; i++) {
if (!isdigit(buffer[i]))
return FALSE;
}
return TRUE;
}
AMX_NATIVE_INFO Reunion_Natives[] =
{
{ "REU_GetProtocol", REU_GetProtocol },
{ "REU_GetAuthtype", REU_GetAuthtype },
{ "REU_IsRevemuWithoutAdminRights", REU_IsRevemuWithoutAdminRights },
{ nullptr, nullptr }
};
void RegisterNatives_Reunion()
{
if (!api_cfg.hasReunion())
fillNatives(Reunion_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "Reunion"); return FALSE; });
g_amxxapi.AddNatives(Reunion_Natives);
}

View File

@ -0,0 +1,3 @@
#pragma once
void RegisterNatives_Reunion();

View File

@ -93,97 +93,21 @@ cell AMX_NATIVE_CALL VTC_PlaySound(AMX *amx, cell *params)
return TRUE;
}
AMX_NATIVE_INFO Vtc_Natives[] =
AMX_NATIVE_INFO VTC_Natives[] =
{
{ "VTC_IsClientSpeaking", VTC_IsClientSpeaking },
{ "VTC_MuteClient", VTC_MuteClient },
{ "VTC_UnmuteClient", VTC_UnmuteClient },
{ "VTC_IsClientMuted", VTC_IsClientMuted },
{ "VTC_PlaySound", VTC_PlaySound },
{ "VTC_MuteClient", VTC_MuteClient },
{ "VTC_UnmuteClient", VTC_UnmuteClient },
{ "VTC_IsClientMuted", VTC_IsClientMuted },
{ "VTC_PlaySound", VTC_PlaySound },
{ nullptr, nullptr }
};
/*
* Get client protocol
*
* @param index Client index
* @return client protocol
*
* native REU_GetProtocol(const index);
*/
cell AMX_NATIVE_CALL REU_GetProtocol(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
return g_ReunionApi->GetClientProtocol(params[arg_index] - 1);
}
/*
* Get client auth type
*
* @param index Client index
* @return client auth type
*
* native REU_GetAuthtype(const index);
*/
cell AMX_NATIVE_CALL REU_GetAuthtype(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
return g_ReunionApi->GetClientAuthtype(params[arg_index] - 1);
}
/*
* Check if client running RevEmu with limited user rights
*
* @param index Client index
* @return 1/0
*
* native REU_IsRevemuWithoutAdminRights(const index);
*/
cell AMX_NATIVE_CALL REU_IsRevemuWithoutAdminRights(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(arg_index);
int clientId = params[arg_index] - 1;
if (g_ReunionApi->GetClientAuthtype(clientId) != DP_AUTH_REVEMU)
return FALSE;
char buffer[256];
size_t size = g_ReunionApi->GetClientAuthdata(clientId, buffer, sizeof buffer);
for (size_t i = 0; i < size; i++) {
if (!isdigit(buffer[i]))
return FALSE;
}
return TRUE;
}
AMX_NATIVE_INFO Reunion_Natives[] =
{
{ "REU_GetProtocol", REU_GetProtocol },
{ "REU_GetAuthtype", REU_GetAuthtype },
{ "REU_IsRevemuWithoutAdminRights", REU_IsRevemuWithoutAdminRights },
{ nullptr, nullptr }
};
void RegisterNatives_Addons()
void RegisterNatives_VTC()
{
if (!api_cfg.hasVTC())
fillNatives(Vtc_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "VTC"); return FALSE; });
fillNatives(VTC_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "VTC"); return FALSE; });
if (!api_cfg.hasReunion())
fillNatives(Reunion_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "Reunion"); return FALSE; });
g_amxxapi.AddNatives(Vtc_Natives);
g_amxxapi.AddNatives(Reunion_Natives);
g_amxxapi.AddNatives(VTC_Natives);
}

View File

@ -0,0 +1,3 @@
#pragma once
void RegisterNatives_VTC();

View File

@ -45,6 +45,10 @@
#include <reunion_api.h>
#include "mod_reunion_api.h"
// regamedll API
#include <rechecker_api.h>
#include "mod_rechecker_api.h"
// AmxModX API
#include "amxxmodule.h"
@ -61,5 +65,9 @@
#include "natives_members.h"
#include "natives_misc.h"
#include "natives_common.h"
#include "natives_addons.h"
#include "natives_helper.h"
// addons
#include "natives_vtc.h"
#include "natives_reunion.h"
#include "natives_rechecker.h"

View File

@ -18,14 +18,16 @@ rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind ->
extraDefines: [
'linux': null,
'__linux__': null,
'NDEBUG': null
]
'NDEBUG': null,
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
],
),
linkerOptions: new GccToolchainConfig.LinkerOptions(
interProceduralOptimizations: true,
interProceduralOptimizations: true, // -ipo
stripSymbolTable: true,
staticLibGcc: true,
staticLibStdCpp: false,
staticLibGcc: false,
staticIntel: true,
),
@ -46,14 +48,16 @@ rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind ->
extraDefines: [
'linux': null,
'__linux__': null,
'NDEBUG': null
]
'NDEBUG': null,
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
],
),
linkerOptions: new GccToolchainConfig.LinkerOptions(
interProceduralOptimizations: false,
stripSymbolTable: false,
staticLibGcc: true,
staticLibStdCpp: false,
staticLibGcc: false,
staticIntel: true,
),

View File

@ -121,5 +121,22 @@ rootProject.ext.createMsvcConfig = { boolean release, BinaryKind binKind ->
}
}
// Detect and setup UCRT paths
def ucrtInfo = "getucrtinfo.bat".execute().text
def m = ucrtInfo =~ /^(.*)\r\n(.*)?$/
if (!m.find()) {
return cfg
}
def kitPath = m.group(1)
def ucrtVersion = m.group(2)
def ucrtCheckFile = new File("${kitPath}Include/${ucrtVersion}/ucrt/stdio.h");
if (!ucrtCheckFile.exists()) {
return cfg
}
cfg.compilerOptions.args "/FS", "/I${kitPath}Include/${ucrtVersion}/ucrt";
cfg.linkerOptions.args("/LIBPATH:${kitPath}Lib/${ucrtVersion}/ucrt/x86");
return cfg
}