filtergc
Key RequiredUniversal

filtergc

Universal ScriptVerifiedVerified 4.9K views 80 executesUpdated Mar 2, 2025
5.0/ 5(1 votes)
10100% Positive
Lua Script•198 lines (6254 chars)
type FunctionFilterOptions = {
    Name: string?, 
    Hash: string?,
    IgnoreExecutor: boolean?,
    Constants: { any }?,
    Upvalues: { any }?,
}

type TableFilterOptions = {
    Metatable: { any }?,
    Keys: { any }?,
    Values: { any }?,
    KeyValuePairs: { [any]: any }?,
}

type Function = ((...any) -> (...any))
type Table = ({ [any]: any })
type ReturnType = Function | Table

local info, find, insert = debug.getinfo, table.find, table.insert
local constants, upvalues = debug.getconstants, debug.getupvalues


local function filter_upvalues(func: Function, expected_upvalues: Table, ignore_executor: boolean): boolean
    
    local func_upvalues = upvalues(func)
    if #func_upvalues == 0 then return false end 

    local found = false 
    for _, value in pairs(expected_upvalues) do 
        if not find(func_upvalues, value) then continue end 

        found = true 
        break  
    end 
    return found 
end 

local function filter_constants(func: Function, expected_constants: Table, ignore_executor: boolean): boolean
    if iscclosure(func) then return false end 
    local func_constants = constants(func)
    if #func_constants == 0 then 
        return false 
    end

    local found = false 
    for _, value in pairs(expected_constants) do 
        if not find(func_constants, value) then continue end 
        
        found = true 
        break
    end 
    return found 
end 

local function filtergc(filter_type: "function" | "table", filter_options: FunctionFilterOptions | TableFilterOptions, return_one: boolean): ReturnType? | { ReturnType }
    if string.lower(filter_type) == "function" then 
        local output = {}

        local specific_name = filter_options.Name
        local specific_hash = filter_options.Hash
        local specific_constants = filter_options.Constants 
        local specific_upvalues = filter_options.Upvalues
        local ignore_executor = filter_options.IgnoreExecutor

        if ignore_executor == nil then 
            ignore_executor = true 
        end 

        local nothing_provided = not specific_name and not specific_constants and not specific_upvalues and not specific_hash 

        for _, value in pairs(getgc()) do 
            if typeof(value) ~= "function" or iscclosure(value) then continue end  
            
            if ignore_executor and isexecutorclosure(value) then continue end 
            
            local function_info = info(value)
            local name = function_info.name 

            if nothing_provided then 
                insert(output, value)
            end             

            if specific_name and name ~= specific_name then
                continue
            end

            if specific_hash and specific_hash ~= getfunctionhash(value) then
                continue 
            end 

            if specific_upvalues and function_info.nups ~= 0 and not filter_upvalues(value, specific_upvalues, ignore_executor) then 
                continue 
            elseif specific_upvalues and function_info.nups == 0 then 
                continue 
            end 

            if specific_constants and not filter_constants(value, specific_constants, ignore_executor) then 
                continue
            end 

            insert(output, value)
            if return_one then
                break
            end
 
        end 

        return not return_one and output or output[1]

    elseif string.lower(filter_type) == "table" then 
        local output = {}
        
        local specific_keys = filter_options.Keys 
        local specific_values = filter_options.Values
        local specific_pairs = filter_options.KeyValuePairs
        local specific_metatable = filter_options.Metatable
        local max_depth = 1 -- increase it if you want, I dont recommend it tho (will either lag or crash completly)

        local nothing_provided = not specific_keys and not specific_values and not specific_pairs and not specific_metatable

        local function check_table(tbl: Table, depth: number)
            if depth > max_depth then
                return false 
            end

            if nothing_provided then 
                insert(output, tbl)
            end 

            local matches = false
            if specific_keys then
                for key, _ in pairs(tbl) do 
                    if find(specific_keys, key) then 
                        matches = true 
                        break 
                    end 
                end 
            end

            if specific_values then
                for _, value in pairs(tbl) do 
                    if find(specific_values, value) then 
                        matches = true 
                        break 
                    end 
                end
            end

            if specific_metatable and getrawmetatable(tbl) == specific_metatable then 
                matches = true 
            end 

            if specific_pairs then
                for key, value in pairs(tbl) do     
                    if specific_pairs[key] == value then
                        matches = true
                        break
                    end
                end
            end

            if not matches then
                for _, v in pairs(tbl) do
                    if typeof(v) == "table" then
                        matches = check_table(v, depth + 1)
                        if matches then
                            break
                        end
                    end
                end
            end

            return not nothing_provided and matches or nothing_provided
        end

        for _, tbl in pairs(getgc(true)) do 
            if typeof(tbl) ~= "table" then 
                continue 
            end 
            local is_not_self = tbl ~= specific_keys and tbl ~= specific_values and tbl ~= specific_pairs
            if not is_not_self then 
                continue 
            end 
            if check_table(tbl, 1) then
                insert(output, tbl)
                if return_one then
                    break
                end
            end
        end
        return not return_one and output or output[1]
    end 
end 



getgenv().filtergc = newcclosure(filtergc)

Features & Information

This is filtergc made in luau. Its not the best implementation of it but still useful for executors that dont have it. Functions required: - getgc (ofc) - debug.getconstants - debug.getupvalues - Updated: [+] fixed upvalues handling [+] made isexecutor to true as default [+] made it return all tables / functions if no arguments are passed into to avoid looking trough the gc for nothing [+] fixed (mostly) table lookup speed [+] improved general speed by around 20% [+] added Hash option to function and Metatable option to table [+] now passes sunc

Community Comments (4)

deadgothbo11deadgothbo11Mar 2, 2025(edited)

doesnt work

deadgothbo11deadgothbo11Mar 2, 2025(edited)

ip logger maybe

ComeOnSyntaxComeOnSyntaxMar 3, 2025(edited)

what does this do?

tiamtiamMar 3, 2025(edited)

bro said ip logger

More Scripts for Universal Scripts