forked from steven4547466/Rovird
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRovird.Script
More file actions
54 lines (54 loc) · 13.6 KB
/
Copy pathRovird.Script
File metadata and controls
54 lines (54 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{
"className": "Script",
"name": "Rovird",
"referent": "RBX3698A258F7EA4DAC85C2817D2357FB2B",
"properties": {
"AttributesSerialize": {
"_propertyType": "BinaryString",
"values": {}
},
"Tags": {
"_propertyType": "BinaryString",
"values": {}
},
"Disabled": {
"_propertyType": "bool",
"values": {
"_": "false"
}
},
"LinkedSource": {
"_propertyType": "Content",
"values": {
"null": [
""
]
}
},
"Name": {
"_propertyType": "string",
"values": {
"_": "Rovird"
}
},
"ScriptGuid": {
"_propertyType": "string",
"values": {
"_": "{64805FA4-3923-423D-BB9A-59FA41E6CD7F}"
}
},
"Source": {
"_propertyType": "ProtectedString",
"values": {
"_": "local HttpService = game:GetService(\"HttpService\")\nlocal Selection = game:GetService(\"Selection\")\nlocal CollectionService = game:GetService(\"CollectionService\")\n\nlocal toolbar = plugin:CreateToolbar(\"Rovird\")\nlocal openUiButton = toolbar:CreateButton(\"Rovird Plugin GUI\", \"Flags scripts that could possibly contain or require viruses\", \"rbxassetid://7970846461\")\n\nopenUiButton.ClickableWhenViewportHidden = true\n\nlocal hasRunBefore = plugin:GetSetting(\"hasRunBefore\")\nif not hasRunBefore then\n\tplugin:SetSetting(\"hasRunBefore\", true)\n\tplugin:SetSetting(\"baseUrl\", \"https://rovird.xyz/\")\nend\n\nlocal lastJobs = {}\nlocal lastUUIDs = {}\n\nlocal previousResults = {}\n\nlocal ui = nil\n\nlocal doNotCheckTag = \"Rovird_DoNotCheck\"\n\nlocal resultsLocked = false\n\nlocal info = {\n\tInternalScanned=0;\n\tExternalScanned=0;\n\tTotalScanned=0;\n\tTotalFlags=0;\n}\n\nfunction getBaseUrl()\n\treturn plugin:GetSetting(\"baseUrl\")\nend\n\nfunction getUrl(ext)\n\treturn getBaseUrl()..ext\nend\n\nfunction trim(s)\n\treturn s:gsub(\"^%s+\", \"\"):gsub(\"%s+$\", \"\")\nend\n\nfunction updateInfo(prop, newValue)\n\tlocal label = ui.Frame.Results.Folder.OverallInfo:FindFirstChild(prop)\n\tif label then \n\t\tlabel.Text = trim(label.Text:gsub(\"%d\", \"\"))\n\t\tlabel.Text = label.Text .. \" \" .. tostring(newValue)\n\tend\n\tinfo[prop] = newValue\nend\n\nfunction openUi()\n\tif ui ~= nil then\n\t\tui.Enabled = true\n\telse\n\t\tui = plugin:CreateDockWidgetPluginGui(\n\t\t\t\"Rovird\",\n\t\t\tDockWidgetPluginGuiInfo.new(\n\t\t\t\tEnum.InitialDockState.Float,\n\t\t\t\ttrue,\n\t\t\t\ttrue,\n\t\t\t\t588,\n\t\t\t\t310,\n\t\t\t\t588,\n\t\t\t\t310\n\t\t\t)\n\t\t)\n\t\tui.Title = \"Rovird Advanced Virus Detector\"\n\t\tlocal frame = script.Frame\n\t\tframe.Size = UDim2.new(1,0,1,0)\n\t\tframe.Parent = ui\n\t\tframe.Main.ToggleDNC.MouseButton1Click:Connect(toggleDNC)\n\t\tframe.Main.SendJob.MouseButton1Click:Connect(sendJob)\n\t\tframe.Main.Results.MouseButton1Click:Connect(getResults)\n\t\tframe.Main.ListDNC.MouseButton1Click:Connect(listDNC)\n\t\tframe.Main.Options.MouseButton1Click:Connect(openOptions)\n\tend\nend\n\nfunction openOptions()\n\tui.Frame.Options.BaseUrl.Text = getBaseUrl()\n\tui.Frame.Main.Visible = false\n\tui.Frame.Options.Visible = true\nend\n\nfunction listDNC()\n\tfor i, v in ipairs(CollectionService:GetTagged(doNotCheckTag)) do\n\t\tlocal button = script.Parent.Button:Clone()\n\t\tbutton.Name = \"ListItem\"\n\t\tbutton.Text = v.Name\n\t\tbutton.Parent = ui.Frame.DNCList\n\t\tbutton.MouseButton1Click:Connect(function()\n\t\t\tSelection:Set({v})\n\t\t\tif v:IsA(\"LuaSourceContainer\") then\n\t\t\t\tplugin:OpenScript(v)\n\t\t\tend\n\t\tend)\n\t\tbutton.MouseButton2Click:Connect(function()\n\t\t\tCollectionService:RemoveTag(v, doNotCheckTag)\n\t\t\tbutton:Destroy()\n\t\tend)\n\tend\n\tui.Frame.Main.Visible = false\n\tui.Frame.DNCList.Visible = true\nend\n\nfunction toggleDNC()\n\tlocal selection = Selection:Get()\n\tfor i, v in ipairs(selection) do\n\t\tif CollectionService:HasTag(v, doNotCheckTag) then\n\t\t\tCollectionService:RemoveTag(v, doNotCheckTag)\n\t\telse\n\t\t\tCollectionService:AddTag(v, doNotCheckTag)\n\t\tend\n\tend\nend\n\nfunction sendJob()\n\tfor k in pairs(info) do\n\t\tupdateInfo(k, 0)\n\tend\n\ttable.clear(lastJobs)\n\ttable.clear(lastJobs)\n\ttable.clear(previousResults)\n\tlocal toPost = {}\n\ttopLevel(game, toPost, 1, nil)\n\tlocal chunked = {}\n\tfor i, v in ipairs(toPost) do\n\t\ttable.insert(chunked, chunk(v, 10))\n\tend\n\t\n\tui.Frame.Main.Results.BackgroundColor3 = Color3.new(0.329412, 0.329412, 0.329412)\n\tresultsLocked = true\n\t\n\tfor _, v in ipairs(chunked) do\n\t\tfor _, v2 in ipairs(v) do\n\t\t\tif #v2 == 0 then continue end\n\t\t\tlocal success, res = pcall(HttpService.RequestAsync, HttpService, {[\"Url\"]=getUrl(\"jobs\");[\"Method\"]=\"POST\";[\"Body\"]=HttpService:JSONEncode(v2),[\"Headers\"]={[\"Content-Type\"]=\"application/json\"}})\n\t\t\tif not success then\n\t\t\t\tui.Frame.Main.Results.BackgroundColor3 = Color3.new(1,0,0)\n\t\t\t\terror(\"Connection to \" .. getBaseUrl() .. \" was refused.\")\n\t\t\tend\n\t\t\tif res.StatusCode ~= 200 then\n\t\t\t\tprint(\"Posting job returned non-200 code: \" .. tostring(res.StatusCode))\n\t\t\t\tif res.StatusCode ~= 413 then\n\t\t\t\t\tprint(\"Message from server:\")\n\t\t\t\t\tprint(res.Body)\n\t\t\t\tend\n\t\t\t\tcontinue\n\t\t\tend\n\t\t\ttable.insert(lastJobs, HttpService:JSONDecode(res.Body).jobId)\n\t\t\tif #v2 > 60 then task.wait(1) end\n\t\tend\n\tend\n\twhile true do\n\t\tlocal res = HttpService:RequestAsync({[\"Url\"]=getUrl(\"jobs-status\")..\"?jobIds=\"..table.concat(lastJobs,\",\");[\"Method\"]=\"GET\"})\n\t\tif res.StatusCode ~= 200 then\n\t\t\tui.Frame.Main.Results.BackgroundColor3 = Color3.new(1,0,0)\n\t\t\tprint(\"Failed to get job status\")\n\t\t\tprint(\"Message from server:\")\n\t\t\tprint(res.Body)\n\t\t\tbreak\n\t\telse\n\t\t\tlocal flag = false\n\t\t\t\n\t\t\tfor id, value in pairs(HttpService:JSONDecode(res.Body)) do\n\t\t\t\tif value == 0 then\n\t\t\t\t\tflag = true\n\t\t\t\t\tbreak\n\t\t\t\tend\n\t\t\tend\n\t\t\t\n\t\t\tif not flag then\n\t\t\t\tresultsLocked = false\n\t\t\t\tui.Frame.Main.Results.BackgroundColor3 = Color3.new(0, 1, 0)\n\t\t\t\tbreak\n\t\t\tend\n\t\tend\n\t\t\n\t\ttask.wait(0.5)\n\tend\nend\n\nfunction getResults()\n\tif resultsLocked then return end\n\tfor k in pairs(info) do\n\t\tupdateInfo(k, 0)\n\tend\n\tlocal toRemove = {}\n\tif #lastJobs > 0 then\n\t\tfor i, jobId in ipairs(lastJobs) do\n\t\t\tlocal res = HttpService:RequestAsync({[\"Url\"]=getUrl(\"jobs\")..\"?jobId=\"..jobId;[\"Method\"]=\"GET\"})\n\t\t\tif res.StatusCode ~= 200 then\n\t\t\t\tprint(\"Job Id \" .. jobId .. \" returned non-200 code: \" .. tostring(res.StatusCode))\n\t\t\t\tprint(\"Message from server:\")\n\t\t\t\tprint(res.Body)\n\t\t\t\tif res.Body ~= \"Job not yet complete. Try again soon\" then\n\t\t\t\t\ttable.insert(toRemove, jobId)\n\t\t\t\tend\n\t\t\t\tcontinue\n\t\t\tend\n\t\t\ttable.insert(toRemove, jobId)\n\t\t\tlocal results = HttpService:JSONDecode(res.Body)\n\t\t\texecuteResults(results)\n\t\t\ttable.insert(previousResults, results)\n\t\tend\n\telse\n\t\tfor i, results in ipairs(previousResults) do\n\t\t\texecuteResults(results)\n\t\tend\n\tend\n\t\n\tfor i, v in ipairs(toRemove) do\n\t\tlocal index = table.find(lastJobs, v)\n\t\tif index ~= nil then table.remove(lastJobs, index) end\n\tend\n\t\n\tui.Frame.Main.Visible = false\n\tui.Frame.Results.Visible = true\nend\n\nfunction executeResults(results)\n\tlocal toClone = script.Parent.Button\n\tfor i, result in ipairs(results) do\n\t\tfor uuid, r in pairs(result) do\n\t\t\tlocal name = \"\"\n\t\t\tif lastUUIDs[uuid] == nil then\n\t\t\t\tname = r.name\n\t\t\telse\n\t\t\t\tname = lastUUIDs[uuid].Name\n\t\t\tend\n\t\t\tlocal button = toClone:Clone()\n\t\t\tbutton.Name = \"ListItem\"\n\t\t\tbutton.Text = name .. \" (\" .. getLocationInWorkspace(lastUUIDs[uuid], r) .. \")\"\n\t\t\tbutton.TextScaled = false\n\t\t\tbutton.TextWrapped = true\n\t\t\tbutton.TextSize = 22\n\t\t\tbutton.UIAspectRatioConstraint.AspectRatio = 4\n\t\t\tbutton.Parent = ui.Frame.Results\n\t\t\tupdateInfo(\"TotalFlags\", info.TotalFlags + #r.flags)\n\t\t\tupdateInfo(\"TotalScanned\", info.TotalScanned + 1)\n\t\t\tif r.isExternal > 0 then\n\t\t\t\tupdateInfo(\"ExternalScanned\", info.ExternalScanned + 1)\n\t\t\telse\n\t\t\t\tupdateInfo(\"InternalScanned\", info.InternalScanned + 1)\n\t\t\tend\n\t\t\tif #r.flags > 0 then\n\t\t\t\tbutton.BackgroundColor3 = Color3.new(1,0,0)\n\t\t\t\tbutton:SetAttribute(\"HasFlags\", true)\n\t\t\telse\n\t\t\t\tbutton.BackgroundColor3 = Color3.new(0,1,0)\n\t\t\t\tbutton:SetAttribute(\"HasFlags\", false)\n\t\t\tend\n\t\t\tbutton.MouseButton2Click:Connect(function()\n\t\t\t\tif r.isExternal == 0 then\n\t\t\t\t\tplugin:OpenScript(lastUUIDs[uuid])\n\t\t\t\telse\n\t\t\t\t\tprint(\"Can't open external script. You may view it here: https://www.roblox.com/library/\" .. tostring(r.assetId))\n\t\t\t\tend\n\t\t\tend)\n\t\t\tbutton.MouseButton1Click:Connect(function()\n\t\t\t\tfor i, v in ipairs(ui.Frame.Results:GetChildren()) do\n\t\t\t\t\tif v.Name == \"ListItem\" then\n\t\t\t\t\t\tv:Destroy()\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tlocal titleButton = toClone:Clone()\n\t\t\t\ttitleButton.Name = \"ListItem\"\n\t\t\t\ttitleButton.Text = name .. \" (\" .. getLocationInWorkspace(lastUUIDs[uuid], r) .. \")\"\n\t\t\t\ttitleButton.TextScaled = false\n\t\t\t\ttitleButton.TextWrapped = true\n\t\t\t\ttitleButton.TextSize = 22\n\t\t\t\ttitleButton.UIAspectRatioConstraint.AspectRatio = 4\n\t\t\t\ttitleButton.Parent = ui.Frame.Info\n\t\t\t\ttitleButton.MouseButton1Click:Connect(function()\n\t\t\t\t\tif r.isExternal == 0 then\n\t\t\t\t\t\tplugin:OpenScript(lastUUIDs[uuid])\n\t\t\t\t\telse\n\t\t\t\t\t\tprint(\"Can't open external script. You may view it here: https://www.roblox.com/library/\" .. tostring(r.assetId))\n\t\t\t\t\tend\n\t\t\t\tend)\n\n\t\t\t\tfor i, f in ipairs(r.flags) do\n\t\t\t\t\tlocal flagButton = toClone:Clone()\n\t\t\t\t\tflagButton.Name = \"ListItem\"\n\t\t\t\t\tflagButton.Text = f.reason\n\t\t\t\t\tflagButton.TextScaled = false\n\t\t\t\t\tflagButton.TextWrapped = true\n\t\t\t\t\tflagButton.TextSize = 22\n\t\t\t\t\tflagButton.UIAspectRatioConstraint.AspectRatio = 4\n\t\t\t\t\tflagButton.Parent = ui.Frame.Info\n\t\t\t\t\tflagButton.BackgroundColor3 = Color3.new(1,0,0)\n\t\t\t\t\tflagButton.MouseButton1Click:Connect(function()\n\t\t\t\t\t\tif r.isExternal == 0 then\n\t\t\t\t\t\t\tplugin:OpenScript(lastUUIDs[uuid], f.line)\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tprint(\"Can't open external script. You may view it here: https://www.roblox.com/library/\" .. tostring(r.assetId) .. \" line number: \" .. tostring(f.line))\n\t\t\t\t\t\tend\n\t\t\t\t\tend)\n\t\t\t\tend\n\n\t\t\t\tui.Frame.Results.Visible = false\n\t\t\t\tui.Frame.Info.Visible = true\n\t\t\t\t-- Get more info\n\t\t\tend)\n\t\tend\n\tend\nend\n\nfunction backwardsParent(m, parents)\n\ttable.insert(parents, m.Name)\n\tif m.Parent == nil then\n\t\ttable.insert(parents, \"(Deleted)\")\n\t\treturn\n\tend\n\tif m.Parent ~= game then\n\t\tbackwardsParent(m.Parent, parents)\n\tend\nend\n\nfunction getLocationInWorkspace(m, result)\n\tlocal parents = {}\n\tif m == nil then\n\t\treturn \"External \" .. result.isExternal\n\telseif m.Parent == nil then\n\t\treturn \"Deleted\"\n\telse\n\t\tbackwardsParent(m, parents)\n\tend\n\tlocal hierarchy = \"\"\t\n\tfor i = #parents, 1, -1 do\n\t\thierarchy = hierarchy..parents[i]\n\t\tif i ~= 1 then\n\t\t\thierarchy = hierarchy..\".\"\n\t\tend\n\tend\n\treturn hierarchy\nend\n\nfunction getChunk(arr, startIndex, endIndex)\n\tlocal chunk = {}\n\tfor i = startIndex, endIndex do\n\t\tif arr[i] then\n\t\t\ttable.insert(chunk, arr[i])\n\t\telse\n\t\t\tbreak\n\t\tend\n\tend\n\treturn chunk\nend\n\nfunction chunk(arr, chunkSize)\n\tlocal chunked = {}\n\tfor i = 1, #arr, chunkSize do\n\t\ttable.insert(chunked, getChunk(arr, i, i+chunkSize - 1))\n\tend\n\treturn chunked\nend\n\nfunction topLevel(parent, toPost, curIndex, parentScript)\n\tif parentScript == nil then\n\t\ttable.insert(toPost, {})\n\t\tcurIndex = #toPost\n\tend\n\tfor _, dataModel in ipairs(parent:GetChildren()) do\n\t\tpcall(function()\n\t\t\tif dataModel.Name == \"CoreGui\" then return end\n\t\t\tfor _, child in ipairs(dataModel:GetChildren()) do\n\t\t\t\tif child:IsA(\"LuaSourceContainer\") and not child:IsA(\"CoreScript\") then\n\t\t\t\t\tif CollectionService:HasTag(child, doNotCheckTag) then continue end\n\t\t\t\t\tlocal schema = {[\"Source\"]=child.Source, [\"Children\"]={}, [\"UUID\"]=HttpService:GenerateGUID(false)}\n\t\t\t\t\tlastUUIDs[schema.UUID] = child\n\t\t\t\t\ttable.insert(toPost[curIndex], schema)\n\t\t\t\t\trecurseChildren(child, schema)\n\t\t\t\telse\n\t\t\t\t\tlocal schema = {}\n\t\t\t\t\ttable.insert(toPost[curIndex], schema)\n\t\t\t\t\trecurseChildren(child, schema)\n\t\t\t\t\tif schema.Source == nil then table.remove(toPost[curIndex], #toPost[curIndex]) end\n\t\t\t\tend\n\t\t\tend\n\t\tend)\n\tend\nend\n\nfunction recurseChildren(parent, schema)\n\tfor _, child in ipairs(parent:GetChildren()) do\n\t\tif child:IsA(\"LuaSourceContainer\") and not child:IsA(\"CoreScript\") then\n\t\t\tif CollectionService:HasTag(child, doNotCheckTag) then continue end\n\t\t\tif schema.Source == nil then\n\t\t\t\tschema.Source = child.Source\n\t\t\t\tschema.Children = {}\n\t\t\t\tschema.UUID = HttpService:GenerateGUID(false)\n\t\t\t\tlastUUIDs[schema.UUID] = child\n\t\t\t\trecurseChildren(child, schema)\n\t\t\telse\n\t\t\t\tlocal childSchema = {[\"Source\"]=child.Source, [\"Children\"]={}, [\"UUID\"]=HttpService:GenerateGUID(false)}\n\t\t\t\tlastUUIDs[childSchema.UUID] = child\n\t\t\t\ttable.insert(schema.Children, childSchema)\n\t\t\t\trecurseChildren(child, childSchema)\n\t\t\tend\n\t\telse\n\t\t\trecurseChildren(child, schema)\n\t\tend\n\tend\nend\n\nopenUiButton.Click:Connect(openUi)"
}
},
"SourceAssetId": {
"_propertyType": "int64",
"values": {
"_": "-1"
}
}
},
"_exportInfo": "Exported with rbx-export v1.1.0. Contains all properties of this instance."
}