wANN
wANN

Reputation: 5

How to run 3 functions at once?

I have one project called "everything" and 3 source files inside, "glow", "radar", "trigger". Inside, each one of these has a function(int glow {code}, int radar {code}, int trigger {code}). I am aware I need a main function to successfully debug the application. But here is the problem: if you set all 3 of the functions to be named "int main" - you cannot debug (I am also aware of that). If I set the name of one function within my .cpp files to be named "int main", only that one can be debugged, the rest of the .cpp files do not work at all, they get compiled, but nothing else happens. So I thought, maybe I should make another .cpp file called main.cpp . Then I thought, maybe including the other source files into this main file will work. In this "main.cpp" file, if I do

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



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

that and compile, only the glow function gets rendered. I don't understand what should I do, I don't want 3 console apps to be open at the same time just so each function works.


Below I will list the source code for each one.

glow.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);
    }

}

radar.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);
    }
}

trigger.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:: if you're wondering as to why I read and write memory with GZUZ in one source file, LX in another and Mem in another I just couldn't use Mem for all and it's just what I came up with as a solution at the time. I will try to put every line of code into a big source file again and compile (that sounds insane as I am expecting a different result while doing the same thing).

Upvotes: 1

Views: 136

Answers (2)

Lie Ryan
Lie Ryan

Reputation: 64837

When you do:

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

The three functions will run sequentially, one after another.

The problem is that you've designed each of your functions to run forever in an infinite loop, so glow never finishes and radar and trigger never had a chance to run.

There are two approaches here you can take. First is that you can run in multiple ghreads, which allows you to run multiple threads of execution in parallel without modifying your existing code. This is a a fairly easy and straightforward way to reuse your existing code without much modification, but if you need your functions to actually interact with one another or modify a shared data, you'll now have to deal with the multi threaded code, race conditions, locking, synchronisation, dead locks, and all the quirks of multi threading, which can be hard to work with if you're not careful.

The other approach is that instead of running your function in an infinite loop, you can rewrite your functions so they take turns.

So if you started with a program with functions that looks like this:

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

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

rewrite it so they share a single loop instead:

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

This loop will run all your functions in a single thread, but they would take turns to run instead of hogging the entire thread for themselves. Note that you should avoid doing things like sleep() inside the function, as that'll block all the other functions as well.

Instead, you'd want to rewrite those sleeps to yield control back to the main function and to reschedule a callback to continue execution to be called some time later when the sleep should've expired. This use of continuation callback scheduling can be implemented using a priority queue to make a code architecture usually called event driven programming or async programming.

If you have the pleasure of working with a very recent compiler, you may significantly simplify doing async programming by using the new C++20 coroutine.

Upvotes: 2

Caleth
Caleth

Reputation: 62656

As Nathan's comment alludes, this can easily be done with threads

#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();
} 

Upvotes: 1

Related Questions