M-Tass / Cyth

A gmod internal ESP hack
MIT License
15 stars 5 forks source link

Having trouble passing tables into functions #8

Closed FocuzJS closed 6 years ago

FocuzJS commented 6 years ago

So I've worked with tables as far as pulling values from a table goes, I'm using ents.FindByClass to return a table on the stack and then i want to use the Count method of table and when I make a call to Count with Push(-2) assuming its the table, but I must not know something about tables, because this call to Count fails with tried to call a table value when i use ents.GetAll() or tried to call a nil value with FindByClass. I've tried switching from Count to IsValid and get the same lua errors.

Some example code:

auto glua = globals::lua->create_interface(lua::type::client);

if (glua) {
    glua->PushSpecial(lua::special::glob);
    glua->GetField(-1, "ents");
    glua->GetField(-1, "FindByClass");
    glua->PushString("bit_miner_*", 11);
    glua->Call(1, 1);

    glua->GetField(-1, "IsValid");
    glua->Push(-2);
    glua->Call(1, 1);

    if (!glua->GetBool())
    {
        glua->Pop(4);
        continue;
    }

    glua->Pop();

    glua->PushString("1");
    glua->GetTable(-2);

    //the way this part was done may be a misunderstanding of stacks but im sure this is not the root cause of my issue because i've tried other combinations without this

    glua->GetField(-1, "IsValid");
    glua->Call(1, 1);

    //glua->GetField(-2, "Count");
    //glua->Push(-2);
    //glua->Call(1, 1);
    //auto x = glua->GetNumber();

    //char s[50];

    //sprintf(s, "%f", x);
    if (glua->GetBool()) {
        globals::print({ 255, 0, 0, 255 }, "boolin");
    }
    else {
        globals::print({ 255, 0, 0, 255 }, "not boolin");
    }

    glua->Pop(5);
}

maybe if you could show me an example of passing a table into a function, i would probably be able to figure this out on my own :)

M-Tass commented 6 years ago

Hi,

There's nothing special in passing tables to functions, they behave just as any other type The problem you're facing is due to how you're calling the IsValid / Count functions

Firstly, the table type has no IsValid or Count member functions. What you're looking for is the table.Count function or the universal IsValid function

An example of calling table.Count

if (auto glua = Lua::get())
{
    glua->push_special(Lua::special::glob);

    glua->get_field(-1, "ents");
    glua->get_field(-1, "FindByClass");
    glua->push_string("gmod_wire_expression2");
    glua->call(1, 1);

    glua->get_field(-3, "table");
    glua->get_field(-1, "Count");
    glua->push(-3);
    glua->call(1, 1);

    int32_t count = glua->get_number();
    glua->pop(5);

    ImGui::Text("Count: %i", count);
}

Note the -3 in glua->get_field(-3, "table");

The -3 means the 3rd element from the top of the stack (which is the global table or glob) because the "table" meta-table is a part of the global environment and not an attribute/field of the table type

M-Tass commented 6 years ago

Here's a quick snippet for entity esp:

if (auto glua = Lua::get())
{
    glua->push_special(Lua::special::glob);

    glua->get_field(-1, "ents");
    glua->get_field(-1, "FindByClass");
    glua->push_string("<Entity type>");
    glua->call(1, 1);

    glua->get_field(-3, "table");
    glua->get_field(-1, "Count");
    glua->push(-3);
    glua->call(1, 1);

    size_t count = glua->get_number();

    if (!count)
    {
        // We didn't find any E2's
        glua->pop(5);
    }
    else
    {
        // Pop count off the stack
        glua->pop();

        // Iterate all entities
        for (size_t i = 1; i <= count; ++i)
        {
            // Get the entity at index i
            glua->push_number(static_cast<double>(i));

            // -2 is the "table" meta-table (one with the Count function), our table is at -3
            glua->get_table(-3);

            // Get it's index
            glua->get_field(-1, "EntIndex");
            glua->push(-2);
            glua->call(1, 1);

            size_t index = glua->get_number();

            // Pop the index off the stack
            glua->pop();

            // Get the entitys position
            auto origin = globals::entities->get_entity(index)->get_abs_origin();

            if (auto pos = transform(origin))
            {
                // Entity is visible, let's draw it
                // But first let's get it's print name (Be very careful as printname can be nil)
                glua->get_field(-1, "PrintName");

                draw_text(pos.value(), IM_COL32(0, 255, 0, 255), glua->get_string());

                // Pop the printname off the stack
                glua->pop();
            }

            // Pop the entity off the stack
            glua->pop();
        }

        // Pop the glob, ent, table meta-table and table type off the stack
        glua->pop(4);
    }

    // Output the count
    ImGui::Text("Count: %i", count);
}

Result: DarkRP money pot ESP

FocuzJS commented 6 years ago

very nice anti-copy pasta 👍 so now im trying to give a bounding box to entities. I'm drawing boxes but the x coord (i think, the left right) seems to be exactly inverted. So when I move it to the left the box moves right and vice versa. I'm using the normal draw_box without a health bar and this is how it looks.

Here is how I want it to look. capture

Here's how it looks when you move it left/right or rotate: (note the line running through the middle is just a players eye angles being drawn since he had a gun out lol so ignore that) capture2

And here is an example of the up/down being correct from any angles/position capture3

FocuzJS commented 6 years ago

I also really like your debug output window, im jealous. for now im just drawing the counter on screen ;) (you can see it top left of screenshot 2 & 3)

M-Tass commented 6 years ago

It was never my intension to add "anti copy pasta" rather just a means of saying you're not restricted to a certain class only

Anyways, it's probably the rgfl_CoordinateFrame being incorrect so use the "draw_3d_box" function which doesn't require it. You still need to modify the function as it wasn't designed for entities, only players

Also the "Debug" window is just stock ImGui. Nothing special

FocuzJS commented 6 years ago

I should've known, I seen 3d box did the math. It's not the biggest deal in the world but im not sure how i'd go about supporting the rotation of entities in the esp. Currently the box is drawn perfect with position but the box doesn't rotate with the rotation of the model. If you can't be bothered, I do understand.

M-Tass commented 6 years ago

Here you go

M-Tass commented 6 years ago

Just got back to gmod This should fix the bounding box issue:

// This just calls the 10th vtable method
// Signature: const Angle& (__thiscall*)(void*)
FORCE_INLINE const Angle& get_abs_angles()
{
    return METHOD(10, Entity::get_abs_angles)();
}
void Vector::rotate(const Angle& angles)
{
    float pitch = angles[0] * rads;
    float yaw = angles[1] * rads;
    float roll = angles[2] * rads;

    float sp = std::sin(pitch);
    float cp = std::cos(pitch);

    float sy = std::sin(yaw);
    float cy = std::cos(yaw);

    float sr = std::sin(roll);
    float cr = std::cos(roll);

    float x = this->offsets[0], y = this->offsets[1], z = this->offsets[2];

    this->offsets[0] = x * cy * cp + y * (cy * sp * sr - sy * cr) + z * (cy * sp * cr + sy * sr);
    this->offsets[1] = x * sy * cp + y * (sy * sp * sr + cy * cr) + z * (sy * sp * cr - cy * sr);
    this->offsets[2] = y * (cp * sr) + z * (cp * cr) - sp * x;
}

Result: Rotated bounding boxes

FocuzJS commented 6 years ago

Thank you so much, the link was very helpful too.

FocuzJS commented 6 years ago

Would

inline const Angle& get_angles()
{
    using namespace hash::literals;
    auto offset = globals::netvars["DT_GMOD_Player"_fnv1a]["m_angEyeAngles[0]"_fnv1a];
    return *reinterpret_cast<Angle*>(reinterpret_cast<uintptr_t>(this) + offset);
}

be the get_abs_angles method you're on about?

M-Tass commented 6 years ago

No. It's a new function:

inline const Angle& get_abs_angles()
{
    using get_abs_angles_t = const Angle& (__thiscall*)(void*);
    return method<get_abs_angles_t>(10, this)(this)
}
FocuzJS commented 6 years ago

I find it funny I can draw all entities just fine now (including gmod_cameraprop) except for worldspawn.. Game crashes with no error. Wonder what could be causing this, gonna try some debug write to file to find out where the crash is happening.

FocuzJS commented 6 years ago

What is the actual classname of a prop as entity

M-Tass commented 6 years ago

prop_physics

FocuzJS commented 6 years ago

Thanks, so I am not crazy. I was trying to make prop esp for the flood gamemode but they spawn as a different entity with the same model as the props, but not as a normal prop_physics. Will update with the entity class name of a flood prop soon.

FocuzJS commented 6 years ago

prop_physics works everywhere but flood and the public source indicates that its' still a prop_physics..

M-Tass commented 6 years ago

Use trace ray to get the entity you're aiming at and check its class?

FocuzJS commented 6 years ago

My exact idea, but when I call GetClass on a prop_physics or worldspawn it freezes and then crashes my game with no error. Was wondering if there was a way to check if the entity has a valid GetClass method?

FocuzJS commented 6 years ago

Otherwise I'll only use the trace ray once im already looking at what i want to know the class of

M-Tass commented 6 years ago

fm_prop

FocuzJS commented 6 years ago

gosh, you're so helpful it's ridiculous. How did you manage to find that before me haha.

Here's my ray trace code, it works when printing to console and i close console and my game crashes with a stack leak, pretty sure im not popping something i should be

inline const char* trace_to_class() {
        auto glua = globals::lua->create_interface(lua::type::client);

        if (!glua)
            return {};

        glua->PushSpecial(lua::special::glob); // 1 GLOB
        glua->GetField(-1, "Entity");
        glua->PushNumber(this->get_index());
        glua->Call(1, 1); // 2 ent

        glua->GetField(-1, "GetEyeTrace");
        glua->Push(-2);
        glua->Call(1, 1); //3 table

        /*glua->GetField(-1, "Entity");
        glua->Push(-2);
        glua->Call(1, 1);*/
        glua->PushString("Entity"); 
        glua->GetTable(-2); // 5 ent

        glua->GetField(-1, "IsValid");
        glua->Push(-2);
        glua->Call(1, 1);

        if (!glua->GetBool()) {
            glua->Pop(5);
        }else{
            glua->Pop();

            glua->GetField(-1, "GetClass");
            glua->Push(-2);
            glua->Call(1, 1);

            return glua->GetString();
            glua->Pop(5);
        }
        return "nil";

    }
FocuzJS commented 6 years ago

holy shit i see it, im trying to pop after RETURNING OMFG

FocuzJS commented 6 years ago

Update: I'm no longer a dumb ass, my trace ray is also working!!