CBaseGameStats::SaveToFileNOW
0x004636c0 · 1229 bytes · __thiscall
_ZN14CBaseGameStats13SaveToFileNOWEb
Decompiled
undefined (2 params)
/* CBaseGameStats::SaveToFileNOW(bool) */
undefined4 __thiscall CBaseGameStats::SaveToFileNOW(CBaseGameStats *this,bool param_1)
{
code *pcVar1;
size_t sVar2;
char cVar3;
undefined4 uVar4;
void *pvVar5;
int iVar6;
undefined4 uVar7;
char *pcVar8;
int in_GS_OFFSET;
byte bVar9;
undefined1 local_392;
undefined1 local_391;
void *local_390 [4];
size_t local_380;
byte local_37b;
int local_370;
byte local_35c;
undefined4 local_358 [4];
undefined4 local_348;
char local_320 [256];
char local_220 [512];
int local_20;
bVar9 = 0;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
if (CBGSDriver[0x130d] != '\0') {
cVar3 = StatsTrackingIsFullyEnabled();
if (cVar3 != '\0') {
uVar7 = (*(code *)**(undefined4 **)gamestats)(gamestats);
if ((char)uVar7 != '\0') {
CUtlBuffer::CUtlBuffer((CUtlBuffer *)local_390,0,0,0);
if ((local_37b & 1) == 0) {
cVar3 = CUtlBuffer::CheckPut((CUtlBuffer *)local_390,2);
if (cVar3 != '\0') {
if ((local_35c & 1) == 0) {
*(undefined2 *)((int)local_390[0] + (local_380 - local_370)) = 6;
}
else {
pvVar5 = (void *)((local_380 - local_370) + (int)local_390[0]);
if (pvVar5 != (void *)0x0) {
local_392 = 0;
local_391 = 6;
/* try { // try from 00463b42 to 00463ba1 has its CatchHandler @ 00463bb2 */
_V_memcpy(pvVar5,&local_392,2);
}
}
local_380 = local_380 + 2;
CUtlBuffer::AddNullTermination((CUtlBuffer *)local_390);
}
}
else {
/* try { // try from 00463777 to 00463a9b has its CatchHandler @ 00463bb2 */
CUtlBuffer::Printf((CUtlBuffer *)local_390,"%d",6);
}
CUtlBuffer::Put((CUtlBuffer *)local_390,&s_szPseudoUniqueID,0x10);
cVar3 = (**(code **)(*(int *)this + 0x3c))(this);
if (cVar3 == '\0') {
if ((local_37b & 1) == 0) {
cVar3 = CUtlBuffer::CheckPut((CUtlBuffer *)local_390,4);
if (cVar3 != '\0') {
if ((local_35c & 1) == 0) {
*(undefined4 *)((int)local_390[0] + (local_380 - local_370)) = 0xfeedbeef;
}
else {
pvVar5 = (void *)((local_380 - local_370) + (int)local_390[0]);
if (pvVar5 != (void *)0x0) {
local_358[0] = 0xefbeedfe;
_V_memcpy(pvVar5,local_358,4);
}
}
local_380 = local_380 + 4;
CUtlBuffer::AddNullTermination((CUtlBuffer *)local_390);
}
}
else {
CUtlBuffer::Printf((CUtlBuffer *)local_390,"%d",0xfeedbeef);
}
}
else {
BasicGameStats_t::SaveToBuffer((BasicGameStats_t *)(this + 4),(CUtlBuffer *)local_390);
}
(**(code **)(*(int *)gamestats + 0x94))(gamestats,local_390);
pcVar8 = local_220;
for (iVar6 = 0x80; iVar6 != 0; iVar6 = iVar6 + -1) {
pcVar8[0] = '\0';
pcVar8[1] = '\0';
pcVar8[2] = '\0';
pcVar8[3] = '\0';
pcVar8 = pcVar8 + ((uint)bVar9 * -2 + 1) * 4;
}
pcVar1 = *(code **)(filesystem[1] + 0x28);
uVar4 = (**(code **)(*(int *)this + 0x40))(this);
cVar3 = (*pcVar1)(filesystem + 1,uVar4,&DAT_00c146f4);
if (cVar3 == '\0') {
(**(code **)(*engine + 0xd0))(engine,local_320,0x100);
V_StripTrailingSlash(local_320);
uVar4 = (**(code **)(*(int *)this + 0x40))(this);
V_snprintf(local_220,0x200,"%s/%s",local_320,uVar4);
_V_strlower(local_220);
V_FixSlashes(local_220,'/');
}
else {
pcVar1 = *(code **)(*filesystem + 0x30);
uVar4 = (**(code **)(*(int *)this + 0x40))(this);
(*pcVar1)(filesystem,uVar4,&DAT_00c146f4,local_220,0x200,0,0);
}
sVar2 = local_380;
if ((CBGSDriver[0x130e] != '\0') || (param_1)) {
(**(code **)(filesystem[1] + 0x3c))(filesystem + 1,local_220,&DAT_00c146f4,local_390);
StatsLog(this,"Shut down wrote to \'%s\'\n",local_220);
}
else {
pvVar5 = malloc(local_380);
CUtlBuffer::CUtlBuffer((CUtlBuffer *)local_358,pvVar5,sVar2,0);
/* try { // try from 00463aad to 00463af7 has its CatchHandler @ 00463bca */
CUtlBuffer::Put((CUtlBuffer *)local_358,local_390[0],sVar2);
(**(code **)(*filesystem + 0x134))(filesystem,local_220,local_358[0],local_348,1,0,0);
CUtlMemory<unsigned_char,int>::Purge((CUtlMemory<unsigned_char,int> *)local_358);
}
CUtlMemory<unsigned_char,int>::Purge((CUtlMemory<unsigned_char,int> *)local_390);
goto LAB_004636ee;
}
}
}
uVar7 = 0;
LAB_004636ee:
if (local_20 == *(int *)(in_GS_OFFSET + 0x14)) {
return uVar7;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
SourceMod gamedata
paste intoaddons/sourcemod/gamedata/<your_plugin>.txt
used as the SourceMod key — change to fit your plugin's convention
SourceMod library name (server / engine / matchmaking)
Just a Signatures{} block, ready to drop into a gamedata
file. Wire it up in your plugin however you like - SDKCall, DHooks,
raw memory ops, or anything else.
Signatures + Functions block. The plugin uses
DHookCreateFromConf - DHooks reads return type, this-type,
calling convention, and argument types straight from the gamedata. Less
boilerplate in the plugin, types travel with the gamedata.
Gamedata KeyValues
DHooks plugin example
Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.