L L4D2node

CMatchExtL4D::ParseMissionFromFile

0x000360b0 · 2675 bytes · __thiscall

_ZN12CMatchExtL4D20ParseMissionFromFileEPKcby

Decompiled

undefined (4 params)

/* CMatchExtL4D::ParseMissionFromFile(char const*, bool, unsigned long long) */

void __thiscall
CMatchExtL4D::ParseMissionFromFile(CMatchExtL4D *this,char *param_1,bool param_2,ulonglong param_3)

{
  CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>> *this_00;
  CMatchExtL4D CVar1;
  char cVar2;
  KeyValues *pKVar3;
  KeyValues *this_01;
  KeyValues *this_02;
  IBaseFileSystem *pIVar4;
  KeyValues *this_03;
  undefined4 uVar5;
  int iVar6;
  KeyValues *this_04;
  KeyValues *this_05;
  int iVar7;
  undefined4 *puVar8;
  undefined4 uVar9;
  uint uVar10;
  int in_GS_OFFSET;
  char *pcVar11;
  char *pcVar12;
  CMatchExtL4D *pCVar13;
  CMatchExtL4D *pCVar14;
  int local_26c;
  KeyValues *local_25c;
  int local_244;
  short local_23c;
  ushort local_23a;
  CFmtStrN<256> local_238 [5];
  char local_233 [263];
  CFmtStrN<256> local_12c [5];
  char local_127 [263];
  int local_20;
  
  local_20 = *(int *)(in_GS_OFFSET + 0x14);
  pKVar3 = (KeyValues *)KeyValues::FindKey(*(KeyValues **)(this + 4),"GameModes",false);
  pCVar13 = (CMatchExtL4D *)0x0;
  pcVar12 = "Missions";
  pcVar11 = *(char **)(this + 4);
  this_01 = (KeyValues *)KeyValues::FindKey((KeyValues *)pcVar11,"Missions",false);
  if ((pKVar3 != (KeyValues *)0x0) && (this_01 != (KeyValues *)0x0)) {
    this_00 = (CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>> *)(this + 8);
    pCVar14 = this + 0x1c;
    pcVar11 = (char *)&local_23a;
    pcVar12 = (char *)pCVar14;
    pCVar13 = (CMatchExtL4D *)param_1;
    CUtlSymbolTable::Find(pcVar11);
    if (local_23a == 0xffff) {
      CUtlSymbolTable::AddString((char *)&local_23a);
      uVar10 = (uint)local_23a;
      pCVar13 = *(CMatchExtL4D **)(this + 0x14);
      if ((((int)pCVar13 <= (int)uVar10) && ((int)pCVar13 < (int)(uVar10 + 1))) &&
         (iVar7 = (uVar10 + 1) - (int)pCVar13, iVar7 != 0)) {
        CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>>::GrowVector(this_00,iVar7);
        CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>>::ShiftElementsRight
                  (this_00,(int)pCVar13,iVar7);
        pCVar14 = pCVar13;
      }
      *(undefined4 *)(*(int *)(this + 8) + uVar10 * 4) = 0;
      this_02 = KeyValues::operator_new((KeyValues *)0x2c,(uint)pCVar14);
                    /* try { // try from 000361fd to 00036201 has its CatchHandler @ 00036b62 */
      KeyValues::KeyValues(this_02,"mission",(IKeyValuesSystem *)0x0,false);
      pIVar4 = (IBaseFileSystem *)0x0;
      if (g_pFullFileSystem != 0) {
        pIVar4 = (IBaseFileSystem *)(g_pFullFileSystem + 4);
      }
      pCVar13 = (CMatchExtL4D *)param_1;
                    /* try { // try from 00036231 to 0003624f has its CatchHandler @ 00036b4c */
      cVar2 = KeyValues::LoadFromFile(this_02,pIVar4,param_1,(char *)0x0);
      if (cVar2 == '\0') {
        pcVar11 = "MissionManager:  Mission file \"%s\" is malformed, failed to parse.\n";
        Warning("MissionManager:  Mission file \"%s\" is malformed, failed to parse.\n",param_1);
        pcVar12 = param_1;
      }
      else {
                    /* try { // try from 00036289 to 0003643a has its CatchHandler @ 00036b4c */
        pcVar12 = (char *)KeyValues::GetString(this_02,"name",(char *)0x0);
        pCVar14 = (CMatchExtL4D *)0x0;
        pCVar13 = (CMatchExtL4D *)KeyValues::GetString(this_02,"version",(char *)0x0);
        if ((pCVar13 == (CMatchExtL4D *)0x0) || ((CMatchExtL4D *)pcVar12 == (CMatchExtL4D *)0x0)) {
          pcVar11 = "MissionManager:  Mission file \"%s\" is missing name and version\n";
                    /* try { // try from 000364b8 to 000369bb has its CatchHandler @ 00036b4c */
          Warning("MissionManager:  Mission file \"%s\" is missing name and version\n",param_1);
          pcVar12 = param_1;
          pCVar13 = pCVar14;
        }
        else {
          CVar1 = (CMatchExtL4D)*pcVar12;
          pCVar14 = (CMatchExtL4D *)pcVar12;
          while (CVar1 != (CMatchExtL4D)0x0) {
            if ((0x19 < (byte)(((byte)CVar1 & 0xdf) + 0xbf)) && (9 < (byte)((char)CVar1 - 0x30U))) {
              pcVar11 = 
              "MissionManager:  Only alphanumeric characters allowed in mission name: \"%s\" in \"%s\"\n"
              ;
              Warning("MissionManager:  Only alphanumeric characters allowed in mission name: \"%s\" in \"%s\"\n"
                      ,pcVar12,param_1);
              pCVar13 = (CMatchExtL4D *)param_1;
              goto LAB_00036250;
            }
            pCVar14 = pCVar14 + 1;
            CVar1 = *pCVar14;
          }
          CVar1 = *pCVar13;
          pCVar14 = pCVar13;
          while (CVar1 != (CMatchExtL4D)0x0) {
            if (9 < (byte)((char)CVar1 - 0x30U)) {
              pcVar11 = 
              "MissionManager:  Only numeric characters allowed in mission version: \"%s\" in \"%s\"\n"
              ;
              Warning("MissionManager:  Only numeric characters allowed in mission version: \"%s\" in \"%s\"\n"
                      ,pCVar13,param_1);
              pcVar12 = (char *)pCVar13;
              pCVar13 = (CMatchExtL4D *)param_1;
              goto LAB_00036250;
            }
            pCVar14 = pCVar14 + 1;
            CVar1 = *pCVar14;
          }
          pCVar14 = (CMatchExtL4D *)0x0;
          this_03 = (KeyValues *)KeyValues::FindKey(this_02,"modes",false);
          if (this_03 == (KeyValues *)0x0) {
            pcVar11 = "MissionManager:  Mission file \"%s\" is missing data for any game modes\n";
            Warning("MissionManager:  Mission file \"%s\" is missing data for any game modes\n",
                    param_1);
            pcVar12 = param_1;
            pCVar13 = pCVar14;
          }
          else {
            CFmtStrN<256>::CFmtStrN(local_238,"%s_%s",pcVar12,pCVar13);
            CUtlSymbolTable::Find((char *)&local_23c);
            if (local_23c == -1) {
              DevMsg("\tMission %s ver %s loading...\n",pcVar12,pCVar13);
              pcVar11 = (char *)KeyValues::GetString(this_02,"DisplayTitle","");
              if ((pcVar11 == (char *)0x0) || (*pcVar11 == '\0')) {
                KeyValues::SetString(this_02,"DisplayTitle",pcVar12);
              }
              KeyValues::SetName(this_02,pcVar12);
              KeyValues::SetInt(this_02,"BuiltIn",(uint)param_2);
              KeyValues::SetInt(this_02,"addon",(uint)!param_2);
              KeyValues::SetString(this_02,"CfgFile",param_1);
              KeyValues::SetString(this_02,"CfgTag",local_233);
              KeyValues::SetUint64((char *)this_02,CONCAT44((undefined4)param_3,"workshopid"));
              KeyValues::GetUint64((char *)this_02,0xb0b8f);
              uVar5 = 0;
              KeyValues::SetUint64((char *)this_02,0xb0b8f);
              pCVar14 = (CMatchExtL4D *)0x0;
              KeyValues::SetInt(this_02,"dlcrequired",0);
              local_25c = (KeyValues *)KeyValues::GetFirstTrueSubKey(pKVar3);
              if (local_25c != (KeyValues *)0x0) {
                local_26c = 0;
                do {
                  pcVar11 = (char *)KeyValues::GetName(local_25c);
                  pCVar14 = (CMatchExtL4D *)0x0;
                  this_04 = (KeyValues *)KeyValues::FindKey(this_03,pcVar11,false);
                  if (this_04 != (KeyValues *)0x0) {
                    local_244 = 0;
                    while( true ) {
                      iVar7 = local_244 + 1;
                      CFmtStrN<256>::CFmtStrN(local_12c,"%d",iVar7);
                      this_05 = (KeyValues *)KeyValues::FindKey(this_04,local_127,false);
                      if (this_05 == (KeyValues *)0x0) break;
                      pcVar11 = (char *)KeyValues::GetString(this_05,"map","");
                      if ((pcVar11 == (char *)0x0) || (*pcVar11 == '\0')) {
                    /* try { // try from 00036a73 to 00036b37 has its CatchHandler @ 00036b4c */
                        uVar5 = KeyValues::GetName(this_05);
                        uVar9 = KeyValues::GetName(local_25c);
                        Warning("MissionManager:  Mission file \"%s\" has invalid map specified for modes/%s/%s\n"
                                ,param_1,uVar9,uVar5);
                        goto LAB_00036aa6;
                      }
                      pcVar11 = (char *)KeyValues::GetString(this_05,"DisplayName","");
                      if ((pcVar11 == (char *)0x0) || (*pcVar11 == '\0')) {
                        uVar5 = KeyValues::GetName(this_05);
                        CFmtStrN<256>::CFmtStrN(local_12c,"%s-%s",pcVar12,uVar5);
                        KeyValues::SetString(this_05,"DisplayName",local_127);
                      }
                      pcVar11 = (char *)KeyValues::GetString(this_05,"image","");
                      if ((pcVar11 == (char *)0x0) || (*pcVar11 == '\0')) {
                        KeyValues::SetString(this_05,"image","maps/unknown");
                      }
                      KeyValues::SetInt(this_05,"chapter",iVar7);
                      local_244 = iVar7;
                    }
                    if (local_244 == 0) {
LAB_00036aa6:
                      KeyValues::RemoveSubKey(this_03,this_04);
                      if (this_03 != this_04) {
                        KeyValues::deleteThis();
                      }
                      pCVar14 = (CMatchExtL4D *)KeyValues::GetName(local_25c);
                      Warning("MissionManager:  Mission file \"%s\" has invalid settings for game mode %s\n"
                              ,param_1,pCVar14);
                    }
                    else {
                      iVar7 = _V_stricmp(pcVar12,"credits");
                      if (iVar7 != 0) {
                        iVar6 = KeyValues::GetInt(local_25c,"singlechapter",0);
                        iVar7 = 1;
                        if (iVar6 != 0) {
                          iVar7 = local_244;
                        }
                        iVar6 = KeyValues::GetInt(local_25c,"missions",0);
                        KeyValues::SetInt(local_25c,"missions",iVar6 + iVar7);
                      }
                      KeyValues::SetInt(this_04,"chapters",local_244);
                      pCVar14 = (CMatchExtL4D *)KeyValues::GetName(local_25c);
                      DevMsg("\t\tloaded %d %s chapters.\n",local_244,pCVar14);
                      local_26c = local_26c + 1;
                    }
                  }
                  local_25c = (KeyValues *)KeyValues::GetNextTrueSubKey(local_25c);
                } while (local_25c != (KeyValues *)0x0);
                if (local_26c != 0) {
                  puVar8 = (undefined4 *)CUtlStringMap<KeyValues*>::operator[]((char *)this_00);
                  *puVar8 = this_02;
                  puVar8 = (undefined4 *)
                           CUtlStringMap<KeyValues*>::operator[]((char *)(this + 0x54));
                  *puVar8 = this_02;
                  KeyValues::AddSubKey(this_01,this_02);
                    /* try { // try from 000369d1 to 00036a63 has its CatchHandler @ 00036b42 */
                  CFmtStrN<256>::CFmtStrN(local_12c,"missions/%s",pcVar12);
                  pKVar3 = (KeyValues *)KeyValues::GetFirstTrueSubKey(pKVar3);
                  for (; pKVar3 != (KeyValues *)0x0;
                      pKVar3 = (KeyValues *)KeyValues::GetNextTrueSubKey(pKVar3)) {
                    pcVar11 = (char *)KeyValues::GetName(pKVar3);
                    iVar7 = KeyValues::FindKey(this_03,pcVar11,false);
                    if (iVar7 != 0) {
                      KeyValues::SetPtr(pKVar3,local_127,this_02);
                    }
                  }
                  pcVar11 = "\tMission %s ver %s loaded %d game modes.\n";
                  DevMsg("\tMission %s ver %s loaded %d game modes.\n",pcVar12,pCVar13,local_26c);
                  goto LAB_0003612e;
                }
              }
              pcVar11 = 
              "MissionManager:  Mission file \"%s\" does not have valid data for any supported game mode\n"
              ;
              Warning("MissionManager:  Mission file \"%s\" does not have valid data for any supported game mode\n"
                      ,param_1,pCVar14,uVar5);
              pcVar12 = param_1;
              pCVar13 = pCVar14;
            }
            else {
              CUtlSymbolTable::AddString((char *)&local_23a);
              uVar10 = (uint)local_23a;
              iVar7 = *(int *)(this + 0x60);
              if (((iVar7 <= (int)uVar10) && (iVar7 < (int)(uVar10 + 1))) &&
                 (iVar6 = (uVar10 + 1) - iVar7, iVar6 != 0)) {
                CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>>::GrowVector
                          ((CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>> *)(this + 0x54),iVar6)
                ;
                CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>>::ShiftElementsRight
                          ((CUtlVector<KeyValues*,CUtlMemory<KeyValues*,int>> *)(this + 0x54),iVar7,
                           iVar6);
              }
              uVar5 = KeyValues::GetString
                                (*(KeyValues **)(*(int *)(this + 0x54) + uVar10 * 4),"CfgFile","");
              pcVar11 = 
              "MissionManager:  Duplicate mission \"%s\" in file \"%s\", already loaded from \"%s\".\n"
              ;
              Warning("MissionManager:  Duplicate mission \"%s\" in file \"%s\", already loaded from \"%s\".\n"
                      ,pcVar12,param_1,uVar5);
              pCVar13 = (CMatchExtL4D *)param_1;
            }
          }
        }
      }
LAB_00036250:
      if (this_02 != (KeyValues *)0x0) {
        KeyValues::deleteThis();
        pcVar11 = (char *)this_02;
      }
    }
  }
LAB_0003612e:
  if (local_20 != *(int *)(in_GS_OFFSET + 0x14)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail(pcVar11,pcVar12,pCVar13);
  }
  return;
}

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)