KeyValues::LoadFromBuffer
0x000467a0 · 1563 bytes · __thiscall
_ZN9KeyValues14LoadFromBufferEPKcR10CUtlBufferP15IBaseFileSystemS1_
Decompiled
undefined (5 params)
/* KeyValues::LoadFromBuffer(char const*, CUtlBuffer&, IBaseFileSystem*, char const*) */
undefined4 __thiscall
KeyValues::LoadFromBuffer
(KeyValues *this,char *param_1,CUtlBuffer *param_2,IBaseFileSystem *param_3,char *param_4)
{
uint uVar1;
uint uVar2;
char *pcVar3;
int iVar4;
int *piVar5;
bool bVar6;
char *pcVar7;
undefined *puVar8;
CUtlVector *pCVar9;
KeyValues *local_58;
char local_51;
KeyValues *local_50;
bool local_46;
bool local_45;
undefined4 local_44;
undefined4 local_40;
undefined4 local_3c;
int local_38;
undefined4 local_34;
undefined4 local_30;
undefined4 local_2c;
undefined4 local_28;
int local_24;
undefined4 local_20;
uVar2 = ThreadGetCurrentId();
if (uVar2 != g_KVMutex) {
LOCK();
bVar6 = g_KVMutex != 0;
uVar1 = uVar2;
if (bVar6) {
uVar1 = g_KVMutex;
}
g_KVMutex = uVar1;
UNLOCK();
if (bVar6) {
CThreadFastMutex::Lock(0xd3988,uVar2);
goto LAB_000467dc;
}
}
DAT_000d398c = DAT_000d398c + 1;
LAB_000467dc:
local_44 = 0;
local_40 = 0;
local_3c = 0;
local_38 = 0;
local_34 = 0;
local_30 = 0;
local_2c = 0;
local_28 = 0;
local_24 = 0;
local_20 = 0;
DAT_000d34a0 = param_1;
DAT_000d34a8 = 0;
local_50 = this;
local_58 = (KeyValues *)0x0;
do {
/* try { // try from 00046855 to 00046d63 has its CatchHandler @ 00046e60 */
pcVar3 = (char *)ReadToken(this,param_2,&local_46,&local_45);
if (((param_2[0x14] != (CUtlBuffer)0x0) || (pcVar3 == (char *)0x0)) ||
((local_46 == false && (*pcVar3 == '\0')))) break;
iVar4 = _V_stricmp(pcVar3,"#include");
if (iVar4 == 0) {
pcVar3 = (char *)ReadToken(this,param_2,&local_46,&local_45);
if ((pcVar3 == (char *)0x0) || (*pcVar3 == '\0')) {
pcVar7 = "#include is NULL ";
pcVar3 = DAT_000d34a0;
Warning("KeyValues Error: %s in file %s\n","#include is NULL ",DAT_000d34a0);
iVar4 = 0;
if (0 < DAT_000d34a8) {
do {
while ((0x3f < iVar4 || ((&g_KeyValuesErrorStack)[iVar4] == -1))) {
LAB_00046918:
iVar4 = iVar4 + 1;
if (DAT_000d34a8 <= iVar4) goto LAB_00046970;
}
if (iVar4 < DAT_000d34a4) {
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))(piVar5,(&g_KeyValuesErrorStack)[iVar4])
;
Warning(&DAT_000b2b56,pcVar7,pcVar3);
goto LAB_00046918;
}
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))(piVar5,(&g_KeyValuesErrorStack)[iVar4]);
Warning(&DAT_000b2b5b,pcVar7,pcVar3);
iVar4 = iVar4 + 1;
} while (iVar4 < DAT_000d34a8);
}
LAB_00046970:
Warning(&DAT_000b32c1,pcVar7,pcVar3);
}
else {
pCVar9 = (CUtlVector *)&local_44;
LAB_00046ce5:
ParseIncludedKeys(this,param_1,pcVar3,param_3,param_4,pCVar9);
}
}
else {
puVar8 = &DAT_000b2c4a;
iVar4 = _V_stricmp(pcVar3,"#base");
if (iVar4 == 0) {
pcVar3 = (char *)ReadToken(this,param_2,&local_46,&local_45);
if ((pcVar3 == (char *)0x0) || (*pcVar3 == '\0')) {
pcVar7 = "#base is NULL ";
pcVar3 = DAT_000d34a0;
Warning("KeyValues Error: %s in file %s\n","#base is NULL ",DAT_000d34a0);
iVar4 = 0;
if (0 < DAT_000d34a8) {
do {
if ((iVar4 < 0x40) && ((&g_KeyValuesErrorStack)[iVar4] != -1)) {
if (iVar4 < DAT_000d34a4) {
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))
(piVar5,(&g_KeyValuesErrorStack)[iVar4]);
Warning(&DAT_000b2b56,pcVar7,pcVar3);
}
else {
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))
(piVar5,(&g_KeyValuesErrorStack)[iVar4]);
Warning(&DAT_000b2b5b,pcVar7,pcVar3);
}
}
iVar4 = iVar4 + 1;
} while (iVar4 < DAT_000d34a8);
}
goto LAB_00046970;
}
pCVar9 = (CUtlVector *)&local_30;
goto LAB_00046ce5;
}
if (local_50 == (KeyValues *)0x0) {
local_50 = operator_new((KeyValues *)0x2c,(uint)puVar8);
Init(local_50,*(IKeyValuesSystem **)(this + 0x14),false);
/* try { // try from 00046d8a to 00046d8e has its CatchHandler @ 00046de9 */
SetName(local_50,pcVar3);
local_50[0x11] = (KeyValues)(this[0x11] != (KeyValues)0x0);
if (local_58 != (KeyValues *)0x0) {
*(KeyValues **)(local_58 + 0x1c) = local_50;
}
}
else {
SetName(local_50,pcVar3);
}
pcVar3 = (char *)ReadToken(this,param_2,&local_46,&local_45);
local_51 = '\x01';
if (local_45 != false) {
local_51 = EvaluateConditional(this,pcVar3);
pcVar3 = (char *)ReadToken(this,param_2,&local_46,&local_45);
}
if (((pcVar3 == (char *)0x0) || (*pcVar3 != '{')) || (local_46 != false)) {
pcVar7 = "LoadFromBuffer: missing {";
pcVar3 = DAT_000d34a0;
Warning("KeyValues Error: %s in file %s\n","LoadFromBuffer: missing {",DAT_000d34a0);
iVar4 = 0;
if (0 < DAT_000d34a8) {
do {
while ((0x3f < iVar4 || ((&g_KeyValuesErrorStack)[iVar4] == -1))) {
LAB_00046b50:
iVar4 = iVar4 + 1;
if (DAT_000d34a8 <= iVar4) goto LAB_00046ba8;
}
if (iVar4 < DAT_000d34a4) {
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))(piVar5,(&g_KeyValuesErrorStack)[iVar4])
;
Warning(&DAT_000b2b56,pcVar7,pcVar3);
goto LAB_00046b50;
}
piVar5 = (int *)KeyValuesSystem();
pcVar7 = (char *)(**(code **)(*piVar5 + 0x18))(piVar5,(&g_KeyValuesErrorStack)[iVar4]);
Warning(&DAT_000b2b5b,pcVar7,pcVar3);
iVar4 = iVar4 + 1;
} while (iVar4 < DAT_000d34a8);
}
LAB_00046ba8:
Warning(&DAT_000b32c1,pcVar7,pcVar3);
}
else {
RecursiveLoadFromBuffer(local_50,param_1,param_2);
}
if (local_51 == '\0') {
if (local_58 != (KeyValues *)0x0) {
*(undefined4 *)(local_58 + 0x1c) = 0;
}
Clear(local_50);
}
else {
local_58 = local_50;
local_50 = (KeyValues *)0x0;
}
}
} while (param_2[0x14] == (CUtlBuffer)0x0);
AppendIncludedKeys(this,(CUtlVector *)&local_44);
iVar4 = local_38 + -1;
if (0 < iVar4) {
do {
deleteThis();
iVar4 = iVar4 + -1;
} while (iVar4 != 0);
}
MergeBaseKeys(this,(CUtlVector *)&local_30);
iVar4 = local_24 + -1;
if (-1 < iVar4) {
do {
deleteThis();
iVar4 = iVar4 + -1;
} while (iVar4 != -1);
}
DAT_000d34a0 = &DAT_000b2b65;
DAT_000d34a8 = 0;
local_24 = 0;
CUtlMemory<KeyValues*,int>::Purge((CUtlMemory<KeyValues*,int> *)&local_30);
local_20 = local_30;
CUtlMemory<KeyValues*,int>::Purge((CUtlMemory<KeyValues*,int> *)&local_30);
local_38 = 0;
CUtlMemory<KeyValues*,int>::Purge((CUtlMemory<KeyValues*,int> *)&local_44);
local_34 = local_44;
CUtlMemory<KeyValues*,int>::Purge((CUtlMemory<KeyValues*,int> *)&local_44);
DAT_000d398c = DAT_000d398c + -1;
if (DAT_000d398c == 0) {
LOCK();
UNLOCK();
g_KVMutex = 0;
}
return 1;
}
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.