Find Script And Save
Key RequiredUniversal

Find Script And Save

Universal Scriptgw87gw87 767 views 35 executesUpdated Oct 18, 2025
Unrated
00
Lua Script•568 lines (16539 chars)
-- Script Search & Decompiler (Modern Version)
-- Inspired by Depso's Script Search

type ScriptData = {
    Script: LuaSourceContainer,
    Path: string,
    Name: string,
    ClassName: string,
    Index: number
}

local BLACKLISTED_PATHS = {
    workspace,
    game:GetService("Players"),
    game:GetService("StarterGui"),
    game:GetService("CorePackages"),
    game:GetService("CoreGui"),
}

-- Studio/Executor compatibility
decompile = decompile or function(script) 
    return "-- Decompile not supported\n-- Script: " .. script:GetFullName() 
end
cloneref = cloneref or function(...) return ... end
setclipboard = setclipboard or function() end
writefile = writefile or function() end

local Scripts = {}
local FilteredScripts = {}
local CurrentScript = nil
local CurrentSearch = ""
local Index = 0

-- Functions
local function IsBlacklisted(script)
    for _, parent in pairs(BLACKLISTED_PATHS) do
        if script:IsDescendantOf(parent) then
            return true
        end
    end
    return false
end

local function IsAllowed(script)
    if not (script:IsA("Script") or script:IsA("LocalScript") or script:IsA("ModuleScript")) then 
        return false 
    end
    if IsBlacklisted(script) then 
        return false 
    end
    return true
end

local function AddScript(script)
    if not script then return end
    if not IsAllowed(script) then return end
    
    local success, clone = pcall(function()
        return script:Clone()
    end)
    
    if not success or not clone then return end
    
    if clone:IsA("Script") or clone:IsA("LocalScript") then
        pcall(function()
            clone.Enabled = false
        end)
    end
    
    Index = Index + 1
    local data = {
        Script = clone,
        Path = script:GetFullName(),
        Name = script.Name,
        ClassName = script.ClassName,
        Index = Index
    }
    
    table.insert(Scripts, data)
    table.insert(FilteredScripts, data)
    
    return data
end

local function SearchScripts(query)
    FilteredScripts = {}
    local lowerQuery = query:lower()
    
    for _, data in ipairs(Scripts) do
        if lowerQuery == "" or data.Path:lower():find(lowerQuery) then
            table.insert(FilteredScripts, data)
        end
    end
    
    return FilteredScripts
end

local function DecompileScript(data)
    if not data or not data.Script then return "-- No script selected" end
    
    CurrentScript = data
    
    local success, result = pcall(function()
        return decompile(data.Script)
    end)
    
    if success then
        return string.format("-- %s\n-- Type: %s\n-- Path: %s\n\n%s", 
            data.Name, 
            data.ClassName, 
            data.Path, 
            result
        )
    else
        return string.format("-- %s\n-- Type: %s\n-- Path: %s\n\n-- [Decompile Error]\n-- %s", 
            data.Name, 
            data.ClassName, 
            data.Path, 
            tostring(result)
        )
    end
end

-- Cloneref blacklisted paths
for i, parent in pairs(BLACKLISTED_PATHS) do
    BLACKLISTED_PATHS[i] = cloneref(parent)
end

-- Initial collection
print("[Script Search] Collecting scripts...")
for _, obj in ipairs(game:GetDescendants()) do
    AddScript(obj)
end

-- Monitor new scripts
game.DescendantAdded:Connect(function(obj)
    task.wait(0.1)
    AddScript(obj)
end)

