-- 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 })