diff --git a/README.md b/README.md index fd738ab..92eff2b 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ #### `sv_steam_bypass <0/1>`(置1为不验证SteamID) - 本功能可以缓解`No Steam logon`(code 6)问题(仅限开启状态下进入的玩家) - 开启本功能**会削弱服务器安全性**,且禁止家庭共享功能将失效 -- **该cvar为采用延迟加载,不能加入到启动项中** - **注意: 开启此功能会导致A2S_INFO结果异常,可以通过[插件](https://github.com/lakwsh/l4d2_vomit_fix)修复** ## 4. 禁止家庭共享(无依赖) diff --git a/README_EN.md b/README_EN.md index bec0f0b..3bcad87 100644 --- a/README_EN.md +++ b/README_EN.md @@ -36,7 +36,6 @@ #### `sv_steam_bypass <0/1>` (Set to 1 to bypass SteamID verification) - This feature can alleviate the `No Steam logon` (code 6) issue (only for players who enter while the feature is enabled). - Enabling this feature **will weaken server security**, and Family Sharing functionality will be disabled. -- **This cvar is loaded with a delay and cannot be added to launch options.** - **Note: Enabling this feature will cause abnormal A2S_INFO results, which can be fixed with [this plugin](https://github.com/lakwsh/l4d2_vomit_fix).** ## 4. Disable Family Sharing (No dependency) diff --git a/l4dtoolz.cpp b/l4dtoolz.cpp index 1a542a0..cdd189c 100644 --- a/l4dtoolz.cpp +++ b/l4dtoolz.cpp @@ -1,24 +1,27 @@ +#include "eiface.h" +#include "tier1/tier1.h" #ifdef WIN32 #include "sig_win32.h" #else #include "sig_linux.h" #endif +#include "sigtool.h" #include "l4dtoolz.h" #define BINMSIZE 0x1400000 // 20M #define CHKPTR(P, V) ((P) && !((uintptr_t)(P) & (V))) #define CMPPTR(P, V, C) (CHKPTR(P, V) && abs((int)(P) - (int)(C)) < BINMSIZE) #define READCALL(P) (((P) + 5 - 1) + *(int *)(P)) -#define CHKVAL \ - int new_value = ((ConVar *)var)->GetInt(); \ - int old_value = atoi(pOldValue); \ - if (new_value == old_value) return; #pragma pack(push, 1) +class CSteamID { +public: + uint64_t m_steamid; +}; typedef struct { - uint64_t id; + CSteamID id; int32_t code; - uint64_t owner; + CSteamID owner; } ValidateAuthTicketResponse_t; #pragma pack(pop) @@ -30,46 +33,61 @@ static ICvar *g_cvar; static int g_tickrate = 30; static edict_t **edict_ptr; +static int *maxcl_ptr; static int *slots_ptr; static uint64 *cookie_ptr; -static int *maxcl_ptr; -static uintptr_t *gamerules_ptr; +static uintptr_t ***gamerules_ptr; static uintptr_t rules_max_ptr; -static mem_sig_t *rules_max_org; -static uintptr_t dsp_max_ptr; -static mem_sig_t *dsp_max_org; -static uintptr_t lobby_req_ptr; -static mem_sig_t *lobby_req_org; +static uintptr_t rules_max_org; +static uintptr_t match_max_ptr; +static uintptr_t match_max_org; +static uintptr_t lobbyreq_ptr; +static uintptr_t lobbyreq_org; +static uintptr_t check_ptr; +static uintptr_t check_org; static uintptr_t *steam3_ptr; -static uintptr_t authreq_ptr; -static mem_sig_t *authreq_org; static uintptr_t *authrsp_ptr; static uintptr_t authrsp_org; static uintptr_t tickint_ptr; -static mem_sig_t *tickint_org; +static uintptr_t tickint_org; + +static void write_dword(uintptr_t addr, uintptr_t val) { + static uint8_t dword[6] = {0x04, 0x00}; + static auto patch = (mem_sig_t *)dword; + if (!addr) return; + *(uintptr_t *)patch->sig = val; + write_sig(addr, patch); +} + +// Linux: static int FUNC_T GetTotalNumPlayersSupported(void *); +static int FUNC_T GetTotalNumPlayersSupported() { + return 32; // max +} + +// Linux: static int FUNC_T GetMaxHumanPlayers(void *); +static int FUNC_T GetMaxHumanPlayers() { + return g_cvar->FindVar("sv_maxplayers")->GetInt(); +} -void l4dtoolz::OnChangeMax(IConVar *var, const char *pOldValue, float flOldValue) { - CHKVAL +void OnChangeMax(IConVar *var, const char *, float) { if (!slots_ptr) { var->SetValue(-1); Msg("[L4DToolZ] sv_maxplayers init error\n"); return; } + int new_value = ((ConVar *)var)->GetInt(); if (new_value < 0) { - write_sig(rules_max_ptr, rules_max_org); - write_sig(dsp_max_ptr, dsp_max_org); + write_dword(rules_max_ptr, rules_max_org); return; } *slots_ptr = new_value; - max_player_new->sig[1] = (uint8_t)new_value; - write_sig(rules_max_ptr, max_player_new); - if (!dsp_max_ptr) Msg("[L4DToolZ] sv_maxplayers(dsp) init error\n"); - else write_sig(dsp_max_ptr, max_player_new); + write_dword(match_max_ptr, (uintptr_t)&GetTotalNumPlayersSupported); + write_dword(rules_max_ptr, (uintptr_t)&GetMaxHumanPlayers); } -ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max human players", true, -1, true, 31, l4dtoolz::OnChangeMax); +ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max human players", true, -1, true, 31, OnChangeMax); ConVar sv_lobby_cookie("sv_lobby_cookie", "0", 0); -void l4dtoolz::Cookie_f(const CCommand &args) { +void Cookie_f(const CCommand &args) { if (!cookie_ptr) { Msg("[L4DToolZ] sv_cookie init error\n"); return; @@ -88,18 +106,18 @@ void l4dtoolz::Cookie_f(const CCommand &args) { g_cvar->FindVar("sv_allow_lobby_connect_only")->SetValue(val != 0); *cookie_ptr = val; } -ConCommand cookie("sv_cookie", l4dtoolz::Cookie_f, "Lobby reservation cookie"); +ConCommand cookie("sv_cookie", Cookie_f, "Lobby reservation cookie"); -void l4dtoolz::OnSetMaxCl(IConVar *var, const char *pOldValue, float flOldValue) { - CHKVAL +void OnSetMaxCl(IConVar *var, const char *, float) { if (!maxcl_ptr) { Msg("[L4DToolZ] sv_setmax init error\n"); return; } + int new_value = ((ConVar *)var)->GetInt(); *maxcl_ptr = new_value; Msg("[L4DToolZ] maxplayers set to %d\n", new_value); } -ConVar sv_setmax("sv_setmax", "18", 0, "Max clients", true, 18, true, 32, l4dtoolz::OnSetMaxCl); +ConVar sv_setmax("sv_setmax", "18", 0, "Max clients", true, 18, true, 32, OnSetMaxCl); void l4dtoolz::ServerActivate(edict_t *, int, int) { int slots = sv_maxplayers.GetInt(); @@ -109,58 +127,36 @@ void l4dtoolz::ServerActivate(edict_t *, int, int) { Msg("[L4DToolZ] sv_maxplayers(rules) init error\n"); return; } - rules_max_ptr = ((uintptr_t **)*gamerules_ptr)[0][info_idx]; - read_sig(rules_max_ptr, max_player_new, rules_max_org); - if (slots >= 0) write_sig(rules_max_ptr, max_player_new); -} - -// Linux: static float GetTickInterval(void *); -static float GetTickInterval() { - static float tickinv = 1.0f / g_tickrate; - return tickinv; + rules_max_ptr = (uintptr_t)&(*gamerules_ptr)[0][info_idx]; + rules_max_org = (*gamerules_ptr)[0][info_idx]; + if (slots >= 0) write_dword(rules_max_ptr, (uintptr_t)&GetMaxHumanPlayers); } -#ifdef WIN32 -static int PreAuth(const void *, int, uint64 steamID) -#else -static int PreAuth(void *, const void *, int, uint64 steamID) -#endif -{ - if (!steamID) { - Msg("[L4DToolZ] invalid steamID.\n"); - return 1; - } - Msg("[L4DToolZ] %llu connected.\n", steamID); - return 0; +#define steam_off 0x7D +HOOK_DEF(bool, CheckChallengeType, uintptr_t client, int, void *, int, void *key, int keylen) { + if (keylen < 8) return false; + memcpy((void *)(client + steam_off), key, sizeof(CSteamID)); // malloc + return true; } -void l4dtoolz::OnBypassAuth(IConVar *var, const char *pOldValue, float flOldValue) { - CHKVAL - if (!steam3_ptr) { - err: +void OnBypassAuth(IConVar *var, const char *, float) { + int new_value = ((ConVar *)var)->GetInt(); + if (!steam3_ptr || !check_ptr) { var->SetValue(0); Msg("[L4DToolZ] sv_steam_bypass init error\n"); return; } - uint8_t authreq[6] = {0x04, 0x00}; - auto authreq_new = (mem_sig_t *)authreq; - if (!authreq_ptr) { - auto gsv = (uintptr_t **)steam3_ptr[1]; - if (!CHKPTR(gsv, 0xFU)) goto err; - authreq_ptr = (uintptr_t)&gsv[0][authreq_idx]; - read_sig(authreq_ptr, authreq_new, authreq_org); - } - *(uintptr_t *)authreq_new->sig = (uintptr_t)&PreAuth; - if (new_value) write_sig(authreq_ptr, authreq_new); - else write_sig(authreq_ptr, authreq_org); + if (new_value) write_dword(check_ptr, (uintptr_t)&CheckChallengeType); + else write_dword(check_ptr, check_org); } -ConVar sv_steam_bypass("sv_steam_bypass", "0", 0, "Bypass steam validation", true, 0, true, 1, l4dtoolz::OnBypassAuth); +ConVar sv_steam_bypass("sv_steam_bypass", "0", 0, "Bypass steam validation", true, 0, true, 1, OnBypassAuth); +#define rate_idx 0x2C void l4dtoolz::ClientSettingsChanged(edict_t *pEdict) // rate { if (g_tickrate == 30) return; if (!edict_ptr || !CHKPTR(*edict_ptr, 0x3U)) { - Msg("[L4DToolZ] datarate init error.\n"); + Msg("[L4DToolZ] datarate init error\n"); return; } auto net = (int *)g_engine->GetPlayerNetInfo((int)(pEdict - *edict_ptr)); @@ -169,12 +165,8 @@ void l4dtoolz::ClientSettingsChanged(edict_t *pEdict) // rate PLUGIN_RESULT l4dtoolz::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *, const char *, char *, int) { if (sv_steam_bypass.GetInt() != 1) return PLUGIN_CONTINUE; - ValidateAuthTicketResponse_t rsp = {(uint64)g_engine->GetPlayerUserId(pEntity)}; -#ifdef WIN32 - ((void(__thiscall *)(uintptr_t *, void *))authrsp_org)(steam3_ptr, &rsp); -#else - ((void (*)(uintptr_t *, void *))authrsp_org)(steam3_ptr, &rsp); -#endif + ValidateAuthTicketResponse_t rsp = {(uint64_t)g_engine->GetPlayerUserId(pEntity)}; + CALL(void, authrsp_org, uintptr_t *, void *)(steam3_ptr, &rsp); if (g_engine->GetPlayerUserId(pEntity) == -1) { *bAllowConnect = false; return PLUGIN_STOP; @@ -183,58 +175,56 @@ PLUGIN_RESULT l4dtoolz::ClientConnect(bool *bAllowConnect, edict_t *pEntity, con return PLUGIN_CONTINUE; } -#ifdef WIN32 -static void PostAuth(ValidateAuthTicketResponse_t *rsp) -#else -static void PostAuth(void *, ValidateAuthTicketResponse_t *rsp) -#endif -{ - if (!rsp->code && (rsp->id != rsp->owner)) { +HOOK_DEF(void, OnValidateAuthTicketResponse, ValidateAuthTicketResponse_t *rsp) { + if (!rsp->code && (rsp->id.m_steamid != rsp->owner.m_steamid)) { rsp->code = 2; - Msg("[L4DToolZ] %llu using family sharing, owner: %llu.\n", rsp->id, rsp->owner); - } -#ifdef WIN32 - __asm { - leave - mov ecx, steam3_ptr - jmp authrsp_org + Msg("[L4DToolZ] %llu using family sharing, owner: %llu.\n", rsp->id.m_steamid, rsp->owner.m_steamid); } -#else - ((void (*)(uintptr_t *, void *))authrsp_org)(steam3_ptr, rsp); -#endif + CALL(void, authrsp_org, uintptr_t *, void *)(steam3_ptr, rsp); } -void l4dtoolz::OnAntiSharing(IConVar *var, const char *pOldValue, float flOldValue) { - CHKVAL +void OnAntiSharing(IConVar *var, const char *, float) { + int new_value = ((ConVar *)var)->GetInt(); if (!authrsp_ptr) { var->SetValue(0); Msg("[L4DToolZ] sv_anti_sharing init error\n"); return; } - if (new_value) *authrsp_ptr = (uintptr_t)&PostAuth; + if (new_value) *authrsp_ptr = (uintptr_t)&OnValidateAuthTicketResponse; else *authrsp_ptr = authrsp_org; } -ConVar sv_anti_sharing("sv_anti_sharing", "0", 0, "No family sharing", true, 0, true, 1, l4dtoolz::OnAntiSharing); +ConVar sv_anti_sharing("sv_anti_sharing", "0", 0, "No family sharing", true, 0, true, 1, OnAntiSharing); -// Linux: static void ReplyReservationRequest(void *, void *, void *); -static void ReplyReservationRequest(void *, void *) { } +HOOK_DEF(void, ReplyReservationRequest, void *, void *) { } -void l4dtoolz::OnForceUnreserved(IConVar *var, const char *pOldValue, float flOldValue) { - CHKVAL - if (!lobby_req_ptr) { +void OnForceUnreserved(IConVar *var, const char *, float) { + int new_value = ((ConVar *)var)->GetInt(); + if (!lobbyreq_ptr) { var->SetValue(0); Msg("[L4DToolZ] sv_force_unreserved init error\n"); return; } if (new_value) { - write_sig(lobby_req_ptr, lobby_req_new); + write_dword(lobbyreq_ptr, (uintptr_t)&ReplyReservationRequest); g_cvar->FindVar("sv_allow_lobby_connect_only")->SetValue(0); return; } - write_sig(lobby_req_ptr, lobby_req_org); + write_dword(lobbyreq_ptr, lobbyreq_org); } -ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation", true, 0, true, 1, l4dtoolz::OnForceUnreserved); +ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation", true, 0, true, 1, OnForceUnreserved); +// Linux: static float FUNC_T GetTickInterval(void *); +static float FUNC_T GetTickInterval() { + static float tickinv = 1.0f / g_tickrate; + return tickinv; +} + +#define rules_idx 0x12 // rodata +#define sv_idx 0x80 // rodata +#define maxcl_idx 0x41 +#define title_idx 0x8 // rodata +#define match_idx 0x4 // rodata +#define tickint_idx 0x09 // rodata bool l4dtoolz::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) { g_engine = (IVEngineServer *)interfaceFactory(INTERFACEVERSION_VENGINESERVER, NULL); g_cvar = (ICvar *)interfaceFactory(CVAR_INTERFACE_VERSION, NULL); @@ -245,41 +235,39 @@ bool l4dtoolz::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameSe if (!gamerules_ptr) { auto client = (uintptr_t **)gameServerFactory("ServerGameClients003", NULL); - auto gamerules = *(uintptr_t **)(client[0][18] + info_off); // mov + auto gamerules = *(uintptr_t ****)(client[0][rules_idx] + rules_off); // mov if (CMPPTR(gamerules, 0x3U, gameServerFactory)) gamerules_ptr = gamerules; } - if (!edict_ptr) { - auto sv = *(uintptr_t ***)(((uint **)g_engine)[0][0x80] + sv_off); + if (!maxcl_ptr) { // any + auto sv = *(uintptr_t ***)(((uint **)g_engine)[0][sv_idx] + sv_off); if (!CMPPTR(sv, 0x7U, interfaceFactory)) return false; - edict_ptr = (edict_t **)&sv[edict_idx]; + maxcl_ptr = (int *)&sv[maxcl_idx]; slots_ptr = (int *)&sv[slots_idx]; cookie_ptr = (uint64 *)&sv[cookie_idx]; - maxcl_ptr = (int *)&sv[maxcl_idx]; - auto sfunc = (uintptr_t * (*)(void)) READCALL(sv[0][steam3_idx] + steam3_off); + edict_ptr = (edict_t **)&sv[edict_idx]; + lobbyreq_ptr = (uintptr_t)&sv[0][lobby_idx]; + lobbyreq_org = sv[0][lobby_idx]; + check_ptr = (uintptr_t)&sv[0][check_idx]; + check_org = sv[0][check_idx]; + auto sfunc = (uintptr_t *(*)(void)) READCALL(sv[0][steam3_idx] + steam3_off); if (CMPPTR(sfunc, 0xFU, interfaceFactory)) { steam3_ptr = sfunc(); // conn authrsp_ptr = &steam3_ptr[authrsp_idx]; authrsp_org = *authrsp_ptr; } - lobby_req_ptr = (uintptr_t)&sv[0][lobbyreq_idx]; - read_sig(lobby_req_ptr, lobby_req_new, lobby_req_org); - *(uintptr_t *)lobby_req_new->sig = (uintptr_t)&ReplyReservationRequest; } - if (!dsp_max_ptr) { + if (!match_max_ptr) { auto match = (uintptr_t **)interfaceFactory("MATCHFRAMEWORK_001", NULL); - auto title = ((uintptr_t * *(*)(void)) match[0][8])(); - dsp_max_ptr = title[0][4]; - read_sig(dsp_max_ptr, max_player_new, dsp_max_org); + auto title = ((uintptr_t **(*)(void)) match[0][title_idx])(); + match_max_ptr = (uintptr_t)&title[0][match_idx]; + match_max_org = title[0][match_idx]; } if ((g_tickrate != 30) && !tickint_ptr) { auto game = (uintptr_t **)gameServerFactory(INTERFACEVERSION_SERVERGAMEDLL, NULL); tickint_ptr = (uintptr_t)&game[0][tickint_idx]; - uint8_t tickint[6] = {0x04, 0x00}; - auto tickint_new = (mem_sig_t *)tickint; - read_sig(tickint_ptr, tickint_new, tickint_org); - *(uintptr_t *)tickint_new->sig = (uintptr_t)&GetTickInterval; - write_sig(tickint_ptr, tickint_new); + tickint_org = game[0][tickint_idx]; + write_dword(tickint_ptr, (uintptr_t)&GetTickInterval); ((uint *)g_cvar->FindVar("net_splitpacket_maxrate"))[15] = 0; // m_bHasMax Msg("[L4DToolZ] tickrate: %d\n", g_tickrate); } @@ -290,10 +278,10 @@ void l4dtoolz::Unload() { ConVar_Unregister(); DisconnectTier1Libraries(); + write_dword(check_ptr, check_org); if (authrsp_ptr) *authrsp_ptr = authrsp_org; - free_sig(authreq_ptr, authreq_org); - free_sig(rules_max_ptr, rules_max_org); - free_sig(dsp_max_ptr, dsp_max_org); - free_sig(lobby_req_ptr, lobby_req_org); - free_sig(tickint_ptr, tickint_org); -} + write_dword(rules_max_ptr, rules_max_org); + write_dword(match_max_ptr, match_max_org); + write_dword(lobbyreq_ptr, lobbyreq_org); + write_dword(tickint_ptr, tickint_org); +} \ No newline at end of file diff --git a/l4dtoolz.h b/l4dtoolz.h index b0fea3f..832b65f 100644 --- a/l4dtoolz.h +++ b/l4dtoolz.h @@ -1,9 +1,7 @@ #ifndef L4DTOOLZ_H #define L4DTOOLZ_H -#include "eiface.h" -#include "interface.h" -#include "tier1/tier1.h" +#include "iserverplugin.h" class l4dtoolz : public IServerPluginCallbacks { public: @@ -11,7 +9,7 @@ class l4dtoolz : public IServerPluginCallbacks { virtual void Unload(); virtual void Pause() { } virtual void UnPause() { } - virtual const char *GetPluginDescription() { return "L4DToolZ(2155) v2.3.2, https://github.com/lakwsh/l4dtoolz"; } + virtual const char *GetPluginDescription() { return "L4DToolZ(2155) v2.4.0, https://github.com/lakwsh/l4dtoolz"; } virtual void LevelInit(char const *pMapName) { } virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); virtual void GameFrame(bool simulating) { } @@ -25,14 +23,7 @@ class l4dtoolz : public IServerPluginCallbacks { virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity, const CCommand &args) { return PLUGIN_CONTINUE; } virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) { return PLUGIN_CONTINUE; } virtual void OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue) { } - - static void Cookie_f(const CCommand &args); - static void OnChangeMax(IConVar *var, const char *pOldValue, float flOldValue); - static void OnSetMaxCl(IConVar *var, const char *pOldValue, float flOldValue); - static void OnBypassAuth(IConVar *var, const char *pOldValue, float flOldValue); - static void OnAntiSharing(IConVar *var, const char *pOldValue, float flOldValue); - static void OnForceUnreserved(IConVar *var, const char *pOldValue, float flOldValue); }; extern l4dtoolz g_l4dtoolz; -#endif // L4DTOOLZ_H +#endif // L4DTOOLZ_H \ No newline at end of file diff --git a/sig_linux.h b/sig_linux.h index c2363f6..0a1433e 100644 --- a/sig_linux.h +++ b/sig_linux.h @@ -1,26 +1,20 @@ #ifndef SIG_LINUX_H #define SIG_LINUX_H -#include "sigtool.h" +#define FUNC_T __cdecl +#define HOOK_DEF(ret, func, ...) static ret FUNC_T func(void *, __VA_ARGS__) +#define CALL(ret, ptr, ...) ((ret (*)(__VA_ARGS__))ptr) -#define tickint_idx 0x09 // rodata -#define rate_idx 0x2C -#define info_off 0x01 -#define info_idx 0x89 -#define sv_off 0x06 // bss -#define edict_idx 0x85 -#define slots_idx 0x5F -#define cookie_idx 0x5B -#define maxcl_idx 0x41 -#define steam3_idx 0x41 -#define steam3_off 0x0F -#define authreq_idx 0x1D // rodata (?) -#define authrsp_idx 0x25 // bss -#define lobbyreq_idx 0x3E // rodata +#define info_idx 0x89 // rodata +#define rules_off 0x01 +#define sv_off 0x06 // bss +#define slots_idx 0x5F +#define cookie_idx 0x5B +#define edict_idx 0x85 +#define lobby_idx 0x3E // rodata +#define check_idx 0x3A // rodata +#define steam3_idx 0x41 +#define steam3_off 0x0F +#define authrsp_idx 0x25 // bss -uint8_t max_player[] = {0x06, 0x00, 0xB8, '*', 0x00, 0x00, 0x00, 0xC3}; -auto max_player_new = (mem_sig_t *)max_player; -uint8_t lobby_req[] = {0x04, 0x00, '*', '*', '*', '*'}; -auto lobby_req_new = (mem_sig_t *)lobby_req; - -#endif // SIG_LINUX_H +#endif // SIG_LINUX_H \ No newline at end of file diff --git a/sig_win32.h b/sig_win32.h index f5f95c2..fd7f093 100644 --- a/sig_win32.h +++ b/sig_win32.h @@ -1,26 +1,20 @@ #ifndef SIG_WIN32_H #define SIG_WIN32_H -#include "sigtool.h" +#define FUNC_T __stdcall +#define HOOK_DEF(ret, func, ...) static ret FUNC_T func(__VA_ARGS__) +#define CALL(ret, ptr, ...) ((ret (__thiscall *)(__VA_ARGS__))ptr) -#define tickint_idx 0x09 -#define rate_idx 0x2C -#define info_off 0x02 -#define info_idx 0x88 -#define sv_off 0x08 -#define edict_idx 0x86 -#define slots_idx 0x60 -#define cookie_idx 0x5C -#define maxcl_idx 0x41 -#define steam3_idx 0x40 -#define steam3_off 0x0D -#define authreq_idx 0x1D -#define authrsp_idx 0x21 -#define lobbyreq_idx 0x3D +#define info_idx 0x88 +#define rules_off 0x02 +#define sv_off 0x08 +#define slots_idx 0x60 +#define cookie_idx 0x5C +#define edict_idx 0x87 +#define lobby_idx 0x3D +#define check_idx 0x39 +#define steam3_idx 0x40 +#define steam3_off 0x0D +#define authrsp_idx 0x21 -uint8_t max_player[] = {0x06, 0x00, 0xB8, '*', 0x00, 0x00, 0x00, 0xC3}; -auto max_player_new = (mem_sig_t *)max_player; -uint8_t lobby_req[] = {0x04, 0x00, '*', '*', '*', '*'}; -auto lobby_req_new = (mem_sig_t *)lobby_req; - -#endif // SIG_WIN32_H +#endif // SIG_WIN32_H \ No newline at end of file diff --git a/sigtool b/sigtool index 2105b1e..693173d 160000 --- a/sigtool +++ b/sigtool @@ -1 +1 @@ -Subproject commit 2105b1ebccc3ed56b6e6b92447b961943926e159 +Subproject commit 693173d2d08b14df1b0440c88052ab1627944cc3