Cmd_Exec_f
0x00117d90 · 913 bytes · __cdecl
_Z10Cmd_Exec_fRK8CCommand
Decompiled
undefined (1 param)
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
/* Cmd_Exec_f(CCommand const&) */
void Cmd_Exec_f(CCommand *param_1)
{
uint uVar1;
char cVar2;
uint uVar3;
int iVar4;
char *pcVar5;
int iVar6;
char *pcVar7;
int in_GS_OFFSET;
bool bVar8;
char *local_212c;
int local_2128;
char local_2124 [260];
char local_2020 [8192];
int local_20;
local_20 = *(int *)(in_GS_OFFSET + 0x14);
uVar3 = ThreadGetCurrentId();
if (uVar3 == s_CommandBufferMutex) {
LAB_00117dca:
DAT_003887ec = DAT_003887ec + 1;
iVar4 = *(int *)param_1;
}
else {
LOCK();
bVar8 = s_CommandBufferMutex == 0;
uVar1 = uVar3;
if (!bVar8) {
uVar1 = s_CommandBufferMutex;
}
s_CommandBufferMutex = uVar1;
UNLOCK();
if (bVar8) goto LAB_00117dca;
CThreadFastMutex::Lock(0x3887e8,uVar3);
iVar4 = *(int *)param_1;
}
if (iVar4 < 2) {
/* try { // try from 00117f0c to 00118119 has its CatchHandler @ 0011811f */
ConMsg("exec <filename> [path id]: execute a script file\n");
}
else {
pcVar5 = *(char **)(param_1 + 0x40c);
pcVar7 = "*";
if (iVar4 != 2) {
pcVar7 = *(char **)(param_1 + 0x410);
}
/* try { // try from 00117e01 to 00117ed2 has its CatchHandler @ 0011811f */
iVar4 = _V_stricmp(pcVar7,"T");
if (iVar4 == 0) {
V_snprintf(local_2124,0x104,"T:/cfg/%s",pcVar5);
}
else {
V_snprintf(local_2124,0x104,"//%s/cfg/%s",pcVar7,pcVar5);
V_DefaultExtension(local_2124,".cfg",0x104);
cVar2 = COM_IsValidPath(local_2124);
if (cVar2 == '\0') {
ConMsg("exec %s: invalid path.\n",local_2124);
goto LAB_00117e7c;
}
}
cVar2 = IsValidFileExtension(local_2124);
if (cVar2 == '\0') {
ConMsg("exec %s: invalid file type.\n",local_2124);
}
else {
cVar2 = (**(code **)(*(int *)(g_pFileSystem + 4) + 0x28))(g_pFileSystem + 4,local_2124,0);
if ((cVar2 == '\0') ||
(uVar3 = (**(code **)(*(int *)(g_pFileSystem + 4) + 0x1c))(g_pFileSystem + 4,local_2124,0),
uVar3 < 0x100001)) {
pcVar7 = (char *)COM_LoadStackFile(local_2124,local_2020,0x2000,&local_2128,4);
local_212c = pcVar7;
if (pcVar7 == (char *)0x0) {
iVar4 = V_stristr(pcVar5,"autoexec.cfg");
if (((iVar4 == 0) && (iVar4 = V_stristr(pcVar5,"joystick.cfg"), iVar4 == 0)) &&
(iVar4 = V_stristr(pcVar5,"game.cfg"), iVar4 == 0)) {
Warning("exec: couldn\'t exec %s\n",pcVar5);
}
}
else {
(**(code **)(_g_pVCR + 0x38))(&local_212c);
if ((pcVar7 != local_2020) && (pcVar7 != local_212c)) {
free(pcVar7);
}
ConDMsg("execing %s\n",pcVar5);
iVar4 = CCommandBuffer::GetNextCommandHandle((CCommandBuffer *)s_CommandBuffer);
pcVar5 = local_212c;
while( true ) {
pcVar5 = (char *)COM_ParseLine(pcVar5);
iVar6 = _V_strlen(&com_token);
if (iVar6 < 1) break;
Cbuf_InsertText(0,&com_token,0);
while ((iVar6 = CCommandBuffer::GetNextCommandHandle((CCommandBuffer *)s_CommandBuffer),
iVar4 != iVar6 &&
(cVar2 = CCommandBuffer::DequeueNextCommand((CCommandBuffer *)s_CommandBuffer),
cVar2 != '\0'))) {
Cbuf_ExecuteCommand(0,0x38a84c);
}
}
if ((local_212c != local_2020) && (pcVar7 == local_212c)) {
free(pcVar7);
}
}
}
else {
Warning("exec %s: file size larger than 1 MB!\n",pcVar5);
}
}
}
LAB_00117e7c:
DAT_003887ec = DAT_003887ec + -1;
if (DAT_003887ec == 0) {
LOCK();
UNLOCK();
s_CommandBufferMutex = 0;
}
if (local_20 == *(int *)(in_GS_OFFSET + 0x14)) {
return;
}
/* 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.