CSave::ShouldSaveField
0x004a7950 · 467 bytes · __thiscall
_ZN5CSave15ShouldSaveFieldEPKvP17typedescription_t
Decompiled
undefined (3 params)
/* CSave::ShouldSaveField(void const*, typedescription_t*) */
bool __thiscall CSave::ShouldSaveField(CSave *this,void *param_1,typedescription_t *param_2)
{
char *pcVar1;
int *piVar2;
char cVar3;
ushort uVar4;
int iVar5;
uint uVar6;
typedescription_t *ptVar7;
uint uVar8;
int *piVar9;
typedescription_t *ptVar10;
int local_34;
void *local_28;
int local_24;
typedescription_t *local_20;
if (((*(ushort *)(param_2 + 0xe) & 2) != 0) && (iVar5 = *(int *)param_2, iVar5 != 0)) {
if (iVar5 == 0xb) {
local_28 = param_1;
local_24 = (int)param_1 - *(int *)(param_2 + 8);
local_20 = param_2;
cVar3 = (**(code **)(**(int **)(param_2 + 0x14) + 8))(*(int **)(param_2 + 0x14),&local_28);
return cVar3 == '\0';
}
if (iVar5 == 0xd) {
uVar8 = (uint)*(ushort *)(param_2 + 0xc);
if (*(int *)(param_2 + 0x24) != uVar8 * 4) {
Warning("WARNING! Field %s is using the wrong FIELD_ type!\nFix this or you\'ll see a crash.\n"
,*(undefined4 *)(param_2 + 4));
uVar8 = (uint)*(ushort *)(param_2 + 0xc);
}
if (uVar8 != 0) {
if (*(int *)param_1 != -1) {
return true;
}
uVar6 = 0;
while (uVar6 = uVar6 + 1, uVar6 != uVar8) {
if (*(int *)((int)param_1 + uVar6 * 4) != -1) {
return true;
}
}
}
}
else if (iVar5 == 10) {
uVar4 = *(ushort *)(param_2 + 0xe) & 0x40;
if (uVar4 == 0) {
piVar9 = *(int **)(param_2 + 0x20);
piVar2 = piVar9;
}
else {
if (*(short *)(param_2 + 0xc) != 1) {
return false;
}
piVar9 = *(int **)(param_2 + 0x20);
if (piVar9 == (int *)0x0) {
return false;
}
piVar2 = *(int **)param_1;
}
if (piVar2 != (int *)0x0) {
if (piVar9[3] != 0) {
return true;
}
if (uVar4 != 0) {
param_1 = *(void **)param_1;
}
local_34 = *(ushort *)(param_2 + 0xc) - 1;
if (local_34 != -1) {
while( true ) {
ptVar10 = (typedescription_t *)*piVar9;
ptVar7 = ptVar10 + piVar9[1] * 0x40;
for (; ptVar10 < ptVar7; ptVar10 = ptVar10 + 0x40) {
cVar3 = ShouldSaveField(this,(void *)(*(int *)(ptVar10 + 8) + (int)param_1),ptVar10);
if (cVar3 != '\0') {
return true;
}
}
local_34 = local_34 + -1;
param_1 = (void *)((int)param_1 + *(int *)(param_2 + 0x24));
if (local_34 == -1) break;
piVar9 = *(int **)(param_2 + 0x20);
}
}
}
}
else {
iVar5 = (uint)*(ushort *)(param_2 + 0xc) * *(int *)(gSizes + iVar5 * 4);
if (*(int *)(param_2 + 0x24) != iVar5) {
Warning("WARNING! Field %s is using the wrong FIELD_ type!\nFix this or you\'ll see a crash.\n"
,*(undefined4 *)(param_2 + 4));
iVar5 = (uint)*(ushort *)(param_2 + 0xc) * *(int *)(gSizes + *(int *)param_2 * 4);
}
if (iVar5 == 4) {
if (*(int *)param_1 != 0) {
return true;
}
}
else {
pcVar1 = (char *)((int)param_1 + iVar5);
if (param_1 < pcVar1) {
cVar3 = *(char *)param_1;
while( true ) {
if (cVar3 != '\0') {
return true;
}
param_1 = (void *)((int)param_1 + 1);
if (param_1 == pcVar1) break;
cVar3 = *(char *)param_1;
}
}
}
}
}
return false;
}
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.