L L4D2node

SvTagsChangeCallback

0x0010eec0 · 1027 bytes · __cdecl

_ZL20SvTagsChangeCallbackP7IConVarPKcf

Decompiled

undefined (3 params)

/* SvTagsChangeCallback(IConVar*, char const*, float) */

void SvTagsChangeCallback(IConVar *param_1,char *param_2,float param_3)

{
  undefined4 uVar1;
  char cVar2;
  char *pcVar3;
  int iVar4;
  int iVar5;
  undefined4 *puVar6;
  int in_GS_OFFSET;
  CUtlMemory<char*,int> *local_c8;
  int local_c4;
  int local_c0;
  undefined4 *local_bc;
  int local_b8;
  void *local_b4;
  undefined4 local_b0;
  undefined4 local_ac;
  size_t local_a8;
  void *local_a4;
  char local_a0 [128];
  int local_20;
  
  local_20 = *(int *)(in_GS_OFFSET + 0x14);
  CBaseServer::UpdateGameType((CBaseServer *)&sv);
  if (1 < DAT_003b7f64) {
    Cbuf_AddText(4,"heartbeat\n",0);
  }
  if (ServerTagsCleanUp()::s_nNoReentry != 0) goto LAB_0010ef12;
  ServerTagsCleanUp()::s_nNoReentry = 1;
  local_b4 = (void *)0x0;
  local_b0 = 0;
  local_ac = 0;
  local_a8 = 0;
  local_a4 = (void *)0x0;
                    /* try { // try from 0010ef86 to 0010f293 has its CatchHandler @ 0010f2ca */
  ConVarRef::ConVarRef((ConVarRef *)&local_bc,"sv_tags");
  cVar2 = ConVarRef::IsValid((ConVarRef *)&local_bc);
  if (cVar2 != '\0') {
    local_a0[0] = '\0';
    V_SplitString(*(char **)(local_b8 + 0x24),",",(CUtlVector *)&local_b4);
    if (0 < (int)local_a8) {
      iVar5 = 0;
LAB_0010eff8:
      pcVar3 = *(char **)((int)local_b4 + iVar5 * 4);
      cVar2 = *pcVar3;
      while (cVar2 == ' ') {
        pcVar3 = pcVar3 + 1;
        cVar2 = *pcVar3;
      }
      if (cVar2 == '\0') {
        if ((int)local_a8 <= iVar5 + 1) goto LAB_0010f0cd;
      }
      else {
        V_strncat(local_a0,pcVar3,0x80,-1);
        if ((int)local_a8 <= iVar5 + 1) goto LAB_0010f0cd;
      }
      iVar5 = iVar5 + 1;
      if (0 < iVar5) {
        V_strncat(local_a0,",",0x80,-1);
      }
      goto LAB_0010eff8;
    }
    goto LAB_0010f0f4;
  }
  goto LAB_0010f066;
LAB_0010f0cd:
  iVar5 = 0;
  if (0 < (int)local_a8) {
    do {
      iVar4 = iVar5 * 4;
      iVar5 = iVar5 + 1;
      operator_delete(*(void **)((int)local_b4 + iVar4));
    } while (iVar5 < (int)local_a8);
  }
LAB_0010f0f4:
  local_c8 = (CUtlMemory<char*,int> *)&local_b4;
  local_a8 = 0;
  CUtlMemory<char*,int>::Purge(local_c8);
  local_a4 = local_b4;
  V_SplitString(local_a0,",",(CUtlVector *)local_c8);
  if (1 < (int)local_a8) {
    if (local_b4 == (void *)0x0) {
      local_c4 = local_a8 - 1;
      do {
        if (0 < local_c4) {
          local_c0 = 0;
          iVar5 = 1;
          do {
            iVar4 = SortServerTags((char **)((int)local_b4 + local_c0),
                                   (char **)((int)local_b4 + iVar5 * 4));
            if (iVar4 < 0) {
              puVar6 = (undefined4 *)(iVar5 * 4 + (int)local_b4);
              uVar1 = *(undefined4 *)((int)local_b4 + local_c0);
              *(undefined4 *)((int)local_b4 + local_c0) = *puVar6;
              *puVar6 = uVar1;
            }
            local_c0 = local_c0 + 4;
            iVar5 = iVar5 + 1;
          } while (iVar5 <= local_c4);
        }
        local_c4 = local_c4 + -1;
      } while (local_c4 != -1);
    }
    else {
      qsort(local_b4,local_a8,4,SortServerTags);
    }
  }
  local_c8 = (CUtlMemory<char*,int> *)&local_b4;
  iVar5 = 0;
  local_a0[0] = '\0';
  if (0 < (int)local_a8) {
    while( true ) {
      V_strncat(local_a0,*(char **)((int)local_b4 + iVar5 * 4),0x80,-1);
      iVar5 = iVar5 + 1;
      if ((int)local_a8 <= iVar5) break;
      if (0 < iVar5) {
        V_strncat(local_a0,",",0x80,-1);
      }
    }
  }
  (**(code **)*local_bc)(local_bc,local_a0);
  iVar5 = 0;
  if (0 < (int)local_a8) {
    do {
      iVar4 = iVar5 * 4;
      iVar5 = iVar5 + 1;
      operator_delete(*(void **)((int)local_b4 + iVar4));
    } while (iVar5 < (int)local_a8);
  }
  local_a8 = 0;
  CUtlMemory<char*,int>::Purge(local_c8);
  local_a4 = local_b4;
LAB_0010f066:
  local_c8 = (CUtlMemory<char*,int> *)&local_b4;
  local_a8 = 0;
  CUtlMemory<char*,int>::Purge(local_c8);
  local_a4 = local_b4;
  CUtlMemory<char*,int>::Purge(local_c8);
  ServerTagsCleanUp()::s_nNoReentry = ServerTagsCleanUp()::s_nNoReentry + -1;
LAB_0010ef12:
  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)