Tutorial Listening for Game Events [CSGO | Internal]

  • CSGO recently moved logic from 'client_panorama.dll' to 'client.dll', you must update all code that uses 'client_panorama.dll' and replace it with 'client.dll' or the code will not work.
Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Kekz

Maybe Pasting
Dank Tier Donator
Nobleman
Jan 10, 2020
157
4,118
15
How long you been coding/hacking?
~3 years / 6 months
Coding Language
C++
Context:
Today I'm going to show you how to setup a listener for Game Events.
In the game, there are specific events that trigger a notification if they occur (for example a player taking damage).
CS:GO offers the ability to register listeners for these events so you can do what you gotta do at the correct time.
While this tutorial may not be that advanced, I strongly recommend to only implement this if you're further into your CS:GO cheat journey
If you're just starting out, you won't have that many use cases for this and it may just add to the confusion.
If you're more experienced, Event Listeners can be an extremely powerful tool that allows you to do a lot of things.
This thread was inspired by this post: Solved - CSGO Event Hooking / Catching

What you'll need:
You're going to need a couple of classes.
C++:
// I stole this from somewhere but I don't remember where :|
// Just a function to access a function in a VMT
template <typename Fn> __forceinline Fn GetVirtualFunction(void* pClassBase, int nFunctionIndex)
{
    return (Fn)((PDWORD) * (PDWORD*)pClassBase)[nFunctionIndex];
}

class GameEvent
{
public:
    const char* GetName()
    {
        return GetVirtualFunction<const char*(__thiscall*) (void*)>(this, 1)(this);
    }
    // keyName is the name of the event's attribute you want to retrieve
    int GetInt(const char* keyName, int defaultVal = 0)
    {
        return GetVirtualFunction<int(__thiscall*) (void*, const char*, int)>(this, 6)(this, keyName, defaultVal);
    }
    float GetFloat(const char* keyName, float defaultVal = 0.f)
    {
        return GetVirtualFunction<float(__thiscall*) (void*, const char*, float)>(this, 8)(this, keyName, defaultVal);
    }
    const char* GetString(const char* keyName, const char* defaultVal = "")
    {
        return GetVirtualFunction<const char* (__thiscall*)(void*, const char*, const char*)>(this, 9)(this, keyName, defaultVal);
    }
    void SetString(const char* keyName, const char* value)
    {
        GetVirtualFunction<void(__thiscall*)(void*, const char*, const char*)>(this, 16)(this, keyName, value);
    }
};

class GameEventListener {
public:
    virtual ~GameEventListener() {}
    virtual void FireGameEvent(GameEvent* event) = 0;
    // Tells the server whether the event should be handled by this class instance. 42 if we want to handle it (we do)
    virtual int IndicateEventHandling() { return 42; }
};

// The game's interface
class GameEventManager
{
public:
    bool AddListener(GameEventListener* listener, const char* name)
    {
        // Bool specifies whether the context is for server or client, we only want client
        return GetVirtualFunction<bool(__thiscall*)(void*, GameEventListener*, const char*, bool)>(this, 3)(this, listener, name, false);
    }
    void RemoveListener(GameEventListener* listener)
    {
        GetVirtualFunction<void(__thiscall*)(void*, GameEventListener*)>(this, 5)(this, listener);
    }
};

This is what actually interfaces with the game.
You can get it like most CS:GO interfaces:
interfaces::EventManager = (GameEventManager*)GetInterface("engine.dll", "GAMEEVENTSMANAGER002");

Next, you'll need to setup your own Event Listener class.
EventListener.h:
// Inherit from the game's class
class EventListener : public GameEventListener
{
public:
    EventListener() noexcept;
    void Remove() noexcept;
    void FireGameEvent(GameEvent* event);
};

extern EventListener* g_eventListener;
This is the instance that you'll register with the game's GameEventManager.

EventListener.cpp:
EventListener::EventListener() noexcept
{
 
}

void EventListener::Remove() noexcept
{
    interfaces::EventManager->RemoveListener(this);
}

void EventListener::FireGameEvent(GameEvent* event)
{
 
}

EventListener* g_eventListener = nullptr;
Now, when you create the instance of your EventListener, you'll want to register or "subscribe" to all the events that you want to handle.
In this tutorial, I'm going to focus on the "player_hurt" event. As the name suggests, this event gets triggered whenever a player takes damage.

Start listening to the events:
// Somewhere in your initialization phase, you'll want to create an instance of your eventListener (for me, g_eventListener = new EventListener()) which will call this constructor and register your listeners
EventListener::EventListener() noexcept
{
   // Tell the game that this instance should be notified whenever the "player_hurt" event gets triggered
    interfaces::EventManager->AddListener(this, "player_hurt");
}
With this, whenever a player gets hurt, the game will call our EventListener::FireGameEvent(GameEvent* event) where we'll be able to do whatever we want.
I'm gonna give you a quick implementation to show you how it would work:
Handle the event:
void EventListener::FireGameEvent(GameEvent* event)
{
    // Check which event was just triggered. You'll only need this if you listen to multiple events
    if (strncmp(event->GetName(), "player_hurt", sizeof("player_hurt")) == 0)
    {
        // Find out how much damage was done
        int damage = event->GetInt("dmg_health");
        std::cout << "Player hurt for: " << damage << std::endl;
    }
}
Unbenannt.PNG

If you're wondering where I get all these names like "player_hurt" and "dmg_health" from, fear not.
There is a comprehensible overview of all available events and their attributes. Counter-Strike: Global Offensive Events - AlliedModders Wiki
For more (official) information see: Networking Events & Messages - Valve Developer Community and Built-In Engine Events - Valve Developer Community
I'll leave it up to you to properly use this information. There are so many things you can do with it, your imagination truly is the only limit.

I hope you enjoyed this tutorial.
As always, any kind of feedback / criticism is welcome.
 
Last edited:

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,349
78,998
2,412
Wow, you could do so much cool stuff with this, literally endless possibilities. Could send troll messages to chat based on every event lmao "nice shot loser" everytime they miss or something :p
 

Kekz

Maybe Pasting
Dank Tier Donator
Nobleman
Jan 10, 2020
157
4,118
15
Wow, you could do so much cool stuff with this, literally endless possibilities.
Indeed, this got me new motivation in the past weeks.
Could send troll messages to chat based on every event lmao "nice shot loser" everytime they miss or something :p
It's a feature a lot of p2c's have: "Kill say". Basically automatically trash talk whenever you kill someone. I personally hate it but obviously I'm gonna implement it.
You can also play sounds for every event :alex:
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods