--// feel free to remove some of them but some may break the enitre script local required_functions = table.freeze({ "hookfunction", "restorefunction", "isexecutorclosure", "newcclosure", "filtergc", "getgc", "getfunctionhash", "getreg", "setclipboard", "readfile", "writefile", "isfolder", "makefolder", "isfile" }) local env = getgenv and getgenv() or _G for _, funcName in ipairs(required_functions) do if type(env[funcName]) ~= "function" then warn("your current executor doesn't support the required functions: " .. funcName) return end end -- // CONFIGURATION // -- more will be added soon! local MaxFuncsPerPage = 20 --// change this value to set max functions displauyed per page local HttpService = game:GetService("HttpService") local Packages = game:GetService("CorePackages").Packages local CoreGui = game:GetService("CoreGui") local React = require(Packages.React) local RbxReact = require(Packages.ReactRoblox) local e = React.createElement local hooked_functions = {} local SettingsPath = "GCViewer/Settings.json" local defaultSettings = { ignoreC = false, ignoreUnknown = false, ignoreExecutor = true, ignoreTables = false, ignoreCoreScript = false, darkMode = true, --// useRegistry is not saved because it may crash on some devices } local function loadSettings() if not env.isfolder("GCViewer") then env.makefolder("GCViewer") end if env.isfile(SettingsPath) then local success, data = pcall(function() return HttpService:JSONDecode(env.readfile(SettingsPath)) end) if success and type(data) == "table" then for k, v in defaultSettings do if data[k] == nil then data[k] = v end end data.useRegistry = false return data end end local initial = table.clone(defaultSettings) initial.useRegistry = false return initial end local function saveSettings(settingsData) if not env.isfolder("GCViewer") then env.makefolder("GCViewer") end local toSave = table.clone(settingsData) toSave.useRegistry = nil local success, encoded = pcall(function() return HttpService:JSONEncode(toSave) end) if success then env.writefile(SettingsPath, encoded) end end local function getAddress(f) local str = tostring(f) return str:match("0x%w+") or str end local function getFunctionDetails(f) local name, source = debug.info(f, "ns") local isC = source == "[C]" local isCore = source:match("CorePackages") or source:match("CoreGui") if name == nil or name == "" then name = "Unknown" end if source == nil or source == "" then source = "Unknown" elseif isC then source = "C++" elseif isCore then source = "CoreScript" end --// not all functions have hashes local success, hash = pcall(env.getfunctionhash, f) if not success or not hash then hash = "Not Available" end return { Func = f, Name = name, Source = source, Address = getAddress(f), Hash = hash, IsC = isC } end local function getShortSource(sourceStr) if sourceStr == "Unknown" or sourceStr == "C++" or sourceStr == "CoreScript" then return sourceStr end local cleanStr = sourceStr:gsub("^=", ""):gsub("^@", "") local current = game pcall(function() for part in cleanStr:gmatch("[^%.]+") do if current:FindFirstChild(part) then current = current:FindFirstChild(part) else current = nil break end end end) if current and typeof(current) == "Instance" and current:IsA("LuaSourceContainer") then return current.Name .. "." .. current.ClassName end local lastSeg = cleanStr:match("[^%.]+$") or cleanStr return lastSeg end local function parseSearchQuery(query) if query == "" then return "all", "" end if query:match("^#0x") then return "address", query:sub(2):lower() end if query:match("^##") then return "hash", query:sub(3) end if query:match('^"(.*)"$') then return "exact_nocase", query:sub(2, -2):lower() end if query:match("^'(.*)'$") then return "exact_case", query:sub(2, -2) end if query:match("^~(.*)~$") then return "fuzzy", query:sub(2, -2):lower() end return "starts_with", query:lower() end local function isMatch(details, filterType, queryValue) if filterType == "all" then return true end if filterType == "address" then return details.Address:lower() == queryValue end if filterType == "hash" then return details.Hash == queryValue end if filterType == "exact_nocase" then return details.Name:lower() == queryValue end if filterType == "exact_case" then return details.Name == queryValue end if filterType == "fuzzy" then return details.Name:lower():find(queryValue, 1, true) ~= nil end if filterType == "starts_with" then return details.Name:lower():sub(1, #queryValue) == queryValue end return false end local function scanFunctions(query, settings) local results = {} local filterType, queryValue = parseSearchQuery(query) local sourceTable = settings.useRegistry and env.getreg() or env.getgc() local function processFunction(f) if type(f) ~= "function" then return end if settings.ignoreExecutor and env.isexecutorclosure(f) then return end local details = getFunctionDetails(f) if settings.ignoreC and details.IsC then return end if settings.ignoreUnknown and details.Name == "Unknown" then return end if settings.ignoreCoreScript and details.Source == "CoreScript" then return end if isMatch(details, filterType, queryValue) then table.insert(results, details) end end if not settings.useRegistry and (filterType == "exact_nocase" or filterType == "exact_case" or filterType == "hash") then local filterOpts = { IgnoreExecutor = settings.ignoreExecutor } if filterType == "hash" then filterOpts.Hash = queryValue else filterOpts.Name = queryValue end local fastResults = env.filtergc("function", filterOpts, filterType == "hash") if type(fastResults) == "table" then for _, f in fastResults do processFunction(f) end return results end end for _, v in sourceTable do if type(v) == "function" then processFunction(v) elseif type(v) == "table" and not settings.ignoreTables then for _, tblVal in v do if type(tblVal) == "function" then processFunction(tblVal) end end end end return results end local function Button(props) return e("TextButton", { Size = props.Size or UDim2.new(1, 0, 0, 30), Text = props.Text, BackgroundColor3 = props.DarkMode and Color3.fromRGB(50, 50, 50) or Color3.fromRGB(220, 220, 220), TextColor3 = props.DarkMode and Color3.fromRGB(255, 255, 255) or Color3.fromRGB(0, 0, 0), [React.Event.Activated] = props.OnClick, LayoutOrder = props.LayoutOrder }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }) end local function Toggle(props) return e("Frame", { Size = UDim2.new(1, 0, 0, 20), BackgroundTransparency = 1, LayoutOrder = props.LayoutOrder }, { Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder, VerticalAlignment = Enum.VerticalAlignment.Center, Padding = UDim.new(0, 5) }), Circle = e("TextButton", { LayoutOrder = 1, Size = UDim2.new(0, 16, 0, 16), BackgroundColor3 = props.Value and Color3.fromRGB(0, 170, 255) or (props.DarkMode and Color3.fromRGB(70, 70, 70) or Color3.fromRGB(200, 200, 200)), Text = "", [React.Event.Activated] = props.OnToggle }, { Corner = e("UICorner", { CornerRadius = UDim.new(1, 0) }) }), Label = e("TextLabel", { LayoutOrder = 2, Size = UDim2.new(1, -21, 1, 0), BackgroundTransparency = 1, Text = props.Text, TextColor3 = props.DarkMode and Color3.fromRGB(255, 255, 255) or Color3.fromRGB(0, 0, 0), TextXAlignment = Enum.TextXAlignment.Left, TextScaled = true }, { Constraint = e("UITextSizeConstraint", { MaxTextSize = 14 }) }) }) end local function GCViewer() local functions, setFunctions = React.useState({}) local currentPage, setCurrentPage = React.useState(1) local searchQuery, setSearchQuery = React.useState("") local selectedFunc, setSelectedFunc = React.useState(nil) local refreshTick, setRefreshTick = React.useState(0) local settings, setSettings = React.useState(loadSettings()) React.useEffect(function() local results = scanFunctions(searchQuery, settings) setFunctions(results) local newTotal = math.max(1, math.ceil(#results / MaxFuncsPerPage)) if currentPage > newTotal then setCurrentPage(1) end setSelectedFunc(nil) end, {searchQuery, settings, refreshTick}) local function toggleSetting(key) local newSettings = table.clone(settings) newSettings[key] = not newSettings[key] setSettings(newSettings) saveSettings(newSettings) end local dm = settings.darkMode local bgCol = dm and Color3.fromRGB(30, 30, 30) or Color3.fromRGB(240, 240, 240) local textCol = dm and Color3.fromRGB(255, 255, 255) or Color3.fromRGB(0, 0, 0) local panelCol = dm and Color3.fromRGB(40, 40, 40) or Color3.fromRGB(255, 255, 255) local borderCol = dm and Color3.fromRGB(60, 60, 60) or Color3.fromRGB(180, 180, 180) local totalPages = math.max(1, math.ceil(#functions / MaxFuncsPerPage)) local startIndex = (currentPage - 1) * MaxFuncsPerPage + 1 local endIndex = math.min(startIndex + (MaxFuncsPerPage - 1), #functions) local listItems = { Layout = e("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder }) } local count = 1 for i = startIndex, endIndex do local funcInfo = functions[i] local isSelected = selectedFunc and selectedFunc.Address == funcInfo.Address listItems["Item_" .. i] = e("TextButton", { Size = UDim2.new(1, 0, 0, 25), BackgroundColor3 = isSelected and Color3.fromRGB(0, 120, 215) or (count % 2 == 0 and (dm and Color3.fromRGB(50,50,50) or Color3.fromRGB(230,230,230)) or panelCol), Text = "", LayoutOrder = i, [React.Event.Activated] = function() setSelectedFunc(funcInfo) end }, { Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder }), Address = e("TextLabel", { LayoutOrder = 1, Size = UDim2.new(0.3, 0, 1, 0), BackgroundTransparency = 1, Text = " " .. funcInfo.Address, TextXAlignment = Enum.TextXAlignment.Left, TextColor3 = isSelected and Color3.fromRGB(255,255,255) or textCol }), Name = e("TextLabel", { LayoutOrder = 2, Size = UDim2.new(0.4, 0, 1, 0), BackgroundTransparency = 1, Text = " " .. funcInfo.Name, TextXAlignment = Enum.TextXAlignment.Left, TextColor3 = isSelected and Color3.fromRGB(255,255,255) or textCol, TextTruncate = Enum.TextTruncate.AtEnd }), Source = e("TextLabel", { LayoutOrder = 3, Size = UDim2.new(0.3, 0, 1, 0), BackgroundTransparency = 1, Text = " " .. getShortSource(funcInfo.Source), TextXAlignment = Enum.TextXAlignment.Left, TextColor3 = isSelected and Color3.fromRGB(255,255,255) or textCol, TextTruncate = Enum.TextTruncate.AtEnd }) }) count = count + 1 end return e("Frame", { Size = UDim2.new(0.95, 0, 0.9, 0), AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.new(0.5, 0, 0.5, 0), BackgroundColor3 = bgCol, BorderSizePixel = 0, ClipsDescendants = true }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 8) }), Drag = e("UIDragDetector"), SizeConstraint = e("UISizeConstraint", { MaxSize = Vector2.new(850, 550), MinSize = Vector2.new(450, 300) }), TitleBar = e("TextLabel", { Size = UDim2.new(1, 0, 0, 30), BackgroundColor3 = dm and Color3.fromRGB(20, 20, 20) or Color3.fromRGB(200, 200, 200), Text = "GC-Viewer.exe - V1.1.0", TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Center, Font = Enum.Font.SourceSansBold, TextSize = 18, BorderSizePixel = 0 }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 8) }), }), Content = e("Frame", { Size = UDim2.new(1, 0, 1, -30), Position = UDim2.new(0, 0, 0, 30), BackgroundTransparency = 1 }, { Padding = e("UIPadding", { PaddingTop = UDim.new(0, 10), PaddingBottom = UDim.new(0, 10), PaddingLeft = UDim.new(0, 10), PaddingRight = UDim.new(0, 10) }), Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 10) }), LeftPanel = e("Frame", { LayoutOrder = 1, Size = UDim2.new(0.55, -5, 1, 0), BackgroundTransparency = 1 }, { Layout = e("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 10) }), SearchBar = e("TextBox", { LayoutOrder = 1, Size = UDim2.new(1, 0, 0, 30), BackgroundColor3 = panelCol, TextColor3 = textCol, TextWrapped = true, PlaceholderText = "Search...", Text = searchQuery, [React.Change.Text] = function(rbx) setSearchQuery(rbx.Text) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }), ListContainer = e("Frame", { LayoutOrder = 2, Size = UDim2.new(1, 0, 1, -95), BackgroundColor3 = panelCol, BorderSizePixel = 1, BorderColor3 = borderCol, ClipsDescendants = true }, { HorizontalScroll = e("ScrollingFrame", { Size = UDim2.new(1, 0, 1, 0), CanvasSize = UDim2.new(0, 600, 0, 0), AutomaticCanvasSize = Enum.AutomaticSize.X, ScrollingDirection = Enum.ScrollingDirection.X, ScrollBarThickness = 6, BackgroundTransparency = 1 }, { Header = e("Frame", { Size = UDim2.new(0, 600, 0, 20), BackgroundColor3 = dm and Color3.fromRGB(60, 60, 60) or Color3.fromRGB(220, 220, 220) }, { Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder }), H1 = e("TextLabel", { LayoutOrder = 1, Size = UDim2.new(0.3,0,1,0), BackgroundTransparency = 1, Text = " Address", TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left }), H2 = e("TextLabel", { LayoutOrder = 2, Size = UDim2.new(0.4,0,1,0), BackgroundTransparency = 1, Text = " Name", TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left }), H3 = e("TextLabel", { LayoutOrder = 3, Size = UDim2.new(0.3,0,1,0), BackgroundTransparency = 1, Text = " Source", TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left }) }), VerticalScroll = e("ScrollingFrame", { Size = UDim2.new(0, 600, 1, -20), Position = UDim2.new(0, 0, 0, 20), CanvasSize = UDim2.new(0, 0, 0, 0), AutomaticCanvasSize = Enum.AutomaticSize.Y, ScrollingDirection = Enum.ScrollingDirection.Y, ScrollBarThickness = 6, BackgroundTransparency = 1 }, listItems) }) }), Pagination = e("Frame", { LayoutOrder = 3, Size = UDim2.new(1, 0, 0, 45), BackgroundTransparency = 1 }, { Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder, HorizontalAlignment = Enum.HorizontalAlignment.Center, VerticalAlignment = Enum.VerticalAlignment.Center, Padding = UDim.new(0, 5) }), Prev10 = e("TextButton", { Size = UDim2.new(0, 30, 0, 25), Text = "<<", BackgroundColor3 = panelCol, TextColor3 = textCol, LayoutOrder = 1, [React.Event.Activated] = function() setCurrentPage(math.max(1, currentPage - 10)) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }), Prev = e("TextButton", { Size = UDim2.new(0, 30, 0, 25), Text = "<", BackgroundColor3 = panelCol, TextColor3 = textCol, LayoutOrder = 2, [React.Event.Activated] = function() setCurrentPage(math.max(1, currentPage - 1)) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }), CenterControls = e("Frame", { Size = UDim2.new(0, 80, 1, 0), BackgroundTransparency = 1, LayoutOrder = 3 }, { Layout = e("UIListLayout", { FillDirection = Enum.FillDirection.Vertical, HorizontalAlignment = Enum.HorizontalAlignment.Center, VerticalAlignment = Enum.VerticalAlignment.Center, Padding = UDim.new(0, 2) }), Label = e("TextLabel", { Size = UDim2.new(1, 0, 0, 20), Text = currentPage .. " / " .. totalPages, BackgroundTransparency = 1, TextColor3 = textCol, LayoutOrder = 1 }), Refresh = e("TextButton", { Size = UDim2.new(0, 60, 0, 20), Text = "Refresh", BackgroundColor3 = panelCol, TextColor3 = textCol, LayoutOrder = 2, [React.Event.Activated] = function() setRefreshTick(refreshTick + 1) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }) }), Next = e("TextButton", { Size = UDim2.new(0, 30, 0, 25), Text = ">", BackgroundColor3 = panelCol, TextColor3 = textCol, LayoutOrder = 4, [React.Event.Activated] = function() setCurrentPage(math.min(totalPages, currentPage + 1)) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }), Next10 = e("TextButton", { Size = UDim2.new(0, 30, 0, 25), Text = ">>", BackgroundColor3 = panelCol, TextColor3 = textCol, LayoutOrder = 5, [React.Event.Activated] = function() setCurrentPage(math.min(totalPages, currentPage + 10)) end }, { Corner = e("UICorner", { CornerRadius = UDim.new(0, 4) }) }) }) }), RightPanel = e("Frame", { LayoutOrder = 2, Size = UDim2.new(0.45, -5, 1, 0), BackgroundTransparency = 1 }, { Layout = e("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 10) }), SettingsPanel = e("Frame", { LayoutOrder = 1, Size = UDim2.new(1, 0, 0, 175), BackgroundColor3 = panelCol, BorderSizePixel = 1, BorderColor3 = borderCol }, { Layout = e("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 2) }), Padding = e("UIPadding", { PaddingTop = UDim.new(0,5), PaddingLeft = UDim.new(0,5) }), T1 = e(Toggle, { Text = "Ignore C functions", Value = settings.ignoreC, DarkMode = dm, LayoutOrder = 1, OnToggle = function() toggleSetting("ignoreC") end }), T2 = e(Toggle, { Text = "Ignore Unknown functions", Value = settings.ignoreUnknown, DarkMode = dm, LayoutOrder = 2, OnToggle = function() toggleSetting("ignoreUnknown") end }), T3 = e(Toggle, { Text = "Ignore Executor functions", Value = settings.ignoreExecutor, DarkMode = dm, LayoutOrder = 3, OnToggle = function() toggleSetting("ignoreExecutor") end }), T4 = e(Toggle, { Text = "Ignore functions from tables", Value = settings.ignoreTables, DarkMode = dm, LayoutOrder = 4, OnToggle = function() toggleSetting("ignoreTables") end }), T5 = e(Toggle, { Text = "Check in Registry ( LAGGY ⚠️ )", Value = settings.useRegistry, DarkMode = dm, LayoutOrder = 5, OnToggle = function() toggleSetting("useRegistry") end }), T6 = e(Toggle, { Text = "Ignore CoreScript functions", Value = settings.ignoreCoreScript, DarkMode = dm, LayoutOrder = 6, OnToggle = function() toggleSetting("ignoreCoreScript") end }), T7 = e(Toggle, { Text = "Dark Mode", Value = settings.darkMode, DarkMode = dm, LayoutOrder = 7, OnToggle = function() toggleSetting("darkMode") end }) }), DetailsPanel = selectedFunc and e("ScrollingFrame", { LayoutOrder = 2, Size = UDim2.new(1, 0, 1, -185), BackgroundColor3 = panelCol, BorderSizePixel = 1, BorderColor3 = borderCol, CanvasSize = UDim2.new(0, 0, 0, 0), AutomaticCanvasSize = Enum.AutomaticSize.Y, ScrollingDirection = Enum.ScrollingDirection.Y, ScrollBarThickness = 4 }, { Padding = e("UIPadding", { PaddingTop = UDim.new(0,10), PaddingLeft = UDim.new(0,10), PaddingRight = UDim.new(0,10), PaddingBottom = UDim.new(0,10) }), Layout = e("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 5) }), L1 = e("TextLabel", { LayoutOrder = 1, Size = UDim2.new(1,0,0,0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left, Text = "Name: " .. selectedFunc.Name, TextWrapped = true }), L2 = e("TextLabel", { LayoutOrder = 2, Size = UDim2.new(1,0,0,0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left, Text = "Source: " .. selectedFunc.Source, TextWrapped = true }), L3 = e("TextLabel", { LayoutOrder = 3, Size = UDim2.new(1,0,0,0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left, Text = "Address: " .. selectedFunc.Address, TextWrapped = true }), L4 = e("TextLabel", { LayoutOrder = 4, Size = UDim2.new(1,0,0,0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, TextColor3 = textCol, TextXAlignment = Enum.TextXAlignment.Left, Text = "Hash: " .. tostring(selectedFunc.Hash), TextWrapped = true }), BtnExecute = e(Button, { Text = "Call (check console)", DarkMode = dm, LayoutOrder = 5, OnClick = function() local bool, data = pcall(selectedFunc.Func) if not bool then warn("[GC-Viewer] When called errored: ", tostring(data)) elseif bool then print("[GC-Viewer] When called got: ", tostring(data)) end end }), BtnHook = e(Button, { Text = "Hook", DarkMode = dm, LayoutOrder = 6, OnClick = function() local f = selectedFunc.Func if not hooked_functions[selectedFunc.Address] then local rep = function() return end if selectedFunc.IsC then rep = env.newcclosure(rep) end env.hookfunction(f, rep) hooked_functions[selectedFunc.Address] = f end end }), BtnRestore = e(Button, { Text = "Restore (Removes Hook)", DarkMode = dm, LayoutOrder = 7, OnClick = function() if hooked_functions[selectedFunc.Address] then env.restorefunction(hooked_functions[selectedFunc.Address]) hooked_functions[selectedFunc.Address] = nil end end }), BtnCopyScript = e(Button, { Text = "Create Script", DarkMode = dm, LayoutOrder = 8, OnClick = function() local execState = tostring(settings.ignoreExecutor) local template = "" --// sorry for ugly syntax [[ ]] gets the spaces, there is a better way but lazy if selectedFunc.Name ~= "Unknown" then template = string.format([[ local func = filtergc("function", { Name = "%s", IgnoreExecutor = %s }, true) -- note that ill return the first result, if you want it to give you every function that has the same identifier please set to false or nothing print(func) -- this is your function ]], selectedFunc.Name, execState) elseif selectedFunc.Hash ~= "Not Available" then template = string.format([[ local func = filtergc("function", { Hash = "%s", IgnoreExecutor = %s }, true) -- note that ill return the first result, if you want it to give you every function that has the same identifier please set to false or nothing print(func) -- this is your function ]], selectedFunc.Hash, execState) else template = string.format([[ local func for _, v in getgc() do if type(v) == "function" then local str = tostring(v) local addr = str:match("0x%%w+") or str if addr == "%s" then func = v break end end end print(func) -- this is your function ]], selectedFunc.Address) end env.setclipboard(template) end }), BtnCopyPath = e(Button, { Text = "Copy Path", DarkMode = dm, LayoutOrder = 9, OnClick = function() if selectedFunc.Source ~= "Unknown" and selectedFunc.Source ~= "C++" and selectedFunc.Source ~= "CoreScript" then env.setclipboard(selectedFunc.Source) end end }), BtnCopyAddr = e(Button, { Text = "Copy Address", DarkMode = dm, LayoutOrder = 10, OnClick = function() env.setclipboard(selectedFunc.Address) end }), BtnCopyHash = e(Button, { Text = "Copy Hash", DarkMode = dm, LayoutOrder = 11, OnClick = function() if selectedFunc.Hash ~= "Not Available" then env.setclipboard(tostring(selectedFunc.Hash)) end end }) }) }) }) }) end local target = (env.gethui and env.gethui()) or CoreGui local gui = Instance.new("ScreenGui", target) gui.Name = "GCViewerApp" gui.ResetOnSpawn = false gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling local root = RbxReact.createRoot(gui) root:render(e(GCViewer))