L L4D2node

CNetChan::SendDatagram

0x001b37f0 · 3113 bytes · __thiscall

_ZN8CNetChan12SendDatagramEP8bf_write

Decompiled

undefined (2 params)

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* CNetChan::SendDatagram(bf_write*) */

int __thiscall CNetChan::SendDatagram(CNetChan *this,bf_write *param_1)

{
  netadr_s *this_00;
  bool bVar1;
  char cVar2;
  int *piVar3;
  int iVar4;
  int iVar5;
  int iVar6;
  uint uVar7;
  undefined4 uVar8;
  undefined4 uVar9;
  byte bVar10;
  int iVar11;
  uint uVar12;
  uchar *puVar13;
  char *pcVar14;
  int in_GS_OFFSET;
  byte bVar15;
  double dVar16;
  double dVar17;
  longlong lVar18;
  uint local_15c;
  uint local_130;
  undefined4 local_12c;
  undefined4 local_128;
  undefined4 local_120;
  undefined4 local_11c;
  int *local_118;
  uchar *local_114;
  undefined4 local_110;
  uint local_10c;
  uint local_108;
  undefined4 local_104;
  undefined4 local_100;
  uchar *local_fc;
  undefined4 local_f8;
  uint local_f4;
  uint local_f0;
  undefined4 local_ec;
  undefined4 local_e8;
  undefined4 local_e4;
  char local_e0 [64];
  char local_a0 [128];
  int local_20;
  
  bVar15 = 0;
  local_12c = 0;
  local_20 = *(int *)(in_GS_OFFSET + 0x14);
  local_128 = 0;
  if (_exit == (int *)0x0) {
    local_118 = (int *)0x0;
  }
  else {
    (*(code *)_exit[0x14])
              (_exit,&local_12c,0,0,0,0,"/data/src/engine/./net_chan.cpp",0x85a,
               &SendDatagram(bf_write*)::tm_fmt,"(%s)%s","Unaccounted","CNetChan::SendDatagram");
    local_118 = _exit;
  }
  iVar4 = _DAT_0040b9d4;
  local_120 = local_12c;
  local_11c = local_128;
                    /* try { // try from 001b3a26 to 001b3a74 has its CatchHandler @ 001b449b */
  if (((_DAT_0040b028 != 0) || (DAT_0040b02c == '\0')) &&
     (iVar5 = ThreadGetCurrentId(), iVar4 == iVar5)) {
    if ((char *)*_DAT_0040b030 != "CNetChan::SendDatagram") {
      _DAT_0040b030 =
           (int *)CVProfNode::GetSubNode((char *)_DAT_0040b030,0x2bb109,&DAT_00000001,0x2a054b);
    }
    CVProfNode::EnterScope();
    DAT_0040b02c = '\0';
  }
                    /* try { // try from 001b38cc to 001b38d0 has its CatchHandler @ 001b4497 */
  piVar3 = (int *)NET_AllocMessageBuffer();
  if (((*(int *)(vcr_verbose._28_4_ + 0x30) != 0) && (param_1 != (bf_write *)0x0)) &&
     (iVar4 = *(int *)(param_1 + 0xc) + 7 >> 3, 0 < iVar4)) {
                    /* try { // try from 001b390d to 001b3990 has its CatchHandler @ 001b4465 */
    (**(code **)(_g_pVCR + 0x90))("datagram",*(undefined4 *)param_1,iVar4 + -1);
  }
  if ((*(int *)(this + 0x8c) == 0) &&
     (iVar4 = *(int *)(net_maxroutable._28_4_ + 0x30),
     iVar5 = (**(code **)(*(int *)this + 0x11c))(this), iVar5 != iVar4)) {
    (**(code **)(*(int *)this + 0x118))(this,*(undefined4 *)(net_maxroutable._28_4_ + 0x30));
  }
  this_00 = (netadr_s *)(this + 0x98);
  iVar4 = netadr_s::GetType(this_00);
  if (iVar4 == 0) {
    *(undefined4 *)(this + 0x1c) = 0;
    *(undefined8 *)(this + 0xb4) = 0;
    bf_write::Reset((bf_write *)(this + 0x20));
    bf_write::Reset((bf_write *)(this + 0x44));
  }
  else {
                    /* try { // try from 001b3ad3 to 001b4443 has its CatchHandler @ 001b4465 */
    SplitUserCombineForSending(this);
    if (this[0x30] != (CNetChan)0x0) {
      uVar8 = netadr_s::ToString(this_00,false);
      ConMsg("%s:send reliable stream overflow\n",uVar8);
      iVar4 = 0;
      goto LAB_001b399a;
    }
    if (0 < *(int *)(this + 0x2c)) {
      CreateFragmentsFromBuffer(this,(bf_write *)(this + 0x20),0);
      bf_write::Reset((bf_write *)(this + 0x20));
    }
    bf_write::bf_write((bf_write *)&local_114,"CNetChan_TransmitBits->send",piVar3,0x37ab0,-1);
    bf_write::WriteLong((bf_write *)&local_114,*(long *)(this + 8));
    bf_write::WriteLong((bf_write *)&local_114,*(long *)(this + 0xc));
    local_fc = local_114;
    local_f8 = local_110;
    local_f4 = local_10c;
    local_f0 = local_108;
    local_ec = local_104;
    local_e8 = local_100;
    bf_write::WriteByte((bf_write *)&local_114,0);
    cVar2 = NET_IsMultiplayer();
    if (cVar2 != '\0') {
      bf_write::WriteShort((bf_write *)&local_114,0);
    }
    uVar7 = local_108;
    bf_write::WriteByte((bf_write *)&local_114,*(uint *)(this + 0x18));
    if ((int)*(uint *)(this + 0x1c) < 1) {
      local_15c._0_1_ = 0;
    }
    else {
      bf_write::WriteByte((bf_write *)&local_114,*(uint *)(this + 0x1c) & 0xff);
      local_15c._0_1_ = 0x10;
    }
    cVar2 = SendSubChannelData(this,(bf_write *)&local_114);
    bVar10 = (byte)local_15c;
    if (cVar2 != '\0') {
      bVar10 = (byte)local_15c | 1;
    }
    local_15c = (uint)bVar10;
    if (param_1 != (bf_write *)0x0) {
      if (*(int *)(param_1 + 0xc) < (int)(local_10c - local_108)) {
        bf_write::WriteBits((bf_write *)&local_114,*(void **)param_1,*(int *)(param_1 + 0xc));
      }
      else {
        ConDMsg("CNetChan::SendDatagram:  data would overfow, ignoring\n");
      }
    }
    if (*(int *)(this + 0x50) < (int)(local_10c - local_108)) {
      bf_write::WriteBits((bf_write *)&local_114,*(void **)(this + 0x44),*(int *)(this + 0x50));
    }
    else {
      ConDMsg("CNetChan::SendDatagram:  Unreliable would overfow, ignoring\n");
    }
    bf_write::Reset((bf_write *)(this + 0x44));
    iVar4 = *(int *)(this + 0x74);
    if ((0 < iVar4) && (iVar4 < (int)(local_10c - local_108))) {
      bf_write::WriteBits((bf_write *)&local_114,*(void **)(this + 0x68),iVar4);
      bf_write::Reset((bf_write *)(this + 0x68));
    }
    if (*(int *)(this + 0x8c) == 1) {
      iVar4 = *(int *)(net_minroutable._28_4_ + 0x30);
    }
    else {
      iVar4 = 0x10;
    }
    while ((int)(local_108 + 7) >> 3 < iVar4) {
      while ((int)(local_108 + 6) <= (int)local_10c) {
        iVar5 = ((int)local_108 >> 5) * 4;
        *(uint *)(local_114 + iVar5) =
             *(uint *)(local_114 + iVar5) & *(uint *)(&DAT_003f2db8 + (local_108 & 0x1f) * 0x84);
        iVar6 = 0x20 - (local_108 & 0x1f);
        if (iVar6 < 6) {
          *(uint *)(local_114 + iVar5 + 4) =
               *(uint *)(local_114 + iVar5 + 4) & (&g_BitWriteMasks)[6 - iVar6];
        }
        uVar12 = local_108 + 6;
        iVar5 = local_108 + 0xd;
        local_108 = uVar12;
        if (iVar4 <= iVar5 >> 3) goto LAB_001b3d43;
      }
      local_104 = CONCAT31(local_104._1_3_,1);
      local_108 = local_10c;
    }
LAB_001b3d43:
    iVar4 = (int)local_108 % 8;
    if (iVar4 - 1U < 2) {
      if ((int)local_10c < (int)(local_108 + 6)) {
        local_108 = local_10c;
        local_104 = CONCAT31(local_104._1_3_,1);
      }
      else {
        iVar4 = ((int)local_108 >> 5) * 4;
        *(uint *)(local_114 + iVar4) =
             *(uint *)(local_114 + iVar4) & *(uint *)(&DAT_003f2db8 + (local_108 & 0x1f) * 0x84);
        iVar5 = 0x20 - (local_108 & 0x1f);
        if (iVar5 < 6) {
          *(uint *)(local_114 + iVar4 + 4) =
               *(uint *)(local_114 + iVar4 + 4) & (&g_BitWriteMasks)[6 - iVar5];
        }
        local_108 = local_108 + 6;
      }
      iVar4 = (int)local_108 % 8;
    }
    if (0 < iVar4) {
      iVar4 = 8 - iVar4;
      iVar5 = (&GetBitForBitnum(int)::bitsForBitnum)[iVar4];
      local_15c = (uint)(byte)(bVar10 | (char)iVar4 * ' ');
      if ((int)local_10c < (int)(iVar4 + local_108)) {
        local_108 = local_10c;
        local_104 = CONCAT31(local_104._1_3_,1);
      }
      else {
        uVar12 = local_108 & 0x1f;
        iVar6 = ((int)local_108 >> 5) * 4;
        iVar11 = 0x20 - uVar12;
        *(uint *)(local_114 + iVar6) =
             *(uint *)(local_114 + iVar6) & (&g_BitWriteMasks)[uVar12 * 0x21 + iVar4] |
             iVar5 - 1U << (sbyte)uVar12;
        if (iVar11 < iVar4) {
          *(uint *)(local_114 + iVar6 + 4) =
               (&g_BitWriteMasks)[iVar4 - iVar11] & *(uint *)(local_114 + iVar6 + 4) |
               iVar5 - 1U >> ((byte)iVar11 & 0x1f);
        }
        local_108 = local_108 + iVar4;
      }
    }
    bVar1 = false;
    if (*(int *)(net_compresspackets._28_4_ + 0x30) != 0) {
      bVar1 = *(int *)(net_compresspackets_minsize._28_4_ + 0x30) <= (int)(local_108 + 7) >> 3;
    }
    bf_write::WriteByte((bf_write *)&local_fc,local_15c);
    cVar2 = NET_IsMultiplayer();
    if (cVar2 != '\0') {
      iVar5 = (int)(uVar7 + 7) >> 3;
      puVar13 = local_114 + iVar5;
      iVar4 = local_108 + 7;
      CRC32_Init(&local_130);
      CRC32_ProcessBuffer(&local_130,puVar13,(iVar4 >> 3) - iVar5);
      CRC32_Final(&local_130);
      if ((int)local_f4 < (int)(local_f0 + 0x10)) {
        local_f0 = local_f4;
        local_ec = CONCAT31(local_ec._1_3_,1);
      }
      else {
        iVar5 = ((int)local_f0 >> 5) * 4;
        uVar12 = local_f0 & 0x1f;
        uVar7 = (local_130 ^ local_130 >> 0x10) & 0xffff;
        *(uint *)(local_fc + iVar5) =
             *(uint *)(local_fc + iVar5) & *(uint *)(&DAT_003f2de0 + uVar12 * 0x84) |
             uVar7 << (sbyte)uVar12;
        iVar4 = 0x20 - uVar12;
        if (iVar4 < 0x10) {
          *(uint *)(local_fc + iVar5 + 4) =
               (&g_BitWriteMasks)[0x10 - iVar4] & *(uint *)(local_fc + iVar5 + 4) |
               uVar7 >> ((byte)iVar4 & 0x1f);
        }
        local_f0 = local_f0 + 0x10;
      }
    }
    iVar4 = NET_SendPacket((INetChannel *)this,*(int *)(this + 0x8c),this_00,local_114,
                           (int)(local_108 + 7) >> 3,(bf_write *)0x0,bVar1,0);
    bf_write::Reset((bf_write *)(this + 0x68));
    if (((*(uint *)(net_showudp._28_4_ + 0x30) & 0xfffffffd) != 0) &&
       ((*(int *)(net_showudp_remoteonly._28_4_ + 0x30) == 0 ||
        ((cVar2 = netadr_s::IsLocalhost(this_00), cVar2 == '\0' &&
         (cVar2 = netadr_s::IsLoopback(this_00), cVar2 == '\0')))))) {
      pcVar14 = local_e0;
      for (iVar5 = 0x10; iVar5 != 0; iVar5 = iVar5 + -1) {
        pcVar14[0] = '\0';
        pcVar14[1] = '\0';
        pcVar14[2] = '\0';
        pcVar14[3] = '\0';
        pcVar14 = pcVar14 + ((uint)bVar15 * -2 + 1) * 4;
      }
      if (((*(int *)(net_compresspackets._28_4_ + 0x30) != 0) && (iVar4 != 0)) &&
         (iVar5 = (int)(local_108 + 7) >> 3, iVar4 < iVar5)) {
        V_snprintf(local_e0,0x40," compression=%5u [%5.2f %%]",iVar4,
                   (double)(((float)iVar4 * 100.0) / (float)iVar5));
      }
      lVar18 = (**(code **)(*(int *)g_pSteamSocketMgr + 0x1c))(g_pSteamSocketMgr,this_00);
      local_e4 = 0xffffc800;
      if (lVar18 == 0) {
        uVar8 = netadr_s::ToString(this_00,false);
        uVar9 = (*(code *)**(undefined4 **)this)(this);
        V_snprintf(local_a0,0x80,"%12.12s %21.21s",uVar9,uVar8);
      }
      else {
        local_e4 = 0xff64ffff;
        uVar8 = netadr_s::ToString(this_00,false);
        uVar9 = (*(code *)**(undefined4 **)this)(this);
        V_snprintf(local_a0,0x80,"%12.12s %21.21s s(%llx)",uVar9,uVar8,(int)lVar18,
                   (int)((ulonglong)lVar18 >> 0x20));
      }
      ConColorMsg((Color *)&local_e4,"UDP -> %s: sz=%5i seq=%5i ack=%5i rel=%1i tm=%8.3f%s\n",
                  local_a0,(int)(local_108 + 7) >> 3,*(uint *)(this + 8) & 0x3f,
                  *(uint *)(this + 0xc) & 0x3f,local_15c & 1,(double)(float)net_time,local_e0);
    }
    iVar4 = iVar4 + 0x1c;
    FlowNewPacket(this,0,*(int *)(this + 8),*(int *)(this + 0xc),*(int *)(this + 0x1c),0,iVar4);
    FlowUpdate(this,0,iVar4);
    dVar17 = net_time;
    uVar8 = net_maxcleartime._28_4_;
    dVar16 = *(double *)(this + 0xb4);
    if (*(double *)(this + 0xb4) <= net_time) {
      dVar16 = net_time;
    }
    dVar16 = dVar16 + (double)((float)iVar4 / (float)*(int *)(this + 0xb0));
    *(double *)(this + 0xb4) = dVar16;
    if ((0.0 < *(float *)(uVar8 + 0x2c)) &&
       (dVar17 = (double)*(float *)(uVar8 + 0x2c) + dVar17, dVar17 < dVar16)) {
      *(double *)(this + 0xb4) = dVar17;
    }
    *(undefined4 *)(this + 0x1c) = 0;
  }
  iVar4 = *(int *)(this + 8);
  *(int *)(this + 8) = iVar4 + 1;
LAB_001b399a:
  NET_AllocMessageBuffer((uchar *)piVar3);
  iVar5 = _DAT_0040b9d4;
  if (((DAT_0040b02c == '\0') || (_DAT_0040b028 != 0)) &&
     (iVar6 = ThreadGetCurrentId(), iVar5 == iVar6)) {
    piVar3 = _DAT_0040b030;
    cVar2 = CVProfNode::ExitScope();
    if (cVar2 != '\0') {
      _DAT_0040b030 = (int *)_DAT_0040b030[0x19];
    }
    DAT_0040b02c = _DAT_0040b030 == (int *)0x40b034;
  }
  if (local_118 != (int *)0x0) {
    piVar3 = local_118;
    (*(code *)local_118[0x15])(local_118,local_120,local_11c,0,0,0);
  }
  if (local_20 != *(int *)(in_GS_OFFSET + 0x14)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail(piVar3);
  }
  return iVar4;
}

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)