如何一次运行3个函数?

How to run 3 functions at once?

本文关键字:函数 3个 运行 何一次      更新时间:2023-10-16

我有一个名为"一切"的项目,里面有 3 个源文件,"发光"、"雷达"、"触发器"。在里面,每一个都有一个功能(int glow {code}, int radar {code}, int trigger {code}(。我知道我需要一个 main 函数来成功调试应用程序。但问题是:如果您将所有 3 个函数都设置为"int main"——您无法调试(我也知道这一点(。如果我将.cpp文件中一个函数的名称设置为"int main",则只能调试该函数,其余的.cpp文件根本不起作用,它们被编译,但没有任何其他反应。 所以我想,也许我应该制作另一个.cpp文件,叫做main.cpp。然后我想,也许将其他源文件包含到这个主文件中会起作用。在这个"主.cpp"文件中,如果我这样做

#include "glow.cpp"
#include "radar.cpp"
#include "trigger.cpp"

int main()
{
glow();
radar();
trigger();
} 

并编译,只有发光函数被渲染。我不明白我该怎么办,我不希望同时打开 3 个控制台应用程序,以便每个功能都可以正常工作。


下面我将列出每个源代码。

发光.cpp

#include "ProcMem.h"
#include "csgo.hpp"
#include <ctime>
#include <chrono>
#include <iostream>
using namespace std;
using namespace hazedumper;
using namespace netvars;
using namespace signatures;

ProcMem GZUZ;
DWORD clientDll;
DWORD localPly;
const DWORD TO = 0xF4;
const DWORD HP = 0x100;
const DWORD ELD = 0x10;

int glow()
{
char proc[9] = "csgo.exe";
char module[20] = "client_panorama.dll";
GZUZ.Process(proc);
clientDll = GZUZ.Module(module);
do
{
localPly = GZUZ.Read<DWORD>(clientDll + dwLocalPlayer);
} while (localPly == NULL);
DWORD glowObj = GZUZ.Read<DWORD>(clientDll + dwGlowObjectManager);
while (true)
{
localPly = GZUZ.Read<DWORD>(clientDll + dwLocalPlayer);
int myTeam = GZUZ.Read<int>(localPly + TO);
for (short int i = 0; i < 64; i++)
{
DWORD entity = GZUZ.Read<DWORD>(clientDll + dwEntityList + i * 0x10);
if (entity != NULL)
{
int GIDX = GZUZ.Read<int>(entity + m_iGlowIndex);
int entityTeam = GZUZ.Read<int>(entity + TO);
int entityHP = GZUZ.Read<int>(entity + HP);
if (entityTeam != myTeam)
{
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x4), 0.5);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x8), 1.6);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0xC), 1.8);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x10), 0.5);
}
else
{
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x4), 0);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x8), 0);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0xC), 0);
GZUZ.Write<float>(glowObj + ((GIDX * 0x38) + 0x10), 0);
}
GZUZ.Write<bool>(glowObj + ((GIDX * 0x38) + 0x24), true);
GZUZ.Write<bool>(glowObj + ((GIDX * 0x38) + 0x25), false);
}
}
Sleep(1);
}
}

雷达.cpp

#include "ProcMem.h"
#include "csgo.hpp"
#include <ctime>
#include <chrono>
#include <iostream>
using namespace std;
using namespace hazedumper;
using namespace netvars;
using namespace signatures;
ProcMem mem;

int radar() {
char proc[9] = "csgo.exe";
char module[20] = "client_panorama.dll";
mem.Process(proc);
DWORD gameModule = mem.Module(module);
while (true) {
for (short int i = 0; i < 64; i++) { //checks for every available entity, 0 is local player
DWORD entity = mem.Read<DWORD>(gameModule + dwEntityList + i * 0x10); 
if (entity != NULL)
{
mem.Write(entity + m_bSpotted, true);
}
}
Sleep(50);
}
}

触发器.cpp

#include "ProcMem.h"
#include "csgo.hpp"
#include <ctime>
#include <chrono>
#include <iostream>
using namespace std;
using namespace hazedumper;
using namespace netvars;
using namespace signatures;
void Shoot();

