CBaseEntity::PrecacheModelComponents
0x00615d20 · 1592 bytes · __cdecl
_ZN11CBaseEntity23PrecacheModelComponentsEi
Decompiled
undefined (1 param)
/* CBaseEntity::PrecacheModelComponents(int) */
void CBaseEntity::PrecacheModelComponents(int param_1)
{
ushort uVar1;
IMDLCache *pIVar2;
char cVar3;
short sVar4;
int iVar5;
char *pcVar6;
CModelSoundsCache *this;
KeyValues *this_00;
char *pcVar7;
KeyValues *pKVar8;
KeyValues *this_01;
studiohdr_t *psVar9;
int iVar10;
int *piVar11;
int iVar12;
uint uVar13;
int iVar14;
int iVar15;
int iVar16;
int in_GS_OFFSET;
CStudioHdr *local_198;
int local_194;
int local_188 [2];
undefined4 local_180;
undefined4 local_17c;
undefined4 local_174;
undefined4 local_170;
undefined4 local_15c [3];
undefined4 local_150;
undefined4 local_14c;
undefined4 local_148 [3];
undefined4 local_13c;
undefined4 local_138;
char local_120 [256];
int local_20;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
uVar13 = (uint)(ushort)g_ModelPrecacheSystem._28_2_;
local_188[0] = param_1;
if (g_ModelPrecacheSystem._28_2_ != -1) {
do {
while( true ) {
iVar14 = uVar13 * 0x10;
cVar3 = (*(code *)g_ModelPrecacheSystem._12_4_)
(local_188,g_ModelPrecacheSystem._16_4_ + 8 + iVar14);
if (cVar3 != '\0') break;
cVar3 = (*(code *)g_ModelPrecacheSystem._12_4_)
(g_ModelPrecacheSystem._16_4_ + iVar14 + 8,local_188);
if (cVar3 == '\0') {
piVar11 = (int *)(iVar14 + g_ModelPrecacheSystem._16_4_ + 0xc);
*piVar11 = *piVar11 + 1;
goto LAB_00615e37;
}
if ((CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel == '\0') &&
(iVar5 = __cxa_guard_acquire(&CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel), iVar5 != 0)) {
CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel = 0xffff;
DAT_00f26b96 = 0xffff;
DAT_00f26b98 = 0xffff;
__cxa_guard_release(&CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel);
}
uVar1 = *(ushort *)(g_ModelPrecacheSystem._16_4_ + 2 + iVar14);
uVar13 = (uint)uVar1;
if (uVar1 == 0xffff) goto LAB_00615de0;
}
if ((CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel == '\0') &&
(iVar5 = __cxa_guard_acquire(&CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel), iVar5 != 0)) {
CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel = 0xffff;
DAT_00f26b96 = 0xffff;
DAT_00f26b98 = 0xffff;
__cxa_guard_release(&CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Links(unsigned_short)::s_Sentinel);
}
uVar13 = (uint)*(ushort *)(g_ModelPrecacheSystem._16_4_ + iVar14);
} while (*(ushort *)(g_ModelPrecacheSystem._16_4_ + iVar14) != 0xffff);
}
LAB_00615de0:
local_198 = (CStudioHdr *)local_188;
local_188[0] = param_1;
local_188[1] = 0;
CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
::Insert((CUtlRBTree<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short,CUtlMap<int,int,unsigned_short>::CKeyLess,CUtlMemory<UtlRBTreeNode_t<CUtlMap<int,int,unsigned_short>::Node_t,unsigned_short>,unsigned_short>>
*)(g_ModelPrecacheSystem + 0xc),(Node_t *)local_198);
iVar14 = (**(code **)(*modelinfo + 8))(modelinfo,param_1);
if ((iVar14 != 0) && (iVar5 = (**(code **)(*modelinfo + 0x2c))(modelinfo,iVar14), iVar5 == 3)) {
pcVar6 = (char *)(**(code **)(*modelinfo + 0x10))(modelinfo,iVar14);
local_188[0] = 0;
local_188[1] = 0;
local_180 = 0xfffffffe;
local_17c = 0xffffffff;
local_188[0] = (**(code **)(*g_pFullFileSystem + 0x94))(g_pFullFileSystem,pcVar6);
sVar4 = CUtlRBTree<CUtlCachedFileData<CModelSoundsCache>::ElementType_t,unsigned_short,bool(*)(CUtlCachedFileData<CModelSoundsCache>::ElementType_t_const&,CUtlCachedFileData<CModelSoundsCache>::ElementType_t_const&),CUtlMemory<UtlRBTreeNode_t<CUtlCachedFileData<CModelSoundsCache>::ElementType_t,unsigned_short>,unsigned_short>>
::Find((CUtlRBTree<CUtlCachedFileData<CModelSoundsCache>::ElementType_t,unsigned_short,bool(*)(CUtlCachedFileData<CModelSoundsCache>::ElementType_t_const&,CUtlCachedFileData<CModelSoundsCache>::ElementType_t_const&),CUtlMemory<UtlRBTreeNode_t<CUtlCachedFileData<CModelSoundsCache>::ElementType_t,unsigned_short>,unsigned_short>>
*)(g_ModelSoundsCache + 4),(ElementType_t *)local_198);
if (sVar4 == -1) {
V_ExtractFileExtension(pcVar6,local_120,8);
iVar5 = V_stristr(local_120,"mdl");
if (iVar5 == 0) {
if (local_120[0] == '\0') {
Warning("Precache of %s ambigious (no extension specified)\n",pcVar6);
}
else {
Warning("Late precache of %s (file missing?)\n",pcVar6);
}
goto LAB_00615e37;
}
DevMsg(2,"Late precache of %s, need to rebuild modelsounds.cache\n",pcVar6);
}
this = (CModelSoundsCache *)
CUtlCachedFileData<CModelSoundsCache>::Get
((CUtlCachedFileData<CModelSoundsCache> *)g_ModelSoundsCache,pcVar6);
if (this != (CModelSoundsCache *)0x0) {
CModelSoundsCache::PrecacheSoundList(this);
}
this_00 = KeyValues::operator_new((KeyValues *)0x2c,(uint)pcVar6);
/* try { // try from 00615ff7 to 00615ffb has its CatchHandler @ 00616436 */
KeyValues::KeyValues(this_00,"",(IKeyValuesSystem *)0x0,false);
/* try { // try from 0061600a to 006160c6 has its CatchHandler @ 0061636f */
pcVar6 = (char *)(**(code **)(*modelinfo + 0x54))(modelinfo,iVar14);
pcVar7 = (char *)(**(code **)(*modelinfo + 0x10))(modelinfo,iVar14);
cVar3 = KeyValues::LoadFromBuffer(this_00,pcVar7,pcVar6,(IBaseFileSystem *)0x0,(char *)0x0);
if (cVar3 != '\0') {
if ((PrecacheModelComponents(int)::keyParticles == '\0') &&
(iVar5 = __cxa_guard_acquire(&PrecacheModelComponents(int)::keyParticles), iVar5 != 0)) {
/* try { // try from 0061630c to 00616328 has its CatchHandler @ 00616448 */
piVar11 = (int *)KeyValuesSystem();
PrecacheModelComponents(int)::keyParticles =
(**(code **)(*piVar11 + 0x14))(piVar11,"Particles",1);
__cxa_guard_release(&PrecacheModelComponents(int)::keyParticles);
}
if ((PrecacheModelComponents(int)::keyName == '\0') &&
(iVar5 = __cxa_guard_acquire(&PrecacheModelComponents(int)::keyName), iVar5 != 0)) {
/* try { // try from 006162c5 to 006162e1 has its CatchHandler @ 00616385 */
piVar11 = (int *)KeyValuesSystem();
PrecacheModelComponents(int)::keyName = (**(code **)(*piVar11 + 0x14))(piVar11,"name",1);
__cxa_guard_release(&PrecacheModelComponents(int)::keyName);
}
pKVar8 = (KeyValues *)KeyValues::FindKey(this_00,PrecacheModelComponents(int)::keyParticles);
if (pKVar8 != (KeyValues *)0x0) {
for (pKVar8 = (KeyValues *)KeyValues::GetFirstSubKey(pKVar8); pKVar8 != (KeyValues *)0x0;
pKVar8 = (KeyValues *)KeyValues::GetNextKey(pKVar8)) {
this_01 = (KeyValues *)KeyValues::FindKey(pKVar8,PrecacheModelComponents(int)::keyName);
if (this_01 == (KeyValues *)0x0) {
pcVar6 = "";
}
else {
pcVar6 = (char *)KeyValues::GetString(this_01,(char *)0x0,"");
}
PrecacheParticleSystem(pcVar6);
}
}
}
if (this_00 != (KeyValues *)0x0) {
KeyValues::deleteThis();
}
pIVar2 = mdlcache;
psVar9 = (studiohdr_t *)(**(code **)(*modelinfo + 0x7c))(modelinfo,iVar14);
CStudioHdr::CStudioHdr(local_198,psVar9,pIVar2);
if (local_188[0] != 0) {
/* try { // try from 00616122 to 006161dc has its CatchHandler @ 0061639a */
VerifySequenceIndex(local_198);
iVar14 = CStudioHdr::GetNumSeq(local_198);
if (0 < iVar14) {
local_194 = 0;
do {
iVar10 = CStudioHdr::pSeqdesc(local_198,local_194);
iVar5 = *(int *)(iVar10 + 0x18);
iVar16 = 0;
iVar15 = 0;
if (0 < iVar5) {
do {
while ((iVar12 = *(int *)(iVar10 + 0x1c) + iVar16 + iVar10,
(*(uint *)(iVar12 + 8) & 0x410) == 0x400 || (*(int *)(iVar12 + 4) != 0x20))) {
iVar15 = iVar15 + 1;
iVar16 = iVar16 + 0x50;
if (iVar15 == iVar5) goto LAB_006161f0;
}
nexttoken(local_120,0x100,(char *)(iVar12 + 0xc),' ');
PrecacheParticleSystem(local_120);
iVar15 = iVar15 + 1;
iVar16 = iVar16 + 0x50;
} while (iVar15 != iVar5);
}
LAB_006161f0:
local_194 = local_194 + 1;
} while (local_194 != iVar14);
}
}
CStudioHdr::Term(local_198);
local_13c = 0;
CUtlMemory<int,int>::Purge((CUtlMemory<int,int> *)local_148);
local_138 = local_148[0];
CUtlMemory<int,int>::Purge((CUtlMemory<int,int> *)local_148);
local_150 = 0;
CUtlMemory<int,int>::Purge((CUtlMemory<int,int> *)local_15c);
local_14c = local_15c[0];
CUtlMemory<int,int>::Purge((CUtlMemory<int,int> *)local_15c);
local_174 = 0;
CUtlMemory<studiohdr_t_const*,int>::Purge((CUtlMemory<studiohdr_t_const*,int> *)&local_180);
local_170 = local_180;
CUtlMemory<studiohdr_t_const*,int>::Purge((CUtlMemory<studiohdr_t_const*,int> *)&local_180);
}
LAB_00615e37:
if (local_20 != *(int *)(in_GS_OFFSET + 0x14)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
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.