L L4D2node

CMatchExtL4D::LoadCustomGameModes

0x00035880 · 1124 bytes · __thiscall

_ZN12CMatchExtL4D19LoadCustomGameModesEv

Decompiled

undefined (1 param)

/* CMatchExtL4D::LoadCustomGameModes() */

void __thiscall CMatchExtL4D::LoadCustomGameModes(CMatchExtL4D *this)

{
  char cVar1;
  KeyValues *this_00;
  KeyValues *pKVar2;
  KeyValues *this_01;
  char *pcVar3;
  int iVar4;
  IBaseFileSystem *pIVar5;
  undefined4 *puVar6;
  int iVar7;
  int iVar8;
  int in_GS_OFFSET;
  longlong lVar9;
  int local_1254;
  undefined4 local_1244;
  undefined4 local_1240;
  int local_123c [5];
  char local_1228 [260];
  KeyValues local_1124 [260];
  char local_1020 [4096];
  int local_20;
  
  local_20 = *(int *)(in_GS_OFFSET + 0x14);
  this_00 = (KeyValues *)KeyValues::FindKey(*(KeyValues **)(this + 4),"GameModes",true);
  if (this_00 != (KeyValues *)0x0) {
    this_01 = (KeyValues *)local_123c;
    V_snprintf(local_1020,0x1000,"modes/*.txt");
    V_FixSlashes(local_1020,'/');
    local_123c[0] = 0;
    local_123c[1] = 0;
    local_123c[2] = 0;
    local_123c[3] = 0;
    local_123c[4] = 0;
                    /* try { // try from 00035943 to 000359a8 has its CatchHandler @ 00035cec */
    (**(code **)(*g_pFullFileSystem + 0x84))(g_pFullFileSystem,this_01,local_1020,"GAME");
    if (local_123c[3] < 1) {
      local_1254 = 0;
    }
    else {
      local_1254 = 0;
      iVar8 = 0;
LAB_0003599d:
      do {
        this_01 = KeyValues::operator_new((KeyValues *)0x2c,(uint)this_01);
                    /* try { // try from 000359c6 to 000359ca has its CatchHandler @ 00035d09 */
        KeyValues::KeyValues(this_01,"Mode",(IKeyValuesSystem *)0x0,false);
        iVar7 = iVar8 * 0x10;
                    /* try { // try from 000359db to 00035c45 has its CatchHandler @ 00035cec */
        pcVar3 = CUtlString::operator_cast_to_char_((CUtlString *)(local_123c[0] + iVar7));
        pIVar5 = (IBaseFileSystem *)0x0;
        if (g_pFullFileSystem != (int *)0x0) {
          pIVar5 = (IBaseFileSystem *)(g_pFullFileSystem + 1);
        }
        cVar1 = KeyValues::LoadFromFile(this_01,pIVar5,pcVar3,(char *)0x0);
        if (cVar1 == '\0') {
LAB_00035968:
          pKVar2 = (KeyValues *)CUtlString::Get((CUtlString *)(iVar7 + local_123c[0]));
          Warning("CMatchExtL4D:  Unable to load game mode from \"%s\".\n");
          KeyValues::deleteThis();
        }
        else {
          iVar4 = KeyValues::GetFirstSubKey(this_01);
          if (iVar4 == 0) goto LAB_00035968;
          pcVar3 = CUtlString::operator_cast_to_char_((CUtlString *)(local_123c[0] + iVar7));
          iVar4 = V_stristr(pcVar3,"workshop");
          if (iVar4 != 0) {
            pcVar3 = CUtlString::operator_cast_to_char_((CUtlString *)(local_123c[0] + iVar7));
            V_strncpy(local_1228,pcVar3,0x104);
            V_StripLastDir(local_1228,0x104);
            V_StripLastDir(local_1228,0x104);
            V_StripTrailingSlash(local_1228);
            V_FileBase(local_1228,(char *)local_1124,0x104);
            local_1244 = 0;
            local_1240 = 0;
            sscanf((char *)local_1124,"%llu",&local_1244);
            KeyValues::SetUint64((char *)this_01,CONCAT44(local_1244,"workshopid"));
          }
          pcVar3 = CUtlString::operator_cast_to_char_((CUtlString *)(iVar7 + local_123c[0]));
          V_FileBase(pcVar3,(char *)local_1124,0x104);
          KeyValues::SetString(this_01,"CfgFile",(char *)local_1124);
          KeyValues::SetInt(this_01,"mutation",1);
          KeyValues::SetInt(this_01,"addon",1);
          lVar9 = KeyValues::GetUint64((char *)this_01,0xb0b8f);
          if (lVar9 != 0) {
            KeyValues::SetUint64((char *)this_01,0xb0b8f);
          }
          pKVar2 = local_1124;
          iVar7 = KeyValues::FindKey(this_00,(char *)pKVar2,false);
          if (iVar7 == 0) {
            KeyValues::AddSubKey(this_00,this_01);
            local_1254 = local_1254 + 1;
            iVar8 = iVar8 + 1;
            if (local_123c[3] <= iVar8) break;
            goto LAB_0003599d;
          }
        }
        this_01 = pKVar2;
        iVar8 = iVar8 + 1;
      } while (iVar8 < local_123c[3]);
    }
    DevMsg("\tLoaded %d custom game modes.\n",local_1254);
    iVar8 = local_123c[3] + -1;
    iVar7 = iVar8 * 0x10;
    for (; -1 < iVar8; iVar8 = iVar8 + -1) {
      puVar6 = (undefined4 *)(local_123c[0] + iVar7);
      if (-1 < (int)puVar6[2]) {
        if ((void *)*puVar6 != (void *)0x0) {
          free((void *)*puVar6);
          *puVar6 = 0;
        }
        puVar6[1] = 0;
      }
      iVar7 = iVar7 + -0x10;
    }
    local_123c[3] = 0;
    CUtlMemory<CUtlString,int>::Purge((CUtlMemory<CUtlString,int> *)local_123c);
    local_123c[4] = local_123c[0];
    CUtlMemory<CUtlString,int>::Purge((CUtlMemory<CUtlString,int> *)local_123c);
  }
  if (local_20 == *(int *)(in_GS_OFFSET + 0x14)) {
    return;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

SourceMod gamedata

paste into addons/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.



        

        

          

Type inference is best-effort from the C signature - sanity-check the DHooks types before shipping.

Return-type handling cheatsheet (DHookReturn)