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 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.