ProcMem LX;
DWORD cDll;
DWORD lPly;
const DWORD teamOffs = 0xF4;
const DWORD health = 0x100;
const DWORD entLoopDist = 0x10;
int trigger()
{
char proc[9] = "csgo.exe";
char module[20] = "client_panorama.dll";
LX.Process(proc);
cDll = LX.Module(module);
lPly = LX.Read<DWORD>(cDll + dwLocalPlayer);
while (true)
{
Shoot();
Sleep(1);
}
}
void Shoot()
{
DWORD activeWeapon = LX.Read<DWORD>(lPly + m_hActiveWeapon); 
DWORD entNum = activeWeapon & 0xFFF;
DWORD wID = LX.Read<DWORD>(cDll + dwEntityList + (entNum - 1) * entLoopDist); 
int mywID = LX.Read<int>(wID + m_iItemDefinitionIndex); //checks for the weapon we are using 
bool isScoped = LX.Read<bool>(lPly + m_bIsScoped); //if we are scoped
int myTeam = LX.Read<int>(lPly + teamOffs); //checks for our team
int xhairEnt = LX.Read<int>(lPly + m_iCrosshairId); //checks to see if we're hovering over somebody
DWORD entity = LX.Read<DWORD>(cDll + dwEntityList + (xhairEnt - 1) * entLoopDist); //checks for the available entities using client dll
int enemyHP = LX.Read<int>(entity + health); // checks for enemy hp
int enemyTeam = LX.Read<int>(entity + teamOffs); // checks for enemy team
if (GetKeyState(VK_MENU) && enemyTeam != myTeam && enemyHP > 0) // &0x8000 checks if alt is still pressed 
{
bool weapon = (mywID == 9) || (mywID == 40) || (mywID == 38) || (mywID == 11);
if ((weapon&&isScoped) || !weapon)
{
Sleep(0.35);
LX.Write<int>(cDll + dwForceAttack, 5);
Sleep(50);
LX.Write<int>(cDll + dwForceAttack, 4);
Sleep(350);     
}
}
}

PS::如果你想知道为什么我在一个源文件中使用 GZUZ 读写内存,在另一个源文件中使用 LX 和在另一个源文件中使用 Mem 我只是不能全部使用 Mem,这只是我当时想出的解决方案。我将尝试再次将每一行代码放入一个大的源文件中并进行编译(这听起来很疯狂,因为我在做同样的事情时期待不同的结果(。

当你这样做时:

int main()
{
glow();
radar();
trigger();
} 

这三个函数将依次运行。

问题在于,你把每个函数都设计成永远在无限循环中运行,所以辉光永远不会结束,雷达和触发器从来没有机会运行。

这里有两种方法可以采取。首先,您可以在多个 ghreads 中运行,这允许您并行运行多个执行线程,而无需修改现有代码。这是一种相当简单直接的方法,无需太多修改即可重用现有代码,但是如果您需要函数实际相互交互或修改共享数据,您现在必须处理多线程代码、竞争条件、锁定、同步、死锁以及多线程的所有怪癖, 如果你不小心,这可能很难使用。

另一种方法是,您可以重写函数,以便它们轮流运行,而不是在无限循环中运行函数。

因此,如果您从具有如下所示函数的程序开始:

void funcA() {
context contextA;
while (true) {
doA(&contextA);
}
}
void funcB() {
context contextB;
while (true) {
doB(&contextB);
}
}

重写它,以便它们共享一个循环:

int main()
{
context contextA;
context contextB;
while (true) {
doA(&contextA);
doB(&contextB);
}
} 

此循环将在单个线程中运行所有函数,但它们将轮流运行,而不是自己占用整个线程。请注意,您应该避免在函数中执行 sleep(( 之类的操作,因为这也会阻止所有其他函数。

相反,您需要重写这些睡眠以将控制权交还给 main 函数,并重新安排回调以继续执行,以便在睡眠应该过期的某个时间后调用。可以使用优先级队列来实现这种延续回调调度的使用,以创建通常称为事件驱动编程或异步编程的代码体系结构。

如果您有幸使用最新的编译器,则可以通过使用新的 C++20 协程来显著简化异步编程。

正如内森的评论所暗示的那样,这可以很容易地用线程来完成

#include "glow.cpp"
#include "radar.cpp"
#include "trigger.cpp"
#include <thread>
int main()
{
std::thread threads[3] { { glow }, { radar }, { trigger } };
for (auto & thread : threads) thread.join();
}