print("[Script Search] Found " .. #Scripts .. " scripts")

-- Wait for game to load
repeat task.wait() until game:IsLoaded()

-- Load Fluent UI
local Fluent = loadstring(game:HttpGet("https://github.com/dawid-scripts/Fluent/releases/latest/download/main.lua"))()

local Window = Fluent:CreateWindow({
    Title = "Script Search & Decompiler",
    SubTitle = "by Script",
    TabWidth = 160,
    Size = UDim2.fromOffset(700, 500),
    Acrylic = true,
    Theme = "Dark",
    MinimizeKey = Enum.KeyCode.LeftControl
})

local Tabs = {
    Main = Window:AddTab({ Title = "Scripts", Icon = "search" }),
    Viewer = Window:AddTab({ Title = "Viewer", Icon = "code" }),
    Settings = Window:AddTab({ Title = "Settings", Icon = "settings" })
}

-- Variables for UI
local ScriptListDisplay = {}
local CurrentDisplayedSource = "-- Select a script to view its source code"
local SelectedIndex = nil

-- Main Tab - Script List
Tabs.Main:AddParagraph({
    Title = "Script List",
    Content = string.format("Total: %d scripts | Filtered: %d scripts", #Scripts, #FilteredScripts)
})

local SearchInput = Tabs.Main:AddInput("SearchInput", {
    Title = "Search Scripts",
    Default = "",
    Placeholder = "Enter script name or path...",
    Callback = function(value)
        CurrentSearch = value
        SearchScripts(value)
        
        -- Update list display
        ScriptListDisplay = {}
        for i, data in ipairs(FilteredScripts) do
            table.insert(ScriptListDisplay, string.format("[%d] %s", i, data.Path))
        end
        
        print("\n" .. string.rep("=", 80))
        print("SEARCH RESULTS: '" .. value .. "'")
        print(string.rep("=", 80))
        for _, line in ipairs(ScriptListDisplay) do
            print(line)
        end
        print(string.rep("=", 80))
        print("Found: " .. #FilteredScripts .. " script(s)\n")
        
        Fluent:Notify({
            Title = "Search Complete",
            Content = #FilteredScripts .. " scripts found",
            Duration = 2
        })
    end
})

local ViewIndexInput = Tabs.Main:AddInput("ViewIndex", {
    Title = "View Script by Index",
    Default = "",
    Placeholder = "Enter number from list...",
    Callback = function(value)
        local index = tonumber(value)
        if not index then return end
        
        if not FilteredScripts[index] then
            Fluent:Notify({
                Title = "Invalid Index",
                Content = "Script #" .. index .. " not found",
                Duration = 2
            })
            return
        end
        
        SelectedIndex = index
        local source = DecompileScript(FilteredScripts[index])
        CurrentDisplayedSource = source
        
        print("\n" .. string.rep("=", 80))
        print(source)
        print(string.rep("=", 80) .. "\n")
        
        Fluent:Notify({
            Title = "Viewing Script",
            Content = FilteredScripts[index].Name,
            Duration = 2
        })
    end
})

Tabs.Main:AddButton({
    Title = "Show Script List",
    Description = "Display all filtered scripts in console (F9)",
    Callback = function()
        print("\n" .. string.rep("=", 80))
        print("SCRIPT LIST (Total: " .. #FilteredScripts .. ")")
        print(string.rep("=", 80))
        
        for i, data in ipairs(FilteredScripts) do
            print(string.format("[%d] %s - %s", i, data.ClassName, data.Path))
        end
        
        print(string.rep("=", 80) .. "\n")
    end
})

Tabs.Main:AddButton({
    Title = "Refresh Scripts",
    Description = "Rescan all scripts in game",
    Callback = function()
        Scripts = {}
        FilteredScripts = {}
        Index = 0
        
        for _, obj in ipairs(game:GetDescendants()) do
            AddScript(obj)
        end
        
        SearchScripts(CurrentSearch)
        
        print("[Script Search] Rescanned: " .. #Scripts .. " scripts")
        
        Fluent:Notify({
            Title = "Refresh Complete",
            Content = #Scripts .. " scripts found",
            Duration = 3
        })
    end
})

-- Viewer Tab
Tabs.Viewer:AddParagraph({
    Title = "Script Viewer",
    Content = "View decompiled source code"
})

Tabs.Viewer:AddButton({
    Title = "View in Console (F9)",
    Description = "Display full source in console",
    Callback = function()
        if CurrentScript then
            print("\n" .. string.rep("=", 80))
            print(CurrentDisplayedSource)
            print(string.rep("=", 80) .. "\n")
        else
            print("[!] No script selected. Use 'View Script by Index' first.")
        end
    end
})

Tabs.Viewer:AddButton({
    Title = "Copy to Clipboard",
    Description = "Copy current script source",
    Callback = function()
        if CurrentScript then
            setclipboard(CurrentDisplayedSource)
            Fluent:Notify({
                Title = "Copied",
                Content = CurrentScript.Name,
                Duration = 2
            })
        else
            Fluent:Notify({
                Title = "No Script",
                Content = "Select a script first",
                Duration = 2
            })
        end
    end
})

Tabs.Viewer:AddButton({
    Title = "Save to File",
    Description = "Export script to .lua file",
    Callback = function()
        if not CurrentScript then
            Fluent:Notify({
                Title = "No Script",
                Content = "Select a script first",
                Duration = 2
            })
            return
        end
        
        local fileName = CurrentScript.Name:gsub("[^%w]", "_") .. "_decompiled.lua"
        
        local success, err = pcall(function()
            writefile(fileName, CurrentDisplayedSource)
        end)
        
        if success then
            Fluent:Notify({
                Title = "Saved",
                Content = fileName,
                Duration = 3
            })
        else
            Fluent:Notify({
                Title = "Error",
                Content = "writefile not supported or failed",
                Duration = 2
            })
        end
    end
})

-- Settings Tab
Tabs.Settings:AddParagraph({
    Title = "Quick Filters",
    Content = "Filter scripts by location"
})

local LocationFilter = Tabs.Settings:AddDropdown("LocationFilter", {
    Title = "Filter by Location",
    Values = {
        "All",
        "ReplicatedStorage",
        "ReplicatedFirst",
        "ServerScriptService",
        "ServerStorage",
        "StarterPlayer",
        "StarterPack",
        "Lighting"
    },
    Default = 1,
    Callback = function(value)
        if value == "All" then
            FilteredScripts = {table.unpack(Scripts)}
        else
            FilteredScripts = {}
            for _, data in ipairs(Scripts) do
                if data.Path:find(value) then
                    table.insert(FilteredScripts, data)
                end
            end
        end
        
        print("\n[Filter] " .. value .. ": " .. #FilteredScripts .. " scripts")
        
        Fluent:Notify({
            Title = "Filter Applied",
            Content = #FilteredScripts .. " scripts",
            Duration = 2
        })
    end
})

local TypeFilter = Tabs.Settings:AddDropdown("TypeFilter", {
    Title = "Filter by Type",
    Values = {"All", "LocalScript", "Script", "ModuleScript"},
    Default = 1,
    Callback = function(value)
        if value == "All" then
            FilteredScripts = {table.unpack(Scripts)}
        else
            FilteredScripts = {}
            for _, data in ipairs(Scripts) do
                if data.ClassName == value then
                    table.insert(FilteredScripts, data)
                end
            end
        end
        
        print("\n[Filter] " .. value .. ": " .. #FilteredScripts .. " scripts")
        
        Fluent:Notify({
            Title = "Filter Applied",
            Content = #FilteredScripts .. " scripts",
            Duration = 2
        })
    end
})

Tabs.Settings:AddButton({
    Title = "Export All Scripts",
    Description = "Save all scripts to one file",
    Callback = function()
        -- Show starting notification
        Fluent:Notify({
            Title = "Export Started",
            Content = "Processing " .. #Scripts .. " scripts...",
            Duration = 3
        })
        
        print("\n[Export] Starting export of " .. #Scripts .. " scripts...")
        
        task.spawn(function()
            local allContent = "-- All Scripts Export\n"
            allContent = allContent .. "-- Date: " .. os.date("%Y-%m-%d %H:%M:%S") .. "\n"
            allContent = allContent .. "-- Total Scripts: " .. #Scripts .. "\n\n"
            
            local successCount = 0
            local errorCount = 0
            
            for i, data in ipairs(Scripts) do
                local success, decompiledCode = pcall(function()
                    return DecompileScript(data)
                end)
                
                if success then
                    allContent = allContent .. string.rep("-", 80) .. "\n"
                    allContent = allContent .. string.format("-- [%d/%d] %s\n", i, #Scripts, data.Path)
                    allContent = allContent .. string.rep("-", 80) .. "\n\n"
                    allContent = allContent .. decompiledCode .. "\n\n"
                    successCount = successCount + 1
                else
                    allContent = allContent .. string.rep("-", 80) .. "\n"
                    allContent = allContent .. string.format("-- [%d/%d] %s - ERROR\n", i, #Scripts, data.Path)
                    allContent = allContent .. string.rep("-", 80) .. "\n\n"
                    errorCount = errorCount + 1
                end
                
                -- Progress update every 10 scripts
                if i % 10 == 0 then
                    print(string.format("[Export] Progress: %d/%d scripts", i, #Scripts))
                end
            end
            
            allContent = allContent .. string.rep("=", 80) .. "\n"
            allContent = allContent .. "-- Export Complete\n"
            allContent = allContent .. string.format("-- Success: %d | Errors: %d\n", successCount, errorCount)
            allContent = allContent .. string.rep("=", 80) .. "\n"
            
            local fileName = "AllScripts_" .. os.date("%Y%m%d_%H%M%S") .. ".lua"
            
            -- Try to write file
            local writeSuccess, writeErr = pcall(function()
                writefile(fileName, allContent)
            end)
            
            if writeSuccess then
                print("[Export] File saved: " .. fileName)
                Fluent:Notify({
                    Title = "Export Complete",
                    Content = fileName .. " (" .. #Scripts .. " scripts)",
                    Duration = 5
                })
            else
                -- Fallback to clipboard
                print("[Export] writefile failed, copying to clipboard instead")
                local clipSuccess = pcall(function()
                    setclipboard(allContent)
                end)
                
                if clipSuccess then
                    Fluent:Notify({
                        Title = "Copied to Clipboard",
                        Content = "writefile not supported. " .. #Scripts .. " scripts copied.",
                        Duration = 5
                    })
                else
                    Fluent:Notify({
                        Title = "Export Failed",
                        Content = "No file or clipboard support available",
                        Duration = 5
                    })
                end
            end
        end)
    end
})

-- Calculate statistics
local function GetStatistics()
    local stats = {
        Total = #Scripts,
        LocalScript = 0,
        Script = 0,
        ModuleScript = 0
    }
    
    for _, data in ipairs(Scripts) do
        if data.ClassName == "LocalScript" then
            stats.LocalScript = stats.LocalScript + 1
        elseif data.ClassName == "Script" then
            stats.Script = stats.Script + 1
        elseif data.ClassName == "ModuleScript" then
            stats.ModuleScript = stats.ModuleScript + 1
        end
    end
    
    return stats
end

local stats = GetStatistics()

Tabs.Settings:AddParagraph({
    Title = "Statistics",
    Content = string.format([[
Total Scripts: %d
LocalScripts: %d
Scripts: %d
ModuleScripts: %d
    ]], 
    stats.Total,
    stats.LocalScript,
    stats.Script,
    stats.ModuleScript)
})

-- Initial display
print("\n" .. string.rep("=", 80))
print("SCRIPT SEARCH & DECOMPILER")
print(string.rep("=", 80))
print("Total Scripts: " .. #Scripts)
print("Blacklisted Paths: workspace, Players, StarterGui, CorePackages, CoreGui")
print(string.rep("=", 80))
print("\nUSAGE:")
print("1. Use search bar to filter scripts")
print("2. Check console (F9) for script list")
print("3. Enter index number to view script")
print("4. Copy or save decompiled source")
print(string.rep("=", 80) .. "\n")

Fluent:Notify({
    Title = "Script Search Loaded",
    Content = #Scripts .. " scripts found",
    Duration = 5
})

Features & Information

Find all script then save to file
#Find script#Scanner

Community Comments (1)

gw87gw87Oct 21, 2025

@kron1k too easy

More Scripts for Universal Scripts