Dvar cheats
Co-Authored-By: Skull Merlin <86374920+skkuull@users.noreply.github.com>
This commit is contained in:
parent
605f04fa8d
commit
139f3c44a0
@ -83,7 +83,9 @@ namespace dvar_cheats
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto dvar_flag_checks_stub = utils::hook::assemble([](utils::hook::assembler& a)
|
void* get_dvar_flag_checks_stub()
|
||||||
|
{
|
||||||
|
return utils::hook::assemble([](utils::hook::assembler& a)
|
||||||
{
|
{
|
||||||
const auto can_set_value = a.newLabel();
|
const auto can_set_value = a.newLabel();
|
||||||
const auto zero_source = a.newLabel();
|
const auto zero_source = a.newLabel();
|
||||||
@ -92,82 +94,33 @@ namespace dvar_cheats
|
|||||||
a.mov(r8, rdi);
|
a.mov(r8, rdi);
|
||||||
a.mov(edx, esi);
|
a.mov(edx, esi);
|
||||||
a.mov(rcx, rbx);
|
a.mov(rcx, rbx);
|
||||||
a.call_aligned(apply_sv_cheats); //check if we are setting sv_cheats
|
a.call_aligned(apply_sv_cheats); // check if we are setting sv_cheats
|
||||||
a.popad64();
|
a.popad64();
|
||||||
a.cmp(esi, 0);
|
a.cmp(esi, 0);
|
||||||
a.jz(zero_source); //if the SetSource is 0 (INTERNAL) ignore flag checks
|
a.jz(zero_source); // if the SetSource is 0 (INTERNAL) ignore flag checks
|
||||||
|
|
||||||
a.pushad64();
|
a.pushad64();
|
||||||
a.mov(edx, esi); //source
|
a.mov(edx, esi); // source
|
||||||
a.mov(rcx, rbx); //dvar
|
a.mov(rcx, rbx); // dvar
|
||||||
a.call_aligned(dvar_flag_checks); //protect read/write/cheat/replicated dvars
|
a.call_aligned(dvar_flag_checks); // protect read/write/cheat/replicated dvars
|
||||||
a.cmp(al, 1);
|
a.cmp(al, 1);
|
||||||
a.jz(can_set_value);
|
a.jz(can_set_value);
|
||||||
|
|
||||||
// if we get here, we are non-zero source and CANNOT set values
|
// if we get here, we are non-zero source and CANNOT set values
|
||||||
a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag
|
a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag
|
||||||
a.jmp(0x1404FDCAB);
|
a.jmp(0x18655C_b);
|
||||||
|
|
||||||
// if we get here, we are non-zero source and CAN set values
|
// if we get here, we are non-zero source and CAN set values
|
||||||
a.bind(can_set_value);
|
a.bind(can_set_value);
|
||||||
a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag
|
a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag
|
||||||
a.cmp(esi, 1);
|
a.cmp(esi, 1);
|
||||||
a.jmp(0x1404FDA22);
|
a.jmp(0x1861EE_b);
|
||||||
|
|
||||||
// if we get here, we are zero source and ignore flags
|
// if we get here, we are zero source and ignore flags
|
||||||
a.bind(zero_source);
|
a.bind(zero_source);
|
||||||
a.jmp(0x1404FDA62);
|
a.jmp(0x18628F_b);
|
||||||
});
|
});
|
||||||
|
|
||||||
void cg_set_client_dvar_from_server(const int local_client_num, void* cg, const char* dvar_id, const char* value)
|
|
||||||
{
|
|
||||||
const auto* dvar = game::Dvar_FindVar(dvar_id);
|
|
||||||
if (dvar)
|
|
||||||
{
|
|
||||||
// If we send as string, it can't be set with source SERVERCMD because the game only allows that source on real server cmd dvars.
|
|
||||||
// Just use external instead as if it was being set by the console
|
|
||||||
game::Dvar_SetFromStringByNameFromSource(dvar_id, value, game::DvarSetSource::DVAR_SOURCE_EXTERNAL);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not a dvar name, assume it is an id and the game will handle normally
|
|
||||||
game::CG_SetClientDvarFromServer(local_client_num, cg, dvar_id, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_client_dvar_by_string(const int entity_num, const char* value)
|
|
||||||
{
|
|
||||||
const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack
|
|
||||||
const auto* command = utils::string::va("q %s \"%s\"", dvar, value);
|
|
||||||
|
|
||||||
game::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a)
|
|
||||||
{
|
|
||||||
const auto set_by_string = a.newLabel();
|
|
||||||
|
|
||||||
a.pushad64();
|
|
||||||
|
|
||||||
// check if we didn't find a network dvar index
|
|
||||||
a.mov(ecx, dword_ptr(rsp, 0x8C8));
|
|
||||||
a.cmp(ecx, 0);
|
|
||||||
a.je(set_by_string);
|
|
||||||
|
|
||||||
// we found an index, handle normally
|
|
||||||
a.popad64();
|
|
||||||
a.mov(r8d, ptr(rsp, 0x848));
|
|
||||||
a.lea(r9, ptr(rsp, 0x30));
|
|
||||||
a.jmp(0x1402E2E57);
|
|
||||||
|
|
||||||
// no index, let's send the dvar as a string
|
|
||||||
a.bind(set_by_string);
|
|
||||||
a.movzx(ecx, word_ptr(rsp, 0x8C0)); //entity_num
|
|
||||||
a.lea(rdx, ptr(rsp, 0xB0)); //value
|
|
||||||
a.call_aligned(set_client_dvar_by_string);
|
|
||||||
a.popad64();
|
|
||||||
a.jmp(0x1402E2E7D);
|
|
||||||
});
|
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
@ -179,15 +132,8 @@ namespace dvar_cheats
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::hook::nop(0x1404FDA0D, 4); // let our stub handle zero-source sets
|
utils::hook::nop(0x1861D4_b, 8); // let our stub handle zero-source sets
|
||||||
utils::hook::jump(0x1404FDA14, dvar_flag_checks_stub, true); // check extra dvar flags when setting values
|
utils::hook::jump(0x1861DF_b, get_dvar_flag_checks_stub(), true); // check extra dvar flags when setting values
|
||||||
|
|
||||||
// utils::hook::nop(0x14032AACC, 5); // remove error in PlayerCmd_SetClientDvar if setting a non-network dvar
|
|
||||||
// utils::hook::set<uint8_t>(0x14032AA9B, 0xEB);
|
|
||||||
// don't check flags on the dvars, send any existing dvar instead
|
|
||||||
// utils::hook::jump(0x14032AB14, player_cmd_set_client_dvar, true); // send non-network dvars as string
|
|
||||||
// utils::hook::call(0x1401BB782, cg_set_client_dvar_from_server);
|
|
||||||
// check for dvars being sent as string before parsing ids
|
|
||||||
|
|
||||||
scheduler::once([]()
|
scheduler::once([]()
|
||||||
{
|
{
|
||||||
@ -198,4 +144,4 @@ namespace dvar_cheats
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//REGISTER_COMPONENT(dvar_cheats::component)
|
REGISTER_COMPONENT(dvar_cheats::component)
|
||||||
|
@ -232,8 +232,8 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<GfxDrawMethod_s> gfxDrawMethod{0x0, 0x0};
|
WEAK symbol<GfxDrawMethod_s> gfxDrawMethod{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<int> dvarCount{0x0, 0x0};
|
WEAK symbol<int> dvarCount{0x0, 0x2999C34};
|
||||||
WEAK symbol<dvar_t> dvarPool{0x0, 0x0};
|
WEAK symbol<dvar_t> dvarPool{0x0, 0x344DF20};
|
||||||
|
|
||||||
WEAK symbol<void*> DB_XAssetPool{0x0, 0x0};
|
WEAK symbol<void*> DB_XAssetPool{0x0, 0x0};
|
||||||
WEAK symbol<const char*> g_assetNames{0x0, 0x0};
|
WEAK symbol<const char*> g_assetNames{0x0, 0x0};
|
||||||
|
Loading…
Reference in New Issue
Block a user