Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source 2 - Reverse 9/2022 ConVar / ConCommand changes #115

Open
psychonic opened this issue Nov 9, 2022 · 0 comments
Open

Source 2 - Reverse 9/2022 ConVar / ConCommand changes #115

psychonic opened this issue Nov 9, 2022 · 0 comments

Comments

@psychonic
Copy link
Member

ConVars and ConCommands in Source 2 got a rework with a Dota 2 update a couple of months ago. The implementation seems to be fully rewritten.

Some snippets from a Russian Cheat Forum:

enum class EConvarType : std::uint8_t
{
    BOOL = 0,
    INT32,
    UINT32,
    INT64,
    UINT64,
    FLOAT,
    DOUBLE,
    STRING,
    COLOR_RGBA,
    UNK_SOME_TWO_FLOATS,
    UNK_SOME_THREE_FLOATS,
    UNK_SOME_FOUR_FLOATS,
    UNK_SOME_THREE_FLOATS_AGAIN,
};

struct CvarNode
{
    ConVariable* var{};
    int some_leaf_like_index_shit{};
};

union ConVarValue
{
    bool boolean{};
    std::uint64_t u64;
    std::int64_t i64;
    std::uint32_t u32;
    std::int32_t i32;
    float flt;
    double dbl;
    const char* str;
    std::uint32_t clr_rgba;
    std::array<float, 2> two_floats;
    std::array<float, 3> three_floats;
    std::array<float, 4> four_floats;
};

struct ConVariable
{
    const char* name{};
    void* next_convar_node_like_shit{};
    void* unk1{};
    void* unk2{};
    const char* help{};
    EConvarType type{};
    int unk_maybe_number_of_times_changed{};
    int flags{};
    int unk4{};
    int CALLBACK_INDEX{};
    int unk5{};
    ConVarValue value{};
}

struct ConCmd
{
    const char* name{};
    const char* help{};
    int flags{};
    void* accessor{};
    void* accessor_related_shit_maybe{};
    int shit_unk{};
    int CallbackListIndex{};
};

struct ConCMDID
{
    static inline constexpr auto BAD_ID = 0xFFFF;
    std::uint64_t impl{};

    bool IsGood() const noexcept
    {
        return impl != BAD_ID;
    }

    void Invalidate() noexcept
    {
        impl = BAD_ID;
    }
};

struct ConCMDRegistrationInfo
{
    const char* cmd_name{};
    const char* help_str{};
    std::uint64_t flags{};
    void* callback{};
    void* unk1{};
    void* unk2{};
    void* unk3{};
    void* output_id_holder{};
};
ConCommandSource2(const std::string_view& name, const std::string_view& desc, void(* callback)(void*, const CCommand&))
{
    ICvar::ConCMDRegistrationInfo info{};
    info.cmd_name = name.data();
    info.help_str = desc.data();
    info.callback = callback;
    info.output_id_holder = this;
    Constructor::Invoke(&info);
}


...
//CCvar VVV
    private:
    //search for xrefs for constructed concmd variables.
    static inline constexpr auto UnRegisterCMDVFTable_Index = 38;
public:
    auto UnRegisterCMD(const ConCMDID& id)
    {
        CallVFunc<UnRegisterCMDVFTable_Index>(id);
    }

struct ConVarID
{
    static inline constexpr auto BAD_ID = 0xFFFFFFFF;
    std::uint64_t impl{};
    void* var_ptr{};

    bool IsGood() const noexcept
    {
        return impl != BAD_ID;
    }

    void Invalidate() noexcept
    {
        impl = BAD_ID;
    }
};
using t_CvarCallback = void(*)(const ConVarID& id, int unk1, const ConVarValue* val, const ConVarValue* old_val);


/*
    t_CvarCallback GetCVarCallback(int index)
    {
        if (index)
        {
            auto table = Member<void*>(0x80);
            if (table)
                return *reinterpret_cast<t_CvarCallback*>(reinterpret_cast<std::uintptr_t>(table) + 24 * index);
        }
        return nullptr;
    }
*/
            /*
                auto CCvar::GetCvarList() const noexcept
                {
                    return std::span<const CvarNode>{ Member<const CvarNode*>(0x40), Member<std::uint16_t>(0x58) };
                }
            */
         
for (const auto& [cvar_node, idx] : ICvar::Create()->GetCvarList() | indexed_range)
{
    if (cvar_node.var)
    {
        if (make_stringview(cvar_node.var->name) == "dota_camera_distance")
        {
            const auto old_val = cvar_node.var->value;
            cvar_node.var->value.flt = 2222.0f;
            if (auto cb = ICvar::Create()->GetCVarCallback(cvar_node.var->CALLBACK_INDEX); cb)
                cb(ICvar::ConVarID{ .impl = static_cast<std::uint64_t>(idx), .var_ptr = (void*)&cvar_node},
                    0, &cvar_node.var->value, & old_val);
        }
        if (make_stringview(cvar_node.var->name) == "sv_cheats")
        {
            const auto old_val = cvar_node.var->value;
            cvar_node.var->value.boolean = true;
            if (auto cb = ICvar::Create()->GetCVarCallback(cvar_node.var->CALLBACK_INDEX); cb)
                cb(ICvar::ConVarID{ .impl = static_cast<std::uint64_t>(idx), .var_ptr = (void*)&cvar_node },
                    0, &cvar_node.var->value, &old_val);
        }
    }
}
@psychonic psychonic changed the title Dota - Reverse 9/2022 ConVar / ConCommand changes Source 2 - Reverse 9/2022 ConVar / ConCommand changes Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant