CHLTVServer::DispatchToRelay
0x00170560 · 1055 bytes · __thiscall
_ZN11CHLTVServer15DispatchToRelayEP11CHLTVClient
Decompiled
undefined (2 params)
/* CHLTVServer::DispatchToRelay(CHLTVClient*) */
undefined4 __thiscall CHLTVServer::DispatchToRelay(CHLTVServer *this,CHLTVClient *param_1)
{
CHLTVServer *pCVar1;
CHLTVClient *pCVar2;
code *pcVar3;
char cVar4;
int iVar5;
char *pcVar6;
int iVar7;
int *piVar8;
netadr_s *this_00;
undefined4 uVar9;
int iVar10;
int in_GS_OFFSET;
float fVar11;
float local_b30;
CHLTVClient *local_b28;
undefined **local_b14;
undefined1 local_b10;
undefined4 local_b0c;
undefined4 local_b08;
undefined4 local_b04;
undefined8 local_b00;
undefined4 local_af8;
undefined4 local_af4;
undefined8 local_af0;
undefined4 local_ae8;
undefined4 local_ae4;
undefined1 local_ae0;
undefined8 local_adc;
undefined4 local_ad4;
undefined4 local_ad0;
undefined4 local_ac8;
undefined **local_6c4;
undefined1 local_6c0;
undefined4 local_6bc;
undefined4 local_6b8;
undefined4 local_6b4;
undefined8 local_6b0;
undefined4 local_6a8;
undefined4 local_6a4;
undefined8 local_6a0;
undefined4 local_698;
undefined4 local_694;
undefined1 local_690;
undefined8 local_68c;
undefined4 local_684;
undefined4 local_680;
int local_20;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
if (0 < *(int *)(tv_dispatchmode._28_4_ + 0x30)) {
local_b30 = 1.0;
pCVar1 = this + 4;
iVar10 = 0;
local_b28 = (CHLTVClient *)0x0;
while( true ) {
iVar5 = (**(code **)(*(int *)(this + 4) + 0x20))(pCVar1);
if (iVar5 <= iVar10) break;
pCVar2 = *(CHLTVClient **)(*(int *)(this + 0x118) + iVar10 * 4);
cVar4 = (**(code **)(*(int *)pCVar2 + 0x6c))(pCVar2);
if (cVar4 != '\0') {
cVar4 = (**(code **)(*(int *)pCVar2 + 0x7c))(pCVar2);
if ((cVar4 != '\0') && (param_1 != pCVar2)) {
pcVar6 = (char *)(**(code **)(*(int *)pCVar2 + 0x28))(pCVar2,"hltv_slots");
iVar5 = V_atoi(pcVar6);
pcVar6 = (char *)(**(code **)(*(int *)pCVar2 + 0x28))(pCVar2,"hltv_clients");
iVar7 = V_atoi(pcVar6);
if ((0 < iVar5) && (iVar7 <= iVar5)) {
if ((float)iVar7 / (float)iVar5 < local_b30) {
local_b30 = (float)iVar7 / (float)iVar5;
local_b28 = pCVar2;
}
}
}
}
iVar10 = iVar10 + 1;
}
if (local_b28 == (CHLTVClient *)0x0) {
if (*(int *)(tv_dispatchmode._28_4_ + 0x30) == 2) {
(**(code **)(*(int *)param_1 + 0x3c))(param_1,"No SourceTV relay available");
uVar9 = 1;
goto LAB_001708dd;
}
}
else {
if (*(int *)(tv_dispatchmode._28_4_ + 0x30) == 1) {
iVar10 = (**(code **)(*(int *)(this + 4) + 0x18))(pCVar1);
if (0 < iVar10) {
iVar10 = (**(code **)(*(int *)(this + 4) + 0xc))(pCVar1);
iVar5 = (**(code **)(*(int *)(this + 4) + 0x18))(pCVar1);
fVar11 = ((float)iVar10 / (float)iVar5) * 1.25;
if (1.0 <= fVar11) {
fVar11 = 1.0;
}
if (fVar11 < local_b30) {
uVar9 = 0;
goto LAB_001708dd;
}
}
}
iVar10 = (**(code **)(*(int *)local_b28 + 0x28))(local_b28,"hltv_addr");
if (iVar10 != 0) {
piVar8 = (int *)(**(code **)(*(int *)param_1 + 0x20))(param_1);
this_00 = (netadr_s *)(**(code **)(*piVar8 + 200))(piVar8);
uVar9 = netadr_s::ToString(this_00,false);
ConMsg("Redirecting spectator %s to SourceTV relay %s\n",uVar9,iVar10);
local_6b0 = 0;
local_6a0 = 0;
local_68c = 0;
local_6b8 = 0;
local_6b4 = 0;
local_6a8 = 0;
local_6a4 = 0;
local_698 = 0;
local_694 = 0;
local_690 = 0;
local_684 = 0;
local_680 = 0;
local_6c0 = 1;
local_6bc = 0;
local_6c4 = &PTR__SVC_ServerInfo_002a1828;
(**(code **)(*(int *)this + 0x24))(this,&local_6c4);
(**(code **)(*(int *)param_1 + 100))(param_1,&local_6c4,1,0);
local_ac8 = va("connect %s\n",iVar10);
local_b00 = 0;
local_af0 = 0;
local_adc = 0;
local_b08 = 0;
local_b04 = 0;
local_af8 = 0;
local_af4 = 0;
local_ae8 = 0;
local_ae4 = 0;
local_ae0 = 0;
local_ad4 = 0;
local_ad0 = 0;
local_b10 = 1;
local_b0c = 0;
local_b14 = &PTR__NET_StringCmd_002a17c8;
(**(code **)(*(int *)param_1 + 100))(param_1,&local_b14,1,0);
pcVar6 = (char *)(**(code **)(*(int *)local_b28 + 0x28))(local_b28,"hltv_clients");
iVar10 = V_atoi(pcVar6);
pcVar3 = *(code **)(*(int *)local_b28 + 0xfc);
uVar9 = va("%d",iVar10 + 1);
(*pcVar3)(local_b28,"hltv_clients",uVar9);
uVar9 = 1;
goto LAB_001708dd;
}
}
}
uVar9 = 0;
LAB_001708dd:
if (local_20 == *(int *)(in_GS_OFFSET + 0x14)) {
return uVar9;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
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.