Created
February 11, 2023 05:37
-
-
Save regginator/d304d73c639a6a495db39a9b60c61eec to your computer and use it in GitHub Desktop.
Dark Dex Packed with Maui
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This script was automatically @generated by Maui, it is not intended for manual editing. | |
local ModuleRoot={{ClassName="LocalScript",Closure=function() -- Dark Dex for Maui | |
local HiddenGuiContainer = (gethui and gethui()) or game:GetService("CoreGui") | |
for _, Object in next, script:GetChildren() do | |
Object.Parent = HiddenGuiContainer | |
end | |
end,Properties={Name="MauiDarkDex"},Reference=1,Children={{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="<",Text="<",TextStrokeTransparency=0.5,Rotation=180,Size=UDim2.new(0,30,0,30),BackgroundTransparency=1,Position=UDim2.new(0,2,0,10),TextStrokeColor3=Color3.new(0.1176470667123795,1,1),TextWrapped=true,TextSize=24,BackgroundColor3=Color3.new(1,1,1)},Reference=141,ClassName="TextLabel"}},Properties={ImageColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574),Image="rbxassetid://1513966937",BackgroundTransparency=1,Position=UDim2.new(1,0,0,0),Name="Toggle",Size=UDim2.new(0,40,0,40),Rotation=180,BackgroundColor3=Color3.new(1,1,1)},Reference=140,ClassName="ImageButton"},{Children={{Closure=function() --[[ | |
Change log: | |
09/18 | |
Fixed checkbox mouseover sprite | |
Encapsulated checkbox creation into separate method | |
Fixed another checkbox issue | |
09/15 | |
Invalid input is ignored instead of setting to default of that data type | |
Consolidated control methods and simplified them | |
All input goes through ToValue method | |
Fixed position of BrickColor palette | |
Made DropDown appear above row if it would otherwise exceed the page height | |
Cleaned up stylesheets | |
09/14 | |
Made properties window scroll when mouse wheel scrolled | |
Object/Instance and Color3 data types handled properly | |
Multiple BrickColor controls interfering with each other fixed | |
Added support for Content data type | |
--]] | |
wait(0.2) | |
local UIS = game:GetService'UserInputService'; | |
local Gui = script.Parent.Parent | |
local PropertiesFrame = Gui:WaitForChild("PropertiesFrame") | |
local ExplorerFrame = Gui:WaitForChild("ExplorerPanel") | |
print = ExplorerFrame:WaitForChild("GetPrint"):Invoke() | |
-- Services | |
local Teams = game:GetService("Teams") | |
local Workspace = game:GetService("Workspace") | |
local Debris = game:GetService("Debris") | |
local ContentProvider = game:GetService("ContentProvider") | |
local Players = game:GetService("Players") | |
local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
-- Functions | |
function httpGet(url) | |
return game:HttpGet(url,true) | |
end | |
-- RbxApi Stuff | |
local apiUrl = "http://anaminus.github.io/rbx/json/api/latest.json" | |
local maxChunkSize = 100 * 1000 | |
local ApiJson | |
if script:FindFirstChild("RawApiJson") then | |
ApiJson = script.RawApiJson | |
else | |
ApiJson = "" | |
end | |
function getLocalApiJson() | |
print(ApiJson) | |
local usels = false | |
local s = pcall(function() if ApiJson.Source ~= "" then usels = true end end) | |
if usels then | |
return loadstring(ApiJson.Source)()() | |
else | |
return require(ApiJson)() | |
end | |
end | |
function getCurrentApiJson() | |
local jsonStr = nil | |
local success | |
if not SetGlobal then | |
success = pcall(function() | |
jsonStr = httpGet(apiUrl) | |
print("Fetched json successfully") | |
end) | |
end | |
if success then | |
print("Returning json") | |
--print(jsonStr:sub(1,500)) | |
return jsonStr | |
else | |
print("Error fetching json: " .. tostring(err)) | |
print("Falling back to local copy") | |
return getLocalApiJson() | |
end | |
end | |
function splitStringIntoChunks(jsonStr) | |
-- Splits up a string into a table with a given size | |
local t = {} | |
for i = 1, math.ceil(string.len(jsonStr)/maxChunkSize) do | |
local str = jsonStr:sub((i-1)*maxChunkSize+1, i*maxChunkSize) | |
table.insert(t, str) | |
end | |
return t | |
end | |
local jsonToParse = getCurrentApiJson() | |
local apiChunks = splitStringIntoChunks(jsonToParse) | |
function getRbxApi() | |
--[[ | |
Api.Classes | |
Api.Enums | |
Api.GetProperties(className) | |
Api.IsEnum(valueType) | |
--]] | |
-- Services | |
local HttpService = game:GetService("HttpService") | |
local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
-- Remotes | |
--local Remotes = ReplicatedStorage:WaitForChild("OnlineStudio"):WaitForChild("Remotes") | |
--local GetApiJsonFunction = Remotes:WaitForChild("GetApiJson") | |
-- Functions | |
local JsonDecode = function(s) return HttpService:JSONDecode(s) end | |
local function GetApiRemoteFunction(index) | |
if (apiChunks[index]) then | |
return apiChunks[index], #apiChunks | |
else | |
print("Bad index for GetApiJson") | |
return nil | |
end | |
end | |
local function getApiJson() | |
local apiTable = {} | |
local firstPage, pageCount = GetApiRemoteFunction(1) | |
table.insert(apiTable, firstPage) | |
for i = 2, pageCount do | |
--print("Fetching API page # " .. tostring(i)) | |
local result = GetApiRemoteFunction(i) | |
table.insert(apiTable, result) | |
end | |
return table.concat(apiTable) | |
end | |
local json = getApiJson() | |
local apiDump = JsonDecode(json) | |
local Classes = {} | |
local Enums = {} | |
local function sortAlphabetic(t, property) | |
table.sort(t, | |
function(x,y) return x[property] < y[property] | |
end) | |
end | |
local function isEnum(name) | |
return Enums[name] ~= nil | |
end | |
local function getProperties(className) | |
local class = Classes[className] | |
local properties = {} | |
if not class then return properties end | |
while class do | |
for _,property in pairs(class.Properties) do | |
table.insert(properties, property) | |
end | |
class = Classes[class.Superclass] | |
end | |
sortAlphabetic(properties, "Name") | |
return properties | |
end | |
for _,item in pairs(apiDump) do | |
local itemType = item.type | |
-- Classes -- | |
if (itemType == 'Class') then | |
Classes[item.Name] = item | |
item.Properties = {} | |
item.Functions = {} | |
item.YieldFunctions = {} | |
item.Events = {} | |
item.Callbacks = {} | |
-- Members -- | |
elseif (itemType == 'Property') then | |
table.insert(Classes[item.Class].Properties, item) | |
elseif (itemType == 'Function') then | |
table.insert(Classes[item.Class].Functions, item) | |
elseif (itemType == 'YieldFunction') then | |
table.insert(Classes[item.Class].YieldFunctions, item) | |
elseif (itemType == 'Event') then | |
table.insert(Classes[item.Class].Events, item) | |
elseif (itemType == 'Callback') then | |
table.insert(Classes[item.Class].Callbacks, item) | |
-- Enums -- | |
elseif (itemType == 'Enum') then | |
Enums[item.Name] = item | |
item.EnumItems = {} | |
elseif (itemType == 'EnumItem') then | |
Enums[item.Enum].EnumItems[item.Name] = item | |
end | |
end | |
return { | |
Classes = Classes; | |
Enums = Enums; | |
GetProperties = getProperties; | |
IsEnum = isEnum; | |
} | |
end | |
-- Modules | |
local Permissions = {CanEdit = true} | |
local RbxApi = getRbxApi() | |
--[[ | |
RbxApi.Classes | |
RbxApi.Enums | |
RbxApi.GetProperties(className) | |
RbxApi.IsEnum(valueType) | |
--]] | |
-- Styles | |
local function CreateColor3(r, g, b) return Color3.new(r/255,g/255,b/255) end | |
local Styles = { | |
Font = Enum.Font.Arial; | |
Margin = 5; | |
Black = CreateColor3(0,0,0); | |
Black2 = CreateColor3(24, 24, 24); | |
White = CreateColor3(244,244,244); | |
Hover = CreateColor3(2, 128, 144); | |
Hover2 = CreateColor3(5, 102, 141); | |
} | |
local Row = { | |
Font = Styles.Font; | |
FontSize = Enum.FontSize.Size14; | |
TextXAlignment = Enum.TextXAlignment.Left; | |
TextColor = Styles.White; | |
TextColorOver = Styles.White; | |
TextLockedColor = CreateColor3(155,155,155); | |
Height = 24; | |
BorderColor = CreateColor3(216/4,216/4,216/4); | |
BackgroundColor = Styles.Black2; | |
BackgroundColorAlternate = CreateColor3(32, 32, 32); | |
BackgroundColorMouseover = CreateColor3(40, 40, 40); | |
TitleMarginLeft = 15; | |
} | |
local DropDown = { | |
Font = Styles.Font; | |
FontSize = Enum.FontSize.Size14; | |
TextColor = CreateColor3(255,255,255); | |
TextColorOver = Styles.White; | |
TextXAlignment = Enum.TextXAlignment.Left; | |
Height = 16; | |
BackColor = Styles.Black2; | |
BackColorOver = Styles.Hover2; | |
BorderColor = CreateColor3(45,45,45); | |
BorderSizePixel = 2; | |
ArrowColor = CreateColor3(160/2,160/2,160/2); | |
ArrowColorOver = Styles.Hover; | |
} | |
local BrickColors = { | |
BoxSize = 13; | |
BorderSizePixel = 1; | |
BorderColor = CreateColor3(160/3,160/3,160/3); | |
FrameColor = CreateColor3(160/3,160/3,160/3); | |
Size = 20; | |
Padding = 4; | |
ColorsPerRow = 8; | |
OuterBorder = 1; | |
OuterBorderColor = Styles.Black; | |
} | |
wait(1) | |
local bindGetSelection = ExplorerFrame.GetSelection | |
local bindSelectionObjectChanged = ExplorerFrame.SelectionObjectChanged | |
local bindGetApi = PropertiesFrame.GetApi | |
local bindGetAwait = PropertiesFrame.GetAwaiting | |
local bindSetAwait = PropertiesFrame.SetAwaiting | |
local ContentUrl = ContentProvider.BaseUrl .. "asset/?id=" | |
local SettingsRemote = Gui:WaitForChild("SettingsPanel"):WaitForChild("GetSetting") | |
local propertiesSearch = PropertiesFrame.Header.TextBox | |
local AwaitingObjectValue = false | |
local AwaitingObjectObj | |
local AwaitingObjectProp | |
function searchingProperties() | |
if propertiesSearch.Text ~= "" and propertiesSearch.Text ~= "Search Properties" then | |
return true | |
end | |
return false | |
end | |
local function GetSelection() | |
local selection = bindGetSelection:Invoke() | |
if #selection == 0 then | |
return nil | |
else | |
return selection | |
end | |
end | |
-- Number | |
local function Round(number, decimalPlaces) | |
return tonumber(string.format("%." .. (decimalPlaces or 0) .. "f", number)) | |
end | |
-- Strings | |
local function Split(str, delimiter) | |
local start = 1 | |
local t = {} | |
while true do | |
local pos = string.find (str, delimiter, start, true) | |
if not pos then | |
break | |
end | |
table.insert (t, string.sub (str, start, pos - 1)) | |
start = pos + string.len (delimiter) | |
end | |
table.insert (t, string.sub (str, start)) | |
return t | |
end | |
-- Data Type Handling | |
local function ToString(value, type) | |
if type == "float" then | |
return tostring(Round(value,2)) | |
elseif type == "Content" then | |
if string.find(value,"/asset") then | |
local match = string.find(value, "=") + 1 | |
local id = string.sub(value, match) | |
return id | |
else | |
return tostring(value) | |
end | |
elseif type == "Vector2" then | |
local x = value.x | |
local y = value.y | |
return string.format("%g, %g", x,y) | |
elseif type == "Vector3" then | |
local x = value.x | |
local y = value.y | |
local z = value.z | |
return string.format("%g, %g, %g", x,y,z) | |
elseif type == "Color3" then | |
local r = value.r | |
local g = value.g | |
local b = value.b | |
return string.format("%d, %d, %d", r*255,g*255,b*255) | |
elseif type == "UDim2" then | |
local xScale = value.X.Scale | |
local xOffset = value.X.Offset | |
local yScale = value.Y.Scale | |
local yOffset = value.Y.Offset | |
return string.format("{%d, %d}, {%d, %d}", xScale, xOffset, yScale, yOffset) | |
else | |
return tostring(value) | |
end | |
end | |
local function ToValue(value,type) | |
if type == "Vector2" then | |
local list = Split(value,",") | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return Vector2.new(x,y) | |
elseif type == "Vector3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
local z = tonumber(list[3]) or 0 | |
return Vector3.new(x,y,z) | |
elseif type == "Color3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local r = tonumber(list[1]) or 0 | |
local g = tonumber(list[2]) or 0 | |
local b = tonumber(list[3]) or 0 | |
return Color3.new(r/255,g/255, b/255) | |
elseif type == "UDim2" then | |
local list = Split(string.gsub(string.gsub(value, "{", ""),"}",""),",") | |
if #list < 4 then return nil end | |
local xScale = tonumber(list[1]) or 0 | |
local xOffset = tonumber(list[2]) or 0 | |
local yScale = tonumber(list[3]) or 0 | |
local yOffset = tonumber(list[4]) or 0 | |
return UDim2.new(xScale, xOffset, yScale, yOffset) | |
elseif type == "Content" then | |
if tonumber(value) ~= nil then | |
value = ContentUrl .. value | |
end | |
return value | |
elseif type == "float" or type == "int" or type == "double" then | |
return tonumber(value) | |
elseif type == "string" then | |
return value | |
elseif type == "NumberRange" then | |
local list = Split(value,",") | |
if #list == 1 then | |
if tonumber(list[1]) == nil then return nil end | |
local newVal = tonumber(list[1]) or 0 | |
return NumberRange.new(newVal) | |
end | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return NumberRange.new(x,y) | |
else | |
return nil | |
end | |
end | |
-- Tables | |
local function CopyTable(T) | |
local t2 = {} | |
for k,v in pairs(T) do | |
t2[k] = v | |
end | |
return t2 | |
end | |
local function SortTable(T) | |
table.sort(T, | |
function(x,y) return x.Name < y.Name | |
end) | |
end | |
-- Spritesheet | |
local Sprite = { | |
Width = 13; | |
Height = 13; | |
} | |
local Spritesheet = { | |
Image = "http://www.roblox.com/asset/?id=128896947"; | |
Height = 256; | |
Width = 256; | |
} | |
local Images = { | |
"unchecked", | |
"checked", | |
"unchecked_over", | |
"checked_over", | |
"unchecked_disabled", | |
"checked_disabled" | |
} | |
local function SpritePosition(spriteName) | |
local x = 0 | |
local y = 0 | |
for i,v in pairs(Images) do | |
if (v == spriteName) then | |
return {x, y} | |
end | |
x = x + Sprite.Height | |
if (x + Sprite.Width) > Spritesheet.Width then | |
x = 0 | |
y = y + Sprite.Height | |
end | |
end | |
end | |
local function GetCheckboxImageName(checked, readOnly, mouseover) | |
if checked then | |
if readOnly then | |
return "checked_disabled" | |
elseif mouseover then | |
return "checked_over" | |
else | |
return "checked" | |
end | |
else | |
if readOnly then | |
return "unchecked_disabled" | |
elseif mouseover then | |
return "unchecked_over" | |
else | |
return "unchecked" | |
end | |
end | |
end | |
local MAP_ID = 418720155 | |
-- Gui Controls -- | |
---- IconMap ---- | |
-- Image size: 256px x 256px | |
-- Icon size: 16px x 16px | |
-- Padding between each icon: 2px | |
-- Padding around image edge: 1px | |
-- Total icons: 14 x 14 (196) | |
local Icon do | |
local iconMap = 'http://www.roblox.com/asset/?id=' .. MAP_ID | |
game:GetService('ContentProvider'):Preload(iconMap) | |
local iconDehash do | |
-- 14 x 14, 0-based input, 0-based output | |
local f=math.floor | |
function iconDehash(h) | |
return f(h/14%14),f(h%14) | |
end | |
end | |
function Icon(IconFrame,index) | |
local row,col = iconDehash(index) | |
local mapSize = Vector2.new(256,256) | |
local pad,border = 2,1 | |
local iconSize = 16 | |
local class = 'Frame' | |
if type(IconFrame) == 'string' then | |
class = IconFrame | |
IconFrame = nil | |
end | |
if not IconFrame then | |
IconFrame = Create(class,{ | |
Name = "Icon"; | |
BackgroundTransparency = 1; | |
ClipsDescendants = true; | |
Create('ImageLabel',{ | |
Name = "IconMap"; | |
Active = false; | |
BackgroundTransparency = 1; | |
Image = iconMap; | |
Size = UDim2.new(mapSize.x/iconSize,0,mapSize.y/iconSize,0); | |
}); | |
}) | |
end | |
IconFrame.IconMap.Position = UDim2.new(-col - (pad*(col+1) + border)/iconSize,0,-row - (pad*(row+1) + border)/iconSize,0) | |
return IconFrame | |
end | |
end | |
local function CreateCell() | |
local tableCell = Instance.new("Frame") | |
tableCell.Size = UDim2.new(0.5, -1, 1, 0) | |
tableCell.BackgroundColor3 = Row.BackgroundColor | |
tableCell.BorderColor3 = Row.BorderColor | |
return tableCell | |
end | |
local function CreateLabel(readOnly) | |
local label = Instance.new("TextLabel") | |
label.Font = Row.Font | |
label.FontSize = Row.FontSize | |
label.TextXAlignment = Row.TextXAlignment | |
label.BackgroundTransparency = 1 | |
if readOnly then | |
label.TextColor3 = Row.TextLockedColor | |
else | |
label.TextColor3 = Row.TextColor | |
end | |
return label | |
end | |
local function CreateTextButton(readOnly, onClick) | |
local button = Instance.new("TextButton") | |
button.Font = Row.Font | |
button.FontSize = Row.FontSize | |
button.TextXAlignment = Row.TextXAlignment | |
button.BackgroundTransparency = 1 | |
if readOnly then | |
button.TextColor3 = Row.TextLockedColor | |
else | |
button.TextColor3 = Row.TextColor | |
button.MouseButton1Click:connect(function() | |
onClick() | |
end) | |
end | |
return button | |
end | |
local function CreateObject(readOnly) | |
local button = Instance.new("TextButton") | |
button.Font = Row.Font | |
button.FontSize = Row.FontSize | |
button.TextXAlignment = Row.TextXAlignment | |
button.BackgroundTransparency = 1 | |
if readOnly then | |
button.TextColor3 = Row.TextLockedColor | |
else | |
button.TextColor3 = Row.TextColor | |
end | |
local cancel = Create(Icon('ImageButton',177),{ | |
Name = "Cancel"; | |
Visible = false; | |
Position = UDim2.new(1,-20,0,0); | |
Size = UDim2.new(0,20,0,20); | |
Parent = button; | |
}) | |
return button | |
end | |
local function CreateTextBox(readOnly) | |
if readOnly then | |
local box = CreateLabel(readOnly) | |
return box | |
else | |
local box = Instance.new("TextBox") | |
if not SettingsRemote:Invoke("ClearProps") then | |
box.ClearTextOnFocus = false | |
end | |
box.Font = Row.Font | |
box.FontSize = Row.FontSize | |
box.TextXAlignment = Row.TextXAlignment | |
box.BackgroundTransparency = 1 | |
box.TextColor3 = Row.TextColor | |
return box | |
end | |
end | |
local function CreateDropDownItem(text, onClick) | |
local button = Instance.new("TextButton") | |
button.Font = DropDown.Font | |
button.FontSize = DropDown.FontSize | |
button.TextColor3 = DropDown.TextColor | |
button.TextXAlignment = DropDown.TextXAlignment | |
button.BackgroundColor3 = DropDown.BackColor | |
button.AutoButtonColor = false | |
button.BorderSizePixel = 0 | |
button.Active = true | |
button.Text = text | |
button.MouseEnter:connect(function() | |
button.TextColor3 = DropDown.TextColorOver | |
button.BackgroundColor3 = DropDown.BackColorOver | |
end) | |
button.MouseLeave:connect(function() | |
button.TextColor3 = DropDown.TextColor | |
button.BackgroundColor3 = DropDown.BackColor | |
end) | |
button.MouseButton1Click:connect(function() | |
onClick(text) | |
end) | |
return button | |
end | |
local function CreateDropDown(choices, currentChoice, readOnly, onClick) | |
local frame = Instance.new("Frame") | |
frame.Name = "DropDown" | |
frame.Size = UDim2.new(1, 0, 1, 0) | |
frame.BackgroundTransparency = 1 | |
frame.Active = true | |
local menu = nil | |
local arrow = nil | |
local expanded = false | |
local margin = DropDown.BorderSizePixel; | |
local button = Instance.new("TextButton") | |
button.Font = Row.Font | |
button.FontSize = Row.FontSize | |
button.TextXAlignment = Row.TextXAlignment | |
button.BackgroundTransparency = 1 | |
button.TextColor3 = Row.TextColor | |
if readOnly then | |
button.TextColor3 = Row.TextLockedColor | |
end | |
button.Text = currentChoice | |
button.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0) | |
button.Position = UDim2.new(0, Styles.Margin, 0, 0) | |
button.Parent = frame | |
local function showArrow(color) | |
if arrow then arrow:Destroy() end | |
local graphicTemplate = Create('Frame',{ | |
Name="Graphic"; | |
BorderSizePixel = 0; | |
BackgroundColor3 = color; | |
}) | |
local graphicSize = 16/2 | |
arrow = ArrowGraphic(graphicSize,'Down',true,graphicTemplate) | |
arrow.Position = UDim2.new(1,-graphicSize * 2,0.5,-graphicSize/2) | |
arrow.Parent = frame | |
end | |
local function hideMenu() | |
expanded = false | |
showArrow(DropDown.ArrowColor) | |
if menu then menu:Destroy() end | |
end | |
local function showMenu() | |
expanded = true | |
menu = Instance.new("Frame") | |
menu.Size = UDim2.new(1, -2 * margin, 0, #choices * DropDown.Height) | |
menu.Position = UDim2.new(0, margin, 0, Row.Height + margin) | |
menu.BackgroundTransparency = 0 | |
menu.BackgroundColor3 = DropDown.BackColor | |
menu.BorderColor3 = DropDown.BorderColor | |
menu.BorderSizePixel = DropDown.BorderSizePixel | |
menu.Active = true | |
menu.ZIndex = 5 | |
menu.Parent = frame | |
local parentFrameHeight = menu.Parent.Parent.Parent.Parent.Size.Y.Offset | |
local rowHeight = menu.Parent.Parent.Parent.Position.Y.Offset | |
if (rowHeight + menu.Size.Y.Offset) > math.max(parentFrameHeight,PropertiesFrame.AbsoluteSize.y) then | |
menu.Position = UDim2.new(0, margin, 0, -1 * (#choices * DropDown.Height) - margin) | |
end | |
local function choice(name) | |
onClick(name) | |
hideMenu() | |
end | |
for i,name in pairs(choices) do | |
local option = CreateDropDownItem(name, function() | |
choice(name) | |
end) | |
option.Size = UDim2.new(1, 0, 0, 16) | |
option.Position = UDim2.new(0, 0, 0, (i - 1) * DropDown.Height) | |
option.ZIndex = menu.ZIndex | |
option.Parent = menu | |
end | |
end | |
showArrow(DropDown.ArrowColor) | |
if not readOnly then | |
button.MouseEnter:connect(function() | |
button.TextColor3 = Row.TextColor | |
showArrow(DropDown.ArrowColorOver) | |
end) | |
button.MouseLeave:connect(function() | |
button.TextColor3 = Row.TextColor | |
if not expanded then | |
showArrow(DropDown.ArrowColor) | |
end | |
end) | |
button.MouseButton1Click:connect(function() | |
if expanded then | |
hideMenu() | |
else | |
showMenu() | |
end | |
end) | |
end | |
return frame,button | |
end | |
local function CreateBrickColor(readOnly, onClick) | |
local frame = Instance.new("Frame") | |
frame.Size = UDim2.new(1,0,1,0) | |
frame.BackgroundTransparency = 1 | |
local colorPalette = Instance.new("Frame") | |
colorPalette.BackgroundTransparency = 0 | |
colorPalette.SizeConstraint = Enum.SizeConstraint.RelativeXX | |
colorPalette.Size = UDim2.new(1, -2 * BrickColors.OuterBorder, 1, -2 * BrickColors.OuterBorder) | |
colorPalette.BorderSizePixel = BrickColors.BorderSizePixel | |
colorPalette.BorderColor3 = BrickColors.BorderColor | |
colorPalette.Position = UDim2.new(0, BrickColors.OuterBorder, 0, BrickColors.OuterBorder + Row.Height) | |
colorPalette.ZIndex = 5 | |
colorPalette.Visible = false | |
colorPalette.BorderSizePixel = BrickColors.OuterBorder | |
colorPalette.BorderColor3 = BrickColors.OuterBorderColor | |
colorPalette.Parent = frame | |
local function show() | |
colorPalette.Visible = true | |
end | |
local function hide() | |
colorPalette.Visible = false | |
end | |
local function toggle() | |
colorPalette.Visible = not colorPalette.Visible | |
end | |
local colorBox = Instance.new("TextButton", frame) | |
colorBox.Position = UDim2.new(0, Styles.Margin, 0, Styles.Margin) | |
colorBox.Size = UDim2.new(0, BrickColors.BoxSize, 0, BrickColors.BoxSize) | |
colorBox.Text = "" | |
colorBox.MouseButton1Click:connect(function() | |
if not readOnly then | |
toggle() | |
end | |
end) | |
if readOnly then | |
colorBox.AutoButtonColor = false | |
end | |
local spacingBefore = (Styles.Margin * 2) + BrickColors.BoxSize | |
local propertyLabel = CreateTextButton(readOnly, function() | |
if not readOnly then | |
toggle() | |
end | |
end) | |
propertyLabel.Size = UDim2.new(1, (-1 * spacingBefore) - Styles.Margin, 1, 0) | |
propertyLabel.Position = UDim2.new(0, spacingBefore, 0, 0) | |
propertyLabel.Parent = frame | |
local size = (1 / BrickColors.ColorsPerRow) | |
for index = 0, 127 do | |
local brickColor = BrickColor.palette(index) | |
local color3 = brickColor.Color | |
local x = size * (index % BrickColors.ColorsPerRow) | |
local y = size * math.floor(index / BrickColors.ColorsPerRow) | |
local brickColorBox = Instance.new("TextButton") | |
brickColorBox.Text = "" | |
brickColorBox.Size = UDim2.new(size,0,size,0) | |
brickColorBox.BackgroundColor3 = color3 | |
brickColorBox.Position = UDim2.new(x, 0, y, 0) | |
brickColorBox.ZIndex = colorPalette.ZIndex | |
brickColorBox.Parent = colorPalette | |
brickColorBox.MouseButton1Click:connect(function() | |
hide() | |
onClick(brickColor) | |
end) | |
end | |
return frame,propertyLabel,colorBox | |
end | |
local function CreateColor3Control(readOnly, onClick) | |
local frame = Instance.new("Frame") | |
frame.Size = UDim2.new(1,0,1,0) | |
frame.BackgroundTransparency = 1 | |
local colorBox = Instance.new("TextButton", frame) | |
colorBox.Position = UDim2.new(0, Styles.Margin, 0, Styles.Margin) | |
colorBox.Size = UDim2.new(0, BrickColors.BoxSize, 0, BrickColors.BoxSize) | |
colorBox.Text = "" | |
colorBox.AutoButtonColor = false | |
local spacingBefore = (Styles.Margin * 2) + BrickColors.BoxSize | |
local box = CreateTextBox(readOnly) | |
box.Size = UDim2.new(1, (-1 * spacingBefore) - Styles.Margin, 1, 0) | |
box.Position = UDim2.new(0, spacingBefore, 0, 0) | |
box.Parent = frame | |
return frame,box,colorBox | |
end | |
function CreateCheckbox(value, readOnly, onClick) | |
local checked = value | |
local mouseover = false | |
local checkboxFrame = Instance.new("ImageButton") | |
checkboxFrame.Size = UDim2.new(0, Sprite.Width, 0, Sprite.Height) | |
checkboxFrame.BackgroundTransparency = 1 | |
checkboxFrame.ClipsDescendants = true | |
--checkboxFrame.Position = UDim2.new(0, Styles.Margin, 0, Styles.Margin) | |
local spritesheetImage = Instance.new("ImageLabel", checkboxFrame) | |
spritesheetImage.Name = "SpritesheetImageLabel" | |
spritesheetImage.Size = UDim2.new(0, Spritesheet.Width, 0, Spritesheet.Height) | |
spritesheetImage.Image = Spritesheet.Image | |
spritesheetImage.BackgroundTransparency = 1 | |
local function updateSprite() | |
local spriteName = GetCheckboxImageName(checked, readOnly, mouseover) | |
local spritePosition = SpritePosition(spriteName) | |
spritesheetImage.Position = UDim2.new(0, -1 * spritePosition[1], 0, -1 * spritePosition[2]) | |
end | |
local function setValue(val) | |
checked = val | |
updateSprite() | |
end | |
if not readOnly then | |
checkboxFrame.MouseEnter:connect(function() mouseover = true updateSprite() end) | |
checkboxFrame.MouseLeave:connect(function() mouseover = false updateSprite() end) | |
checkboxFrame.MouseButton1Click:connect(function() | |
onClick(checked) | |
end) | |
end | |
updateSprite() | |
return checkboxFrame, setValue | |
end | |
-- Code for handling controls of various data types -- | |
local Controls = {} | |
Controls["default"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local propertyType = propertyData["ValueType"] | |
local box = CreateTextBox(readOnly) | |
box.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0) | |
box.Position = UDim2.new(0, Styles.Margin, 0, 0) | |
local function update() | |
local value = object[propertyName] | |
box.Text = ToString(value, propertyType) | |
end | |
if not readOnly then | |
box.FocusLost:connect(function(enterPressed) | |
Set(object, propertyData, ToValue(box.Text,propertyType)) | |
update() | |
end) | |
end | |
update() | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
return box | |
end | |
Controls["bool"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local checked = object[propertyName] | |
local checkbox, setValue = CreateCheckbox(checked, readOnly, function(value) | |
Set(object, propertyData, not checked) | |
end) | |
checkbox.Position = UDim2.new(0, Styles.Margin, 0, Styles.Margin) | |
setValue(checked) | |
local function update() | |
checked = object[propertyName] | |
setValue(checked) | |
end | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
if object:IsA("BoolValue") then | |
object.Changed:connect(function(val) | |
update() | |
end) | |
end | |
update() | |
return checkbox | |
end | |
Controls["BrickColor"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local frame,label,brickColorBox = CreateBrickColor(readOnly, function(brickColor) | |
Set(object, propertyData, brickColor) | |
end) | |
local function update() | |
local value = object[propertyName] | |
brickColorBox.BackgroundColor3 = value.Color | |
label.Text = tostring(value) | |
end | |
update() | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
return frame | |
end | |
Controls["Color3"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local frame,textBox,colorBox = CreateColor3Control(readOnly) | |
textBox.FocusLost:connect(function(enterPressed) | |
Set(object, propertyData, ToValue(textBox.Text,"Color3")) | |
local value = object[propertyName] | |
colorBox.BackgroundColor3 = value | |
textBox.Text = ToString(value, "Color3") | |
end) | |
local function update() | |
local value = object[propertyName] | |
colorBox.BackgroundColor3 = value | |
textBox.Text = ToString(value, "Color3") | |
end | |
update() | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
return frame | |
end | |
Controls["Enum"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local propertyType = propertyData["ValueType"] | |
local enumName = object[propertyName].Name | |
local enumNames = {} | |
for _,enum in pairs(Enum[tostring(propertyType)]:GetEnumItems()) do | |
table.insert(enumNames, enum.Name) | |
end | |
local dropdown, propertyLabel = CreateDropDown(enumNames, enumName, readOnly, function(value) | |
Set(object, propertyData, value) | |
end) | |
--dropdown.Parent = frame | |
local function update() | |
local value = object[propertyName].Name | |
propertyLabel.Text = tostring(value) | |
end | |
update() | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
return dropdown | |
end | |
Controls["Object"] = function(object, propertyData, readOnly) | |
local propertyName = propertyData["Name"] | |
local propertyType = propertyData["ValueType"] | |
local box = CreateObject(readOnly,function()end) | |
box.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0) | |
box.Position = UDim2.new(0, Styles.Margin, 0, 0) | |
local function update() | |
if AwaitingObjectObj == object then | |
if AwaitingObjectValue == true then | |
box.Text = "Select an Object" | |
return | |
end | |
end | |
local value = object[propertyName] | |
box.Text = ToString(value, propertyType) | |
end | |
if not readOnly then | |
box.MouseButton1Click:connect(function() | |
if AwaitingObjectValue then | |
AwaitingObjectValue = false | |
update() | |
return | |
end | |
AwaitingObjectValue = true | |
AwaitingObjectObj = object | |
AwaitingObjectProp = propertyData | |
box.Text = "Select an Object" | |
end) | |
box.Cancel.Visible = true | |
box.Cancel.MouseButton1Click:connect(function() | |
object[propertyName] = nil | |
end) | |
end | |
update() | |
object.Changed:connect(function(property) | |
if (property == propertyName) then | |
update() | |
end | |
end) | |
if object:IsA("ObjectValue") then | |
object.Changed:connect(function(val) | |
update() | |
end) | |
end | |
return box | |
end | |
function GetControl(object, propertyData, readOnly) | |
local propertyType = propertyData["ValueType"] | |
local control = nil | |
if Controls[propertyType] then | |
control = Controls[propertyType](object, propertyData, readOnly) | |
elseif RbxApi.IsEnum(propertyType) then | |
control = Controls["Enum"](object, propertyData, readOnly) | |
elseif RbxApi.Classes[propertyType] then | |
control = Controls["Object"](object, propertyData, readOnly) | |
else | |
control = Controls["default"](object, propertyData, readOnly) | |
end | |
return control | |
end | |
-- Permissions | |
function CanEditObject(object) | |
local player = Players.LocalPlayer | |
local character = player.Character | |
return Permissions.CanEdit | |
end | |
function CanEditProperty(object,propertyData) | |
local tags = propertyData["tags"] | |
for _,name in pairs(tags) do | |
if name == "readonly" then | |
return false | |
end | |
end | |
return CanEditObject(object) | |
end | |
--RbxApi | |
local function PropertyIsHidden(propertyData) | |
local tags = propertyData["tags"] | |
for _,name in pairs(tags) do | |
if name == "deprecated" | |
or name == "hidden" | |
or name == "writeonly" then | |
return true | |
end | |
end | |
return false | |
end | |
function Set(object, propertyData, value) | |
local propertyName = propertyData["Name"] | |
local propertyType = propertyData["ValueType"] | |
if value == nil then return end | |
for i,v in pairs(GetSelection()) do | |
if CanEditProperty(v,propertyData) then | |
pcall(function() | |
--print("Setting " .. propertyName .. " to " .. tostring(value)) | |
v[propertyName] = value | |
end) | |
end | |
end | |
end | |
function CreateRow(object, propertyData, isAlternateRow) | |
local propertyName = propertyData["Name"] | |
local propertyType = propertyData["ValueType"] | |
local propertyValue = object[propertyName] | |
--rowValue, rowValueType, isAlternate | |
local backColor = Row.BackgroundColor; | |
if (isAlternateRow) then | |
backColor = Row.BackgroundColorAlternate | |
end | |
local readOnly = not CanEditProperty(object, propertyData) | |
--if propertyType == "Instance" or propertyName == "Parent" then readOnly = true end | |
local rowFrame = Instance.new("Frame") | |
rowFrame.Size = UDim2.new(1,0,0,Row.Height) | |
rowFrame.BackgroundTransparency = 1 | |
rowFrame.Name = 'Row' | |
local propertyLabelFrame = CreateCell() | |
propertyLabelFrame.Parent = rowFrame | |
propertyLabelFrame.ClipsDescendants = true | |
local propertyLabel = CreateLabel(readOnly) | |
propertyLabel.Text = propertyName | |
propertyLabel.Size = UDim2.new(1, -1 * Row.TitleMarginLeft, 1, 0) | |
propertyLabel.Position = UDim2.new(0, Row.TitleMarginLeft, 0, 0) | |
propertyLabel.Parent = propertyLabelFrame | |
local propertyValueFrame = CreateCell() | |
propertyValueFrame.Size = UDim2.new(0.5, -1, 1, 0) | |
propertyValueFrame.Position = UDim2.new(0.5, 0, 0, 0) | |
propertyValueFrame.Parent = rowFrame | |
local control = GetControl(object, propertyData, readOnly) | |
control.Parent = propertyValueFrame | |
rowFrame.MouseEnter:connect(function() | |
propertyLabelFrame.BackgroundColor3 = Row.BackgroundColorMouseover | |
propertyValueFrame.BackgroundColor3 = Row.BackgroundColorMouseover | |
end) | |
rowFrame.MouseLeave:connect(function() | |
propertyLabelFrame.BackgroundColor3 = backColor | |
propertyValueFrame.BackgroundColor3 = backColor | |
end) | |
rowFrame.InputEnded:connect(function(input) | |
if input.UserInputType.Name == 'MouseButton1' and UIS:IsKeyDown'LeftControl' then | |
if input.Position.X > rowFrame.AbsolutePosition.X and | |
input.Position.Y > rowFrame.AbsolutePosition.Y and | |
input.Position.X < rowFrame.AbsolutePosition.X + rowFrame.AbsoluteSize.X and | |
input.Position.Y < rowFrame.AbsolutePosition.Y + rowFrame.AbsoluteSize.Y then | |
print(pcall(setclipboard, tostring(object[propertyName]))); | |
end | |
end | |
end) | |
propertyLabelFrame.BackgroundColor3 = backColor | |
propertyValueFrame.BackgroundColor3 = backColor | |
return rowFrame | |
end | |
function ClearPropertiesList() | |
for _,instance in pairs(ContentFrame:GetChildren()) do | |
instance:Destroy() | |
end | |
end | |
local selection = Gui:FindFirstChild("Selection", 1) | |
print(selection) | |
function displayProperties(props) | |
for i,v in pairs(props) do | |
pcall(function() | |
local a = CreateRow(v.object, v.propertyData, ((numRows % 2) == 0)) | |
a.Position = UDim2.new(0,0,0,numRows*Row.Height) | |
a.Parent = ContentFrame | |
numRows = numRows + 1 | |
end) | |
end | |
end | |
function checkForDupe(prop,props) | |
for i,v in pairs(props) do | |
if v.propertyData.Name == prop.Name and v.propertyData.ValueType == prop.ValueType then | |
return true | |
end | |
end | |
return false | |
end | |
function sortProps(t) | |
table.sort(t, | |
function(x,y) return x.propertyData.Name < y.propertyData.Name | |
end) | |
end | |
function showProperties(obj) | |
ClearPropertiesList() | |
if obj == nil then return end | |
local propHolder = {} | |
local foundProps = {} | |
numRows = 0 | |
for _,nextObj in pairs(obj) do | |
if not foundProps[nextObj.className] then | |
foundProps[nextObj.className] = true | |
for i,v in pairs(RbxApi.GetProperties(nextObj.className)) do | |
local suc, err = pcall(function() | |
if not (PropertyIsHidden(v)) and not checkForDupe(v,propHolder) then | |
if string.find(string.lower(v.Name),string.lower(propertiesSearch.Text)) or not searchingProperties() then | |
table.insert(propHolder,{propertyData = v, object = nextObj}) | |
end | |
end | |
end) | |
--[[if not suc then | |
warn("Problem getting the value of property " .. v.Name .. " | " .. err) | |
end --]] | |
end | |
end | |
end | |
sortProps(propHolder) | |
displayProperties(propHolder) | |
ContentFrame.Size = UDim2.new(1, 0, 0, numRows * Row.Height) | |
scrollBar.ScrollIndex = 0 | |
scrollBar.TotalSpace = numRows * Row.Height | |
scrollBar.Update() | |
end | |
---------------------------------------------------------------- | |
-----------------------SCROLLBAR STUFF-------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
local ScrollBarWidth = 16 | |
local ScrollStyles = { | |
Background = Color3.fromRGB(43, 43, 43); | |
Border = Color3.fromRGB(20, 20, 20); | |
Selected = Color3.fromRGB(5, 102, 141); | |
BorderSelected = Color3.fromRGB(2, 128, 144); | |
Text = Color3.fromRGB(245, 245, 245); | |
TextDisabled = Color3.fromRGB(188, 188, 188); | |
TextSelected = Color3.fromRGB(255, 255, 255); | |
Button = Color3.fromRGB(33, 33, 33); | |
ButtonBorder = Color3.fromRGB(133, 133, 133); | |
ButtonSelected = Color3.fromRGB(0, 168, 150); | |
Field = Color3.fromRGB(43, 43, 43); | |
FieldBorder = Color3.fromRGB(50, 50, 50); | |
TitleBackground = Color3.fromRGB(11, 11, 11); | |
} | |
do | |
local ZIndexLock = {} | |
function SetZIndex(object,z) | |
if not ZIndexLock[object] then | |
ZIndexLock[object] = true | |
if object:IsA'GuiObject' then | |
object.ZIndex = z | |
end | |
local children = object:GetChildren() | |
for i = 1,#children do | |
SetZIndex(children[i],z) | |
end | |
ZIndexLock[object] = nil | |
end | |
end | |
end | |
function SetZIndexOnChanged(object) | |
return object.Changed:connect(function(p) | |
if p == "ZIndex" then | |
SetZIndex(object,object.ZIndex) | |
end | |
end) | |
end | |
function Create(ty,data) | |
local obj | |
if type(ty) == 'string' then | |
obj = Instance.new(ty) | |
else | |
obj = ty | |
end | |
for k, v in pairs(data) do | |
if type(k) == 'number' then | |
v.Parent = obj | |
else | |
obj[k] = v | |
end | |
end | |
return obj | |
end | |
-- returns the ascendant ScreenGui of an object | |
function GetScreen(screen) | |
if screen == nil then return nil end | |
while not screen:IsA("ScreenGui") do | |
screen = screen.Parent | |
if screen == nil then return nil end | |
end | |
return screen | |
end | |
-- AutoButtonColor doesn't always reset properly | |
function ResetButtonColor(button) | |
local active = button.Active | |
button.Active = not active | |
button.Active = active | |
end | |
function ArrowGraphic(size,dir,scaled,template) | |
local Frame = Create('Frame',{ | |
Name = "Arrow Graphic"; | |
BorderSizePixel = 0; | |
Size = UDim2.new(0,size,0,size); | |
Transparency = 1; | |
}) | |
if not template then | |
template = Instance.new("Frame") | |
template.BorderSizePixel = 0 | |
end | |
template.BackgroundColor3 = Color3.new(1, 1, 1); | |
local transform | |
if dir == nil or dir == 'Up' then | |
function transform(p,s) return p,s end | |
elseif dir == 'Down' then | |
function transform(p,s) return UDim2.new(0,p.X.Offset,0,size-p.Y.Offset-1),s end | |
elseif dir == 'Left' then | |
function transform(p,s) return UDim2.new(0,p.Y.Offset,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end | |
elseif dir == 'Right' then | |
function transform(p,s) return UDim2.new(0,size-p.Y.Offset-1,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end | |
end | |
local scale | |
if scaled then | |
function scale(p,s) return UDim2.new(p.X.Offset/size,0,p.Y.Offset/size,0),UDim2.new(s.X.Offset/size,0,s.Y.Offset/size,0) end | |
else | |
function scale(p,s) return p,s end | |
end | |
local o = math.floor(size/4) | |
if size%2 == 0 then | |
local n = size/2-1 | |
for i = 0,n do | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,n-i,0,o+i), | |
UDim2.new(0,(i+1)*2,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
else | |
local n = (size-1)/2 | |
for i = 0,n do | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,n-i,0,o+i), | |
UDim2.new(0,i*2+1,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
end | |
if size%4 > 1 then | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,0,0,size-o-1), | |
UDim2.new(0,size,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
for i,v in pairs(Frame:GetChildren()) do | |
v.BackgroundColor3 = Color3.new(1, 1, 1); | |
end | |
return Frame | |
end | |
function GripGraphic(size,dir,spacing,scaled,template) | |
local Frame = Create('Frame',{ | |
Name = "Grip Graphic"; | |
BorderSizePixel = 0; | |
Size = UDim2.new(0,size.x,0,size.y); | |
Transparency = 1; | |
}) | |
if not template then | |
template = Instance.new("Frame") | |
template.BorderSizePixel = 0 | |
end | |
spacing = spacing or 2 | |
local scale | |
if scaled then | |
function scale(p) return UDim2.new(p.X.Offset/size.x,0,p.Y.Offset/size.y,0) end | |
else | |
function scale(p) return p end | |
end | |
if dir == 'Vertical' then | |
for i=0,size.x-1,spacing do | |
local t = template:Clone() | |
t.Size = scale(UDim2.new(0,1,0,size.y)) | |
t.Position = scale(UDim2.new(0,i,0,0)) | |
t.Parent = Frame | |
end | |
elseif dir == nil or dir == 'Horizontal' then | |
for i=0,size.y-1,spacing do | |
local t = template:Clone() | |
t.Size = scale(UDim2.new(0,size.x,0,1)) | |
t.Position = scale(UDim2.new(0,0,0,i)) | |
t.Parent = Frame | |
end | |
end | |
return Frame | |
end | |
do | |
local mt = { | |
__index = { | |
GetScrollPercent = function(self) | |
return self.ScrollIndex/(self.TotalSpace-self.VisibleSpace) | |
end; | |
CanScrollDown = function(self) | |
return self.ScrollIndex + self.VisibleSpace < self.TotalSpace | |
end; | |
CanScrollUp = function(self) | |
return self.ScrollIndex > 0 | |
end; | |
ScrollDown = function(self) | |
self.ScrollIndex = self.ScrollIndex + self.PageIncrement | |
self:Update() | |
end; | |
ScrollUp = function(self) | |
self.ScrollIndex = self.ScrollIndex - self.PageIncrement | |
self:Update() | |
end; | |
ScrollTo = function(self,index) | |
self.ScrollIndex = index | |
self:Update() | |
end; | |
SetScrollPercent = function(self,percent) | |
self.ScrollIndex = math.floor((self.TotalSpace - self.VisibleSpace)*percent + 0.5) | |
self:Update() | |
end; | |
}; | |
} | |
mt.__index.CanScrollRight = mt.__index.CanScrollDown | |
mt.__index.CanScrollLeft = mt.__index.CanScrollUp | |
mt.__index.ScrollLeft = mt.__index.ScrollUp | |
mt.__index.ScrollRight = mt.__index.ScrollDown | |
function ScrollBar(horizontal) | |
-- create row scroll bar | |
local ScrollFrame = Create('Frame',{ | |
Name = "ScrollFrame"; | |
Position = horizontal and UDim2.new(0,0,1,-ScrollBarWidth) or UDim2.new(1,-ScrollBarWidth,0,0); | |
Size = horizontal and UDim2.new(1,0,0,ScrollBarWidth) or UDim2.new(0,ScrollBarWidth,1,0); | |
BackgroundTransparency = 1; | |
Create('ImageButton',{ | |
Name = "ScrollDown"; | |
Position = horizontal and UDim2.new(1,-ScrollBarWidth,0,0) or UDim2.new(0,0,1,-ScrollBarWidth); | |
Size = UDim2.new(0, ScrollBarWidth, 0, ScrollBarWidth); | |
BackgroundColor3 = ScrollStyles.Button; | |
BorderColor3 = ScrollStyles.Border; | |
ImageColor3 = Styles.White; | |
--BorderSizePixel = 0; | |
}); | |
Create('ImageButton',{ | |
Name = "ScrollUp"; | |
Size = UDim2.new(0, ScrollBarWidth, 0, ScrollBarWidth); | |
BackgroundColor3 = ScrollStyles.Button; | |
BorderColor3 = ScrollStyles.Border; | |
ImageColor3 = Styles.White; | |
--BorderSizePixel = 0; | |
}); | |
Create('ImageButton',{ | |
Name = "ScrollBar"; | |
Size = horizontal and UDim2.new(1,-ScrollBarWidth*2,1,0) or UDim2.new(1,0,1,-ScrollBarWidth*2); | |
Position = horizontal and UDim2.new(0,ScrollBarWidth,0,0) or UDim2.new(0,0,0,ScrollBarWidth); | |
AutoButtonColor = false; | |
BackgroundColor3 = Color3.new(1/4, 1/4, 1/4); | |
BorderColor3 = ScrollStyles.Border; | |
--BorderSizePixel = 0; | |
Create('ImageButton',{ | |
Name = "ScrollThumb"; | |
AutoButtonColor = false; | |
Size = UDim2.new(0, ScrollBarWidth, 0, ScrollBarWidth); | |
BackgroundColor3 = ScrollStyles.Button; | |
BorderColor3 = ScrollStyles.Border; | |
ImageColor3 = Styles.White; | |
--BorderSizePixel = 0; | |
}); | |
}); | |
}) | |
local graphicTemplate = Create('Frame',{ | |
Name="Graphic"; | |
BorderSizePixel = 0; | |
BackgroundColor3 = Color3.new(1, 1, 1); | |
}) | |
local graphicSize = ScrollBarWidth/2 | |
local ScrollDownFrame = ScrollFrame.ScrollDown | |
local ScrollDownGraphic = ArrowGraphic(graphicSize,horizontal and 'Right' or 'Down',true,graphicTemplate) | |
ScrollDownGraphic.Position = UDim2.new(0.5,-graphicSize/2,0.5,-graphicSize/2) | |
ScrollDownGraphic.Parent = ScrollDownFrame | |
local ScrollUpFrame = ScrollFrame.ScrollUp | |
local ScrollUpGraphic = ArrowGraphic(graphicSize,horizontal and 'Left' or 'Up',true,graphicTemplate) | |
ScrollUpGraphic.Position = UDim2.new(0.5,-graphicSize/2,0.5,-graphicSize/2) | |
ScrollUpGraphic.Parent = ScrollUpFrame | |
local ScrollBarFrame = ScrollFrame.ScrollBar | |
local ScrollThumbFrame = ScrollBarFrame.ScrollThumb | |
do | |
local size = ScrollBarWidth*3/8 | |
local Decal = GripGraphic(Vector2.new(size,size),horizontal and 'Vertical' or 'Horizontal',2,graphicTemplate) | |
Decal.Position = UDim2.new(0.5,-size/2,0.5,-size/2) | |
Decal.Parent = ScrollThumbFrame | |
end | |
local MouseDrag = Create('ImageButton',{ | |
Name = "MouseDrag"; | |
Position = UDim2.new(-0.25,0,-0.25,0); | |
Size = UDim2.new(1.5,0,1.5,0); | |
Transparency = 1; | |
AutoButtonColor = false; | |
Active = true; | |
ZIndex = 10; | |
}) | |
local Class = setmetatable({ | |
GUI = ScrollFrame; | |
ScrollIndex = 0; | |
VisibleSpace = 0; | |
TotalSpace = 0; | |
PageIncrement = 1; | |
},mt) | |
local UpdateScrollThumb | |
if horizontal then | |
function UpdateScrollThumb() | |
ScrollThumbFrame.Size = UDim2.new(Class.VisibleSpace/Class.TotalSpace,0,0,ScrollBarWidth) | |
if ScrollThumbFrame.AbsoluteSize.x < ScrollBarWidth then | |
ScrollThumbFrame.Size = UDim2.new(0,ScrollBarWidth,0,ScrollBarWidth) | |
end | |
local barSize = ScrollBarFrame.AbsoluteSize.x | |
ScrollThumbFrame.Position = UDim2.new(Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.x)/barSize,0,0,0) | |
end | |
else | |
function UpdateScrollThumb() | |
ScrollThumbFrame.Size = UDim2.new(0,ScrollBarWidth,Class.VisibleSpace/Class.TotalSpace,0) | |
if ScrollThumbFrame.AbsoluteSize.y < ScrollBarWidth then | |
ScrollThumbFrame.Size = UDim2.new(0,ScrollBarWidth,0,ScrollBarWidth) | |
end | |
local barSize = ScrollBarFrame.AbsoluteSize.y | |
ScrollThumbFrame.Position = UDim2.new(0,0,Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.y)/barSize,0) | |
end | |
end | |
local lastDown | |
local lastUp | |
local scrollStyle = {BackgroundColor3=Color3.new(1, 1, 1),BackgroundTransparency=0} | |
local scrollStyle_ds = {BackgroundColor3=Color3.new(1, 1, 1),BackgroundTransparency=0.7} | |
local function Update() | |
local t = Class.TotalSpace | |
local v = Class.VisibleSpace | |
local s = Class.ScrollIndex | |
if v <= t then | |
if s > 0 then | |
if s + v > t then | |
Class.ScrollIndex = t - v | |
end | |
else | |
Class.ScrollIndex = 0 | |
end | |
else | |
Class.ScrollIndex = 0 | |
end | |
if Class.UpdateCallback then | |
if Class.UpdateCallback(Class) == false then | |
return | |
end | |
end | |
local down = Class:CanScrollDown() | |
local up = Class:CanScrollUp() | |
if down ~= lastDown then | |
lastDown = down | |
ScrollDownFrame.Active = down | |
ScrollDownFrame.AutoButtonColor = down | |
local children = ScrollDownGraphic:GetChildren() | |
local style = down and scrollStyle or scrollStyle_ds | |
for i = 1,#children do | |
Create(children[i],style) | |
end | |
end | |
if up ~= lastUp then | |
lastUp = up | |
ScrollUpFrame.Active = up | |
ScrollUpFrame.AutoButtonColor = up | |
local children = ScrollUpGraphic:GetChildren() | |
local style = up and scrollStyle or scrollStyle_ds | |
for i = 1,#children do | |
Create(children[i],style) | |
end | |
end | |
ScrollThumbFrame.Visible = down or up | |
UpdateScrollThumb() | |
end | |
Class.Update = Update | |
SetZIndexOnChanged(ScrollFrame) | |
local scrollEventID = 0 | |
ScrollDownFrame.MouseButton1Down:connect(function() | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollDownFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
Class:ScrollDown() | |
wait(0.2) -- delay before auto scroll | |
while scrollEventID == current do | |
Class:ScrollDown() | |
if not Class:CanScrollDown() then break end | |
wait() | |
end | |
end) | |
ScrollDownFrame.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
end) | |
ScrollUpFrame.MouseButton1Down:connect(function() | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
Class:ScrollUp() | |
wait(0.2) | |
while scrollEventID == current do | |
Class:ScrollUp() | |
if not Class:CanScrollUp() then break end | |
wait() | |
end | |
end) | |
ScrollUpFrame.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
end) | |
if horizontal then | |
ScrollBarFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
if x > ScrollThumbFrame.AbsolutePosition.x then | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if x < ScrollThumbFrame.AbsolutePosition.x + ScrollThumbFrame.AbsoluteSize.x then break end | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait() | |
end | |
else | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if x > ScrollThumbFrame.AbsolutePosition.x then break end | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait() | |
end | |
end | |
end) | |
else | |
ScrollBarFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
if y > ScrollThumbFrame.AbsolutePosition.y then | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if y < ScrollThumbFrame.AbsolutePosition.y + ScrollThumbFrame.AbsoluteSize.y then break end | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait() | |
end | |
else | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if y > ScrollThumbFrame.AbsolutePosition.y then break end | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait() | |
end | |
end | |
end) | |
end | |
if horizontal then | |
ScrollThumbFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local mouse_offset = x - ScrollThumbFrame.AbsolutePosition.x | |
local drag_con | |
local up_con | |
drag_con = MouseDrag.MouseMoved:connect(function(x,y) | |
local bar_abs_pos = ScrollBarFrame.AbsolutePosition.x | |
local bar_drag = ScrollBarFrame.AbsoluteSize.x - ScrollThumbFrame.AbsoluteSize.x | |
local bar_abs_one = bar_abs_pos + bar_drag | |
x = x - mouse_offset | |
x = x < bar_abs_pos and bar_abs_pos or x > bar_abs_one and bar_abs_one or x | |
x = x - bar_abs_pos | |
Class:SetScrollPercent(x/(bar_drag)) | |
end) | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollThumbFrame) | |
drag_con:disconnect(); drag_con = nil | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
end) | |
else | |
ScrollThumbFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local mouse_offset = y - ScrollThumbFrame.AbsolutePosition.y | |
local drag_con | |
local up_con | |
drag_con = MouseDrag.MouseMoved:connect(function(x,y) | |
local bar_abs_pos = ScrollBarFrame.AbsolutePosition.y | |
local bar_drag = ScrollBarFrame.AbsoluteSize.y - ScrollThumbFrame.AbsoluteSize.y | |
local bar_abs_one = bar_abs_pos + bar_drag | |
y = y - mouse_offset | |
y = y < bar_abs_pos and bar_abs_pos or y > bar_abs_one and bar_abs_one or y | |
y = y - bar_abs_pos | |
Class:SetScrollPercent(y/(bar_drag)) | |
end) | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollThumbFrame) | |
drag_con:disconnect(); drag_con = nil | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
end) | |
end | |
function Class:Destroy() | |
ScrollFrame:Destroy() | |
MouseDrag:Destroy() | |
for k in pairs(Class) do | |
Class[k] = nil | |
end | |
setmetatable(Class,nil) | |
end | |
Update() | |
return Class | |
end | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
local MainFrame = Instance.new("Frame") | |
MainFrame.Name = "MainFrame" | |
MainFrame.Size = UDim2.new(1, -1 * ScrollBarWidth, 1, 0) | |
MainFrame.Position = UDim2.new(0, 0, 0, 0) | |
MainFrame.BackgroundTransparency = 1 | |
MainFrame.ClipsDescendants = true | |
MainFrame.Parent = PropertiesFrame | |
ContentFrame = Instance.new("Frame") | |
ContentFrame.Name = "ContentFrame" | |
ContentFrame.Size = UDim2.new(1, 0, 0, 0) | |
ContentFrame.BackgroundTransparency = 1 | |
ContentFrame.Parent = MainFrame | |
scrollBar = ScrollBar(false) | |
scrollBar.PageIncrement = 1 | |
Create(scrollBar.GUI,{ | |
Position = UDim2.new(1,-ScrollBarWidth,0,0); | |
Size = UDim2.new(0,ScrollBarWidth,1,0); | |
Parent = PropertiesFrame; | |
}) | |
scrollBarH = ScrollBar(true) | |
scrollBarH.PageIncrement = ScrollBarWidth | |
Create(scrollBarH.GUI,{ | |
Position = UDim2.new(0,0,1,-ScrollBarWidth); | |
Size = UDim2.new(1,-ScrollBarWidth,0,ScrollBarWidth); | |
Visible = false; | |
Parent = PropertiesFrame; | |
}) | |
do | |
local listEntries = {} | |
local nameConnLookup = {} | |
function scrollBar.UpdateCallback(self) | |
scrollBar.TotalSpace = ContentFrame.AbsoluteSize.Y | |
scrollBar.VisibleSpace = MainFrame.AbsoluteSize.Y | |
ContentFrame.Position = UDim2.new(ContentFrame.Position.X.Scale,ContentFrame.Position.X.Offset,0,-1*scrollBar.ScrollIndex) | |
end | |
function scrollBarH.UpdateCallback(self) | |
end | |
MainFrame.Changed:connect(function(p) | |
if p == 'AbsoluteSize' then | |
scrollBarH.VisibleSpace = math.ceil(MainFrame.AbsoluteSize.x) | |
scrollBarH:Update() | |
scrollBar.VisibleSpace = math.ceil(MainFrame.AbsoluteSize.y) | |
scrollBar:Update() | |
end | |
end) | |
local wheelAmount = Row.Height | |
PropertiesFrame.MouseWheelForward:connect(function() | |
if UIS:IsKeyDown'LeftShift' then | |
if scrollBarH.VisibleSpace - 1 > wheelAmount then | |
scrollBarH:ScrollTo(scrollBarH.ScrollIndex - wheelAmount) | |
else | |
scrollBarH:ScrollTo(scrollBarH.ScrollIndex - scrollBarH.VisibleSpace) | |
end | |
else | |
if scrollBar.VisibleSpace - 1 > wheelAmount then | |
scrollBar:ScrollTo(scrollBar.ScrollIndex - wheelAmount) | |
else | |
scrollBar:ScrollTo(scrollBar.ScrollIndex - scrollBar.VisibleSpace) | |
end | |
end | |
end) | |
PropertiesFrame.MouseWheelBackward:connect(function() | |
if UIS:IsKeyDown'LeftShift' then | |
if scrollBarH.VisibleSpace - 1 > wheelAmount then | |
scrollBarH:ScrollTo(scrollBarH.ScrollIndex + wheelAmount) | |
else | |
scrollBarH:ScrollTo(scrollBarH.ScrollIndex + scrollBarH.VisibleSpace) | |
end | |
else | |
if scrollBar.VisibleSpace - 1 > wheelAmount then | |
scrollBar:ScrollTo(scrollBar.ScrollIndex + wheelAmount) | |
else | |
scrollBar:ScrollTo(scrollBar.ScrollIndex + scrollBar.VisibleSpace) | |
end | |
end | |
end) | |
end | |
scrollBar.VisibleSpace = math.ceil(MainFrame.AbsoluteSize.y) | |
scrollBar:Update() | |
showProperties(GetSelection()) | |
bindSelectionObjectChanged.Event:connect(function() | |
showProperties(GetSelection()) | |
end) | |
bindSetAwait.Event:connect(function(obj) | |
if AwaitingObjectValue then | |
AwaitingObjectValue = false | |
local mySel = obj | |
if mySel then | |
pcall(function() | |
Set(AwaitingObjectObj, AwaitingObjectProp, mySel) | |
end) | |
end | |
end | |
end) | |
propertiesSearch.Changed:connect(function(prop) | |
if prop == "Text" then | |
showProperties(GetSelection()) | |
end | |
end) | |
bindGetApi.OnInvoke = function() | |
return RbxApi | |
end | |
bindGetAwait.OnInvoke = function() | |
return AwaitingObjectValue | |
end end,Properties={Disabled=true,Name="Properties"},Reference=4,ClassName="LocalScript"},{Properties={Name="GetApi"},Reference=8,ClassName="BindableFunction"},{Properties={Name="GetAwaiting"},Reference=9,ClassName="BindableFunction"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.9098039865493774,0.9098039865493774,0.9098039865493774),Text="",TextStrokeTransparency=0.75,BackgroundTransparency=0.800000011920929,TextXAlignment=Enum.TextXAlignment.Left,Position=UDim2.new(0,4,0.5,0),PlaceholderText="Search Properties",TextSize=14,Size=UDim2.new(1,-8,0.5,-3)},Reference=7,ClassName="TextBox"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Properties",Text="Properties",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,BorderColor3=Color3.new(1,1,1),Position=UDim2.new(0,4,0,0),TextSize=14,Size=UDim2.new(1,-4,0.5,0)},Reference=6,ClassName="TextLabel"}},Properties={Name="Header",Position=UDim2.new(0,0,0,-36),BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(1,0,0,36),BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=5,ClassName="Frame"},{Properties={Name="SetAwaiting"},Reference=10,ClassName="BindableEvent"}},Properties={Name="PropertiesFrame",Size=UDim2.new(0,300,0.5,-36),BackgroundTransparency=0.1000000014901161,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Position=UDim2.new(1,0,0.5,36),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=3,ClassName="Frame"},{Children={{Closure=function() local editor = script.Parent; | |
local bindable = editor:WaitForChild("OpenScript"); | |
local SaveScript = editor:WaitForChild("TopBar"):WaitForChild("Other"):WaitForChild('SaveScript') | |
local CopyScript = editor:WaitForChild("TopBar"):WaitForChild("Other"):WaitForChild('CopyScript'); | |
local ClearScript = editor:WaitForChild("TopBar"):WaitForChild("Other"):WaitForChild('ClearScript'); | |
local CloseEditor = editor:WaitForChild("TopBar"):WaitForChild("Close"); | |
local FileName = editor:WaitForChild("TopBar"):WaitForChild("Other"):WaitForChild('FileName'); | |
local Title = editor:WaitForChild("TopBar"):WaitForChild("title"); | |
local cache = {}; | |
local GetDebugId = game.GetDebugId; | |
local dragger = {}; do | |
local mouse = game:GetService("Players").LocalPlayer:GetMouse(); | |
local inputService = game:GetService('UserInputService'); | |
local heartbeat = game:GetService("RunService").Heartbeat; | |
-- // credits to Ririchi / Inori for this cute drag function :) | |
function dragger.new(frame) | |
frame.Draggable = false; | |
local s, event = pcall(function() | |
return frame.MouseEnter | |
end) | |
if s then | |
frame.Active = true; | |
event:connect(function() | |
local input = frame.InputBegan:connect(function(key) | |
if key.UserInputType == Enum.UserInputType.MouseButton1 then | |
local objectPosition = Vector2.new(mouse.X - frame.AbsolutePosition.X, mouse.Y - frame.AbsolutePosition.Y); | |
while heartbeat:wait() and inputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do | |
pcall(function() | |
frame:TweenPosition(UDim2.new(0, mouse.X - objectPosition.X + (frame.Size.X.Offset * frame.AnchorPoint.X), 0, mouse.Y - objectPosition.Y + (frame.Size.Y.Offset * frame.AnchorPoint.Y)), 'Out', 'Quad', 0.1, true); | |
end) | |
end | |
end | |
end) | |
local leave; | |
leave = frame.MouseLeave:connect(function() | |
input:disconnect(); | |
leave:disconnect(); | |
end) | |
end) | |
end | |
end | |
end | |
dragger.new(editor) | |
local newline, tab = "\n", "\t" | |
local TabText = (" "):rep(4) | |
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil | |
local sub, gsub, match, gmatch, find = string.sub, string.gsub, string.match, string.gmatch, string.find | |
local toNumber = tonumber | |
local udim2 = UDim2.new | |
local newInst = Instance.new | |
local SplitCacheResult, SplitCacheStr, SplitCacheDel | |
function Split(str, del) | |
if SplitCacheStr == str and SplitCacheDel == del then | |
return SplitCacheResult | |
end | |
local res = {} | |
if #del == 0 then | |
for i in gmatch(str, ".") do | |
res[#res + 1] = i | |
end | |
else | |
local i = 0 | |
local Si = 1 | |
local si | |
str = str .. del | |
while i do | |
si, Si, i = i, find(str, del, i + 1, true) | |
if i == nil then | |
return res | |
end | |
res[#res + 1] = sub(str, si + 1, Si - 1) | |
end | |
end | |
SplitCacheResult, SplitCacheStr, SplitCacheDel = res, str, del | |
return res | |
end | |
local Place = {} | |
function Place.new(X, Y) | |
return {X = X, Y = Y} | |
end | |
local Lexer; do | |
local find, match, rep, sub = string.find, string.match, string.rep, string.sub | |
local lua_builtin = { | |
"assert", | |
"collectgarbage", | |
"error", | |
"_G", | |
"gcinfo", | |
"getfenv", | |
"getmetatable", | |
"ipairs", | |
"loadstring", | |
"newproxy", | |
"next", | |
"pairs", | |
"pcall", | |
"print", | |
"rawequal", | |
"rawget", | |
"rawset", | |
"select", | |
"setfenv", | |
"setmetatable", | |
"tonumber", | |
"tostring", | |
"type", | |
"unpack", | |
"_VERSION", | |
"xpcall", | |
"delay", | |
"elapsedTime", | |
"require", | |
"spawn", | |
"tick", | |
"time", | |
"typeof", | |
"UserSettings", | |
"wait", | |
"warn", | |
"game", | |
"Enum", | |
"script", | |
"shared", | |
"workspace", | |
"Axes", | |
"BrickColor", | |
"CFrame", | |
"Color3", | |
"ColorSequence", | |
"ColorSequenceKeypoint", | |
"Faces", | |
"Instance", | |
"NumberRange", | |
"NumberSequence", | |
"NumberSequenceKeypoint", | |
"PhysicalProperties", | |
"Random", | |
"Ray", | |
"Rect", | |
"Region3", | |
"Region3int16", | |
"TweenInfo", | |
"UDim", | |
"UDim2", | |
"Vector2", | |
"Vector3", | |
"Vector3int16", | |
"next", | |
"os", | |
"os.time", | |
"os.date", | |
"os.difftime", | |
"debug", | |
"debug.traceback", | |
"debug.profilebegin", | |
"debug.profileend", | |
"math", | |
"math.abs", | |
"math.acos", | |
"math.asin", | |
"math.atan", | |
"math.atan2", | |
"math.ceil", | |
"math.clamp", | |
"math.cos", | |
"math.cosh", | |
"math.deg", | |
"math.exp", | |
"math.floor", | |
"math.fmod", | |
"math.frexp", | |
"math.ldexp", | |
"math.log", | |
"math.log10", | |
"math.max", | |
"math.min", | |
"math.modf", | |
"math.noise", | |
"math.pow", | |
"math.rad", | |
"math.random", | |
"math.randomseed", | |
"math.sign", | |
"math.sin", | |
"math.sinh", | |
"math.sqrt", | |
"math.tan", | |
"math.tanh", | |
"coroutine", | |
"coroutine.create", | |
"coroutine.resume", | |
"coroutine.running", | |
"coroutine.status", | |
"coroutine.wrap", | |
"coroutine.yield", | |
"string", | |
"string.byte", | |
"string.char", | |
"string.dump", | |
"string.find", | |
"string.format", | |
"string.len", | |
"string.lower", | |
"string.match", | |
"string.rep", | |
"string.reverse", | |
"string.sub", | |
"string.upper", | |
"string.gmatch", | |
"string.gsub", | |
"table", | |
"table.concat", | |
"table.insert", | |
"table.remove", | |
"table.sort" | |
} | |
local Keywords = { | |
["and"] = true, | |
["break"] = true, | |
["do"] = true, | |
["else"] = true, | |
["elseif"] = true, | |
["end"] = true, | |
["false"] = true, | |
["for"] = true, | |
["function"] = true, | |
["if"] = true, | |
["in"] = true, | |
["local"] = true, | |
["nil"] = true, | |
["not"] = true, | |
["or"] = true, | |
["repeat"] = true, | |
["return"] = true, | |
["then"] = true, | |
["true"] = true, | |
["until"] = true, | |
["while"] = true; | |
["self"] = true; | |
} | |
local Tokens = { | |
Comment = 1, | |
Keyword = 2, | |
Number = 3, | |
Operator = 4, | |
String = 5, | |
Identifier = 6, | |
Builtin = 7, | |
Symbol = 19400 | |
} | |
local Stream; do | |
local sub, newline = string.sub, "\n" | |
function Stream(Input, FileName) | |
local Index = 1 | |
local Line = 1 | |
local Column = 0 | |
FileName = FileName or "{none}" | |
local cols = {} | |
local function Back() | |
Index = Index - 1 | |
local Char = sub(Input, Index, Index) | |
if Char == newline then | |
Line = Line - 1 | |
Column = cols[#cols] | |
cols[#cols] = nil | |
else | |
Column = Column - 1 | |
end | |
end | |
local function Next() | |
local Char = sub(Input, Index, Index) | |
Index = Index + 1 | |
if Char == newline then | |
Line = Line + 1 | |
cols[#cols + 1] = Column | |
Column = 0 | |
else | |
Column = Column + 1 | |
end | |
return Char, { | |
Index = Index, | |
Line = Line, | |
Column = Column, | |
File = FileName | |
} | |
end | |
local function Peek(length) | |
return sub(Input, Index, Index + (length or 1) - 1) | |
end | |
local function EOF() | |
return Index > #Input | |
end | |
local function Fault(Error) | |
error(Error .. " (col " .. Column .. ", ln " .. Line .. ", file " .. FileName .. ")", 0) | |
end | |
return { | |
Back = Back, | |
Next = Next, | |
Peek = Peek, | |
EOF = EOF, | |
Fault = Fault | |
} | |
end | |
end | |
local idenCheck, numCheck, opCheck = "abcdefghijklmnopqrstuvwxyz_", "0123456789", "+-*/%^#~=<>(){}[];:,." | |
local blank, dot, equal, openbrak, closebrak, newline, backslash, dash, quote, apos = "", ".", "=", "[", "]", "\n", "\\", "-", "\"", "'" | |
function Lexer(Code) | |
local Input = Stream(Code) | |
local Current, LastToken, self | |
local Clone = function(Table) | |
local R = {} | |
for K, V in pairs(Table) do | |
R[K] = V | |
end | |
return R | |
end | |
for Key, Value in pairs(Clone(Tokens)) do | |
Tokens[Value] = Key | |
end | |
local function Check(Value, Type, Start) | |
if Type == Tokens.Identifier then | |
return find(idenCheck, Value:lower(), 1, true) ~= nil or not Start and find(numCheck, Value, 1, true) ~= nil | |
elseif Type == Tokens.Keyword then | |
if Keywords[Value] then | |
return true | |
end | |
return false | |
elseif Type == Tokens.Number then | |
if Value == "." and not Start then | |
return true | |
end | |
return find(numCheck, Value, 1, true) ~= nil | |
elseif Type == Tokens.Operator then | |
return find(opCheck, Value, 1, true) ~= nil | |
end | |
end | |
local function Next() | |
if Current ~= nil then | |
local Token = Current | |
Current = nil | |
return Token | |
end | |
if Input.EOF() then | |
return nil | |
end | |
local Char, DebugInfo = Input.Next() | |
local Result = { | |
Type = Tokens.Symbol | |
} | |
local sValue = Char | |
for i = 0, 256 do | |
local open = openbrak .. rep(equal, i) .. openbrak | |
if Char .. Input.Peek(#open - 1) == open then | |
self.StringDepth = i + 1 | |
break | |
end | |
end | |
local resulting = false | |
if 0 < self.StringDepth then | |
local closer = closebrak .. rep(equal, self.StringDepth - 1) .. closebrak | |
Input.Back() | |
local Value = blank | |
while not Input.EOF() and Input.Peek(#closer) ~= closer do | |
Char, DebugInfo = Input.Next() | |
Value = Value .. Char | |
end | |
if Input.Peek(#closer) == closer then | |
for i = 1, #closer do | |
Value = Value .. Input.Next() | |
end | |
self.StringDepth = 0 | |
end | |
Result.Value = Value | |
Result.Type = Tokens.String | |
resulting = true | |
elseif 0 < self.CommentDepth then | |
local closer = closebrak .. rep(equal, self.CommentDepth - 1) .. closebrak | |
Input.Back() | |
local Value = blank | |
while not Input.EOF() and Input.Peek(#closer) ~= closer do | |
Char, DebugInfo = Input.Next() | |
Value = Value .. Char | |
end | |
if Input.Peek(#closer) == closer then | |
for i = 1, #closer do | |
Value = Value .. Input.Next() | |
end | |
self.CommentDepth = 0 | |
end | |
Result.Value = Value | |
Result.Type = Tokens.Comment | |
resulting = true | |
end | |
local skip = 1 | |
for i = 1, #lua_builtin do | |
local k = lua_builtin[i] | |
if Input.Peek(#k - 1) == sub(k, 2) and Char == sub(k, 1, 1) and skip < #k then | |
Result.Type = Tokens.Builtin | |
Result.Value = k | |
skip = #k | |
resulting = true | |
end | |
end | |
for i = 1, skip - 1 do | |
Char, DebugInfo = Input.Next() | |
end | |
if resulting then | |
elseif Check(Char, Tokens.Identifier, true) then | |
local Value = Char | |
while Check(Input.Peek(), Tokens.Identifier) and not Input.EOF() do | |
Value = Value .. Input.Next() | |
end | |
if Check(Value, Tokens.Keyword) then | |
Result.Type = Tokens.Keyword | |
else | |
Result.Type = Tokens.Identifier | |
end | |
Result.Value = Value | |
elseif Char == dash and Input.Peek() == dash then | |
local Value = Char .. Input.Next() | |
for i = 0, 256 do | |
local open = openbrak .. rep(equal, i) .. openbrak | |
if Input.Peek(#open) == open then | |
self.CommentDepth = i + 1 | |
break | |
end | |
end | |
if 0 < self.CommentDepth then | |
local closer = closebrak .. rep(equal, self.CommentDepth - 1) .. closebrak | |
while not Input.EOF() and Input.Peek(#closer) ~= closer do | |
Char, DebugInfo = Input.Next() | |
Value = Value .. Char | |
end | |
if Input.Peek(#closer) == closer then | |
for i = 1, #closer do | |
Value = Value .. Input.Next() | |
end | |
self.CommentDepth = 0 | |
end | |
else | |
while not Input.EOF() and not find(newline, Char, 1, true) do | |
Char, DebugInfo = Input.Next() | |
Value = Value .. Char | |
end | |
end | |
Result.Value = Value | |
Result.Type = Tokens.Comment | |
elseif Check(Char, Tokens.Number, true) or Char == dot and Check(Input.Peek(), Tokens.Number, true) then | |
local Value = Char | |
while Check(Input.Peek(), Tokens.Number) and not Input.EOF() do | |
Value = Value .. Input.Next() | |
end | |
Result.Value = Value | |
Result.Type = Tokens.Number | |
elseif Char == quote then | |
local Escaped = false | |
local String = blank | |
Result.Value = quote | |
while not Input.EOF() do | |
local Char = Input.Next() | |
Result.Value = Result.Value .. Char | |
if Escaped then | |
String = String .. Char | |
Escaped = false | |
elseif Char == backslash then | |
Escaped = true | |
elseif Char == quote or Char == newline then | |
break | |
else | |
String = String .. Char | |
end | |
end | |
Result.Type = Tokens.String | |
elseif Char == apos then | |
local Escaped = false | |
local String = blank | |
Result.Value = apos | |
while not Input.EOF() do | |
local Char = Input.Next() | |
Result.Value = Result.Value .. Char | |
if Escaped then | |
String = String .. Char | |
Escaped = false | |
elseif Char == backslash then | |
Escaped = true | |
elseif Char == apos or Char == newline then | |
break | |
else | |
String = String .. Char | |
end | |
end | |
Result.Type = Tokens.String | |
elseif Check(Char, Tokens.Operator) then | |
Result.Value = Char | |
Result.Type = Tokens.Operator | |
else | |
Result.Value = Char | |
end | |
Result.TypeName = Tokens[Result.Type] | |
LastToken = Result | |
return Result | |
end | |
local function Peek() | |
local Result = Next() | |
Current = Result | |
return Result | |
end | |
local function EOF() | |
return Peek() == nil | |
end | |
local function GetLast() | |
return LastToken | |
end | |
self = { | |
Next = Next, | |
Peek = Peek, | |
EOF = EOF, | |
GetLast = GetLast, | |
CommentDepth = 0, | |
StringDepth = 0 | |
} | |
return self | |
end | |
end | |
function Place.fromIndex(CodeEditor, Index) | |
local cache = CodeEditor.PlaceCache | |
local fromCache | |
if cache.fromIndex then | |
fromCache = cache.fromIndex | |
else | |
fromCache = {} | |
cache.fromIndex = fromCache | |
end | |
if fromCache[Index] then | |
end | |
local Content = CodeEditor.Content | |
local ContentUpto = sub(Content, 1, Index) | |
if Index == 0 then | |
return Place.new(0, 0) | |
end | |
local Lines = Split(ContentUpto, newline) | |
local res = Place.new(#gsub(Lines[#Lines], tab, TabText), #Lines - 1) | |
fromCache[Index] = res | |
return res | |
end | |
function Place.toIndex(CodeEditor, Place) | |
local cache = CodeEditor.PlaceCache | |
local toCache | |
if cache.toIndex then | |
toCache = cache.toIndex | |
else | |
toCache = {} | |
cache.toIndex = toCache | |
end | |
local Content = CodeEditor.Content | |
if Place.X == 0 and Place.Y == 0 then | |
return 0 | |
end | |
local Lines = CodeEditor.Lines | |
local Index = 0 | |
for I = 1, Place.Y do | |
Index = Index + #Lines[I] + 1 | |
end | |
local line = Lines[Place.Y + 1] | |
local roundedX = Place.X | |
local ix = 0 | |
for i = 1, #line do | |
local c = sub(line, i, i) | |
local pix = ix | |
if c == tab then | |
ix = ix + #TabText | |
else | |
ix = ix + 1 | |
end | |
if Place.X == ix then | |
roundedX = i | |
elseif pix < Place.X and ix > Place.X then | |
if Place.X - pix < ix - Place.X then | |
roundedX = i - 1 | |
else | |
roundedX = i | |
end | |
end | |
end | |
local res = Index + min(#line, roundedX) | |
toCache[Place.X .. "-$-" .. Place.Y] = res | |
return res | |
end | |
local Selection = {} | |
local Side = {Left = 1, Right = 2} | |
function Selection.new(Start, End, CaretSide) | |
return { | |
Start = Start, | |
End = End, | |
Side = CaretSide | |
} | |
end | |
local Themes = { | |
Plain = { | |
LineSelection = Color3.fromRGB(46, 46, 46), | |
SelectionBackground = Color3.fromRGB(118, 118, 118), | |
SelectionColor = Color3.fromRGB(10, 10, 10), | |
SelectionGentle = Color3.fromRGB(46, 46, 46); | |
Background = Color3.fromRGB(40, 41, 35), | |
Comment = Color3.fromRGB(117, 113, 94), | |
Keyword = Color3.fromRGB(249, 38, 114), | |
Builtin = Color3.fromRGB(83, 220, 205), | |
Number = Color3.fromRGB(174, 129, 255), | |
Operator = Color3.fromRGB(182, 151, 135), | |
String = Color3.fromRGB(230, 219, 116), | |
Text = Color3.fromRGB(255, 255, 255); | |
SelectionBackground = Color3.fromRGB(150, 150, 150), | |
SelectionColor = Color3.fromRGB(0, 0, 0), | |
SelectionGentle = Color3.fromRGB(65, 65, 65) | |
} | |
} | |
local EditorLib = {} | |
EditorLib.Place = Place | |
EditorLib.Selection = Selection | |
function EditorLib.NewTheme(Name, Theme) | |
Themes[Name] = Theme | |
end | |
local TextCursor = { | |
Image = "rbxassetid://1188942192", | |
HotspotX = 3, | |
HotspotY = 8, | |
Size = udim2(0, 7, 0, 17) | |
} | |
function EditorLib.Initialize(Frame, Options) | |
local themestuff = {} | |
local function ThemeSet(obj, prop, val) | |
themestuff[obj] = themestuff[obj] or {} | |
themestuff[obj][prop] = val | |
end | |
local baseZIndex = Frame.ZIndex | |
Options.CaretBlinkingRate = toNumber(Options.CaretBlinkingRate) or 0.25 | |
Options.FontSize = toNumber(Options.FontSize or Options.TextSize) or 14 | |
Options.CaretFocusedOpacity = toNumber(Options.CaretOpacity and Options.CaretOpacity.Focused or Options.CaretFocusedOpacity) or 1 | |
Options.CaretUnfocusedOpacity = toNumber(Options.CaretOpacity and Options.CaretOpacity.Unfocused or Options.CaretUnfocusedOpacity) or 0 | |
Options.Theme = type(Options.Theme) == "string" and Options.Theme or "Plain" | |
local SizeDot = game:GetService("TextService"):GetTextSize(".", Options.FontSize, Options.Font, Vector2.new(1000, 1000)) | |
local SizeM = game:GetService("TextService"):GetTextSize("m", Options.FontSize, Options.Font, Vector2.new(1000, 1000)) | |
local SizeAV = game:GetService("TextService"):GetTextSize("AV", Options.FontSize, Options.Font, Vector2.new(1000, 1000)) | |
local Editor = { | |
Content = "", | |
Lines = {""}, | |
Focused = false, | |
PlaceCache = {}, | |
Selection = Selection.new(0, 0, Side.Left), | |
StartingSelection = Selection.new(0, 0, Side.Left), | |
LastKeyCode = false, | |
UndoStack = {}, | |
RedoStack = {} | |
} | |
local CharWidth = SizeM.X | |
local CharHeight = SizeM.Y + 4 | |
if (SizeDot.X ~= SizeM.X or SizeDot.Y ~= SizeM.Y) and SizeAV.X ~= SizeM.X + SizeDot.X then | |
return error("CodeEditor requires a monospace font with no currying", 2) | |
end | |
local ContentChangedEvent = newInst("BindableEvent") | |
local FocusLostEvent = newInst("BindableEvent") | |
local PlayerGui = game:GetService("Players").LocalPlayer:FindFirstChildOfClass("PlayerGui") | |
local Container = newInst("Frame") | |
Container.Name = "Container" | |
Container.BorderSizePixel = 0 | |
Container.BackgroundColor3 = Themes[Options.Theme].Background | |
ThemeSet(Container, "BackgroundColor3", "Background") | |
Container.Size = udim2(1, 0, 1, 0) | |
Container.ClipsDescendants = true | |
local GutterSize = CharWidth * 4 | |
local TextArea = newInst("ScrollingFrame") | |
TextArea.Name = "TextArea" | |
TextArea.BackgroundTransparency = 1; | |
TextArea.BorderSizePixel = 0 | |
TextArea.Size = udim2(1, -GutterSize, 1, 0) | |
TextArea.Position = udim2(0, GutterSize, 0, 0) | |
TextArea.ScrollBarThickness = 10; | |
TextArea.ScrollBarImageTransparency = 0; | |
TextArea.ScrollBarImageColor3 = Color3.fromRGB(20, 20, 20) | |
TextArea.BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png" | |
TextArea.TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png" | |
TextArea.ZIndex = 3; | |
local Gutter = newInst("Frame") | |
Gutter.Name = "Gutter" | |
Gutter.ZIndex = baseZIndex | |
Gutter.BorderSizePixel = 0 | |
Gutter.BackgroundTransparency = 0.96 | |
Gutter.Size = udim2(0, GutterSize - 5, 1.5, 0) | |
local GoodMouseDetector = newInst("TextButton") | |
GoodMouseDetector.Text = "" | |
GoodMouseDetector.BackgroundTransparency = 1 | |
GoodMouseDetector.Size = udim2(1, 0, 1, 0) | |
GoodMouseDetector.Position = udim2(0, 0, 0, 0) | |
GoodMouseDetector.Visible = false | |
local Mouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local Scroll = newInst("TextButton") | |
Scroll.Name = "VertScroll" | |
Scroll.Size = udim2(0, 10, 1, 0) | |
Scroll.Position = udim2(1, -10, 0, 0) | |
Scroll.BackgroundTransparency = 1 | |
Scroll.Text = "" | |
Scroll.ZIndex = 1000 | |
Scroll.Parent = Container | |
local ScrollBar = newInst("TextButton") | |
ScrollBar.Name = "ScrollBar" | |
ScrollBar.Size = udim2(1, 0, 0, 36) | |
ScrollBar.Position = udim2(0, 0, 0, 0) | |
ScrollBar.Text = "" | |
ScrollBar.BackgroundColor3 = Themes[Options.Theme].ScrollBar or Color3.fromRGB(120, 120, 120) | |
ScrollBar.BackgroundTransparency = 0.75 | |
ScrollBar.BorderSizePixel = 0 | |
ScrollBar.AutoButtonColor = false | |
ScrollBar.ZIndex = 3 + baseZIndex | |
ScrollBar.Parent = Scroll | |
local CaretIndicator = newInst("Frame") | |
CaretIndicator.Name = "CaretIndicator" | |
CaretIndicator.Size = udim2(1, 0, 0, 2) | |
CaretIndicator.Position = udim2(0, 0, 0, 0) | |
CaretIndicator.BorderSizePixel = 0 | |
CaretIndicator.BackgroundColor3 = Themes[Options.Theme].Text | |
ThemeSet(CaretIndicator, "BackgroundColor3", "Text") | |
CaretIndicator.BackgroundTransparency = 0.29803921568627456 | |
CaretIndicator.ZIndex = 4 + baseZIndex | |
CaretIndicator.Parent = Scroll | |
local MarkersFolder = newInst("Folder", Scroll) | |
local markers = {} | |
local updateMarkers | |
do | |
local lerp = function(a, b, r) | |
return a + r * (b - a) | |
end | |
function updateMarkers() | |
MarkersFolder:ClearAllChildren() | |
local ra = Themes[Options.Theme].Background.r | |
local ga = Themes[Options.Theme].Background.g | |
local ba = Themes[Options.Theme].Background.b | |
local rb = Themes[Options.Theme].Text.r | |
local gb = Themes[Options.Theme].Text.g | |
local bb = Themes[Options.Theme].Text.b | |
local r = lerp(ra, rb, 0.2980392156862745) | |
local g = lerp(ga, gb, 0.2980392156862745) | |
local b = lerp(ba, bb, 0.2980392156862745) | |
local color = Color3.new(r, g, b) | |
for i, v in ipairs(markers) do | |
local Marker = newInst("Frame") | |
Marker.BorderSizePixel = 0 | |
Marker.BackgroundColor3 = color | |
Marker.Size = udim2(0, 4, 0, 6) | |
Marker.Position = udim2(0, 4, v * CharHeight / TextArea.CanvasSize.Y.Offset, 0) | |
Marker.ZIndex = 4 + baseZIndex | |
Marker.Parent = MarkersFolder | |
end | |
end | |
end | |
do | |
TextArea.Changed:Connect(function(property) | |
if property == "CanvasSize" or property == "CanvasPosition" then | |
Gutter.Position = udim2(0, 0, 0, -TextArea.CanvasPosition.Y) | |
end | |
end) | |
end | |
local ScrollBorder = newInst("Frame") | |
ScrollBorder.Name = "ScrollBorder" | |
ScrollBorder.Position = udim2(0, -1, 0, 0) | |
ScrollBorder.Size = udim2(0, 1, 1, 0) | |
ScrollBorder.BorderSizePixel = 0 | |
ScrollBorder.BackgroundColor3 = Color3.fromRGB(34, 34, 34) | |
ScrollBorder.Parent = Scroll | |
do | |
TextArea.Changed:Connect(function(property) | |
if property == "CanvasSize" or property == "CanvasPosition" then | |
local percent = TextArea.AbsoluteWindowSize.X / TextArea.CanvasSize.X.Offset | |
ScrollBar.Size = udim2(percent, 0, 1, 0) | |
local max = max(TextArea.CanvasSize.X.Offset - TextArea.AbsoluteWindowSize.X, 0) | |
local percent = max == 0 and 0 or TextArea.CanvasPosition.X / max | |
local x = percent * (Scroll.AbsoluteSize.X - ScrollBar.AbsoluteSize.X) | |
ScrollBar.Position = udim2(0, x, 0, 0) | |
Scroll.Visible = false | |
end | |
end) | |
end | |
local LineSelection = newInst("Frame") | |
LineSelection.Name = "LineSelection" | |
LineSelection.BackgroundColor3 = Themes[Options.Theme].Background | |
ThemeSet(LineSelection, "BackgroundColor3", "Background") | |
LineSelection.BorderSizePixel = 2 | |
LineSelection.BorderColor3 = Themes[Options.Theme].LineSelection | |
ThemeSet(LineSelection, "BorderColor3", "LineSelection") | |
LineSelection.Size = udim2(1, -4, 0, CharHeight - 4) | |
LineSelection.Position = udim2(0, 2, 0, 2) | |
LineSelection.ZIndex = -1 + baseZIndex | |
LineSelection.Parent = TextArea | |
LineSelection.Visible = false; | |
local ErrorHighlighter = newInst("Frame") | |
ErrorHighlighter.Name = "ErrorHighlighter" | |
ErrorHighlighter.BackgroundColor3 = Color3.fromRGB(255, 0, 0) | |
ErrorHighlighter.BackgroundTransparency = 0.9 | |
ErrorHighlighter.BorderSizePixel = 0 | |
ErrorHighlighter.Size = udim2(1, -4, 0, CharHeight - 4) | |
ErrorHighlighter.Position = udim2(0, 2, 0, 2) | |
ErrorHighlighter.ZIndex = 5 + baseZIndex | |
ErrorHighlighter.Visible = false | |
ErrorHighlighter.Parent = TextArea | |
local ErrorMessage = newInst("TextLabel") | |
ErrorMessage.Name = "ErrorMessage" | |
ErrorMessage.BackgroundColor3 = Themes[Options.Theme].Background:lerp(Color3.new(1, 1, 1), 0.1) | |
ErrorMessage.TextColor3 = Color3.fromRGB(255, 152, 152) | |
ErrorMessage.BorderSizePixel = 0 | |
ErrorMessage.Visible = false | |
ErrorMessage.Size = udim2(0, 150, 0, CharHeight - 4) | |
ErrorMessage.Position = udim2(0, 2, 0, 2) | |
ErrorMessage.ZIndex = 6 + baseZIndex | |
ErrorMessage.Parent = Container | |
local Tokens = newInst("Frame", TextArea) | |
Tokens.BackgroundTransparency = 1 | |
Tokens.Name = "Tokens" | |
local Selection = newInst("Frame", TextArea) | |
Selection.BackgroundTransparency = 1 | |
Selection.Name = "Selection" | |
Selection.ZIndex = baseZIndex | |
local TextBox = newInst("TextBox") | |
TextBox.BackgroundTransparency = 1 | |
TextBox.Size = udim2(0, 0, 0, 0) | |
TextBox.Position = udim2(-1, 0, -1, 0) | |
TextBox.Text = "" | |
TextBox.ShowNativeInput = false | |
TextBox.MultiLine = true | |
TextBox.ClearTextOnFocus = true | |
local Caret = newInst("Frame") | |
Caret.Name = "Caret" | |
Caret.BorderSizePixel = 0 | |
Caret.BackgroundColor3 = Themes[Options.Theme].Text | |
ThemeSet(Caret, "BackgroundColor3", "Text") | |
Caret.Size = udim2(0, 2, 0, CharHeight) | |
Caret.Position = udim2(0, 0, 0, 0) | |
Caret.ZIndex = 100 | |
Caret.Visible = false; | |
local selectedword | |
local tokens = {} | |
local function NewToken(Content, Color, Position, Parent) | |
local Token = newInst("TextLabel") | |
Token.BorderSizePixel = 0 | |
Token.TextColor3 = Themes[Options.Theme][Color] | |
Token.BackgroundTransparency = 1 | |
Token.BackgroundColor3 = Themes[Options.Theme].SelectionGentle | |
if Content == selectedword then | |
Token.BackgroundTransparency = 0 | |
end | |
Token.Size = udim2(0, CharWidth * #Content, 0, CharHeight) | |
Token.Position = udim2(0, Position.X * CharWidth, 0, Position.Y * CharHeight) | |
Token.Font = Options.Font | |
Token.TextSize = Options.FontSize | |
Token.Text = Content | |
Token.TextXAlignment = "Left" | |
Token.ZIndex = baseZIndex | |
Token.Parent = Parent | |
tokens[#tokens + 1] = Token | |
end | |
local function updateselected() | |
for i, v in ipairs(tokens) do | |
if v.Text == selectedword then | |
v.BackgroundTransparency = 0 | |
else | |
v.BackgroundTransparency = 1 | |
end | |
end | |
markers = {} | |
if selectedword and selectedword ~= "" and selectedword ~= tab then | |
for LineNumber = 1, #Editor.Lines do | |
local line = Editor.Lines[LineNumber] | |
local Dnable = "[^A-Za-z0-9_]" | |
local has = false | |
if sub(line, 1, #selectedword) == selectedword then | |
has = true | |
elseif sub(line, #line - #selectedword + 1) == selectedword then | |
has = true | |
elseif line:match(Dnable .. gsub(selectedword, "%W", "%%%1") .. Dnable) then | |
has = true | |
end | |
if has then | |
markers[#markers + 1] = LineNumber - 1 | |
end | |
end | |
end | |
updateMarkers() | |
end | |
local DrawnLines = {} | |
local depth = {} | |
local sdepth = {} | |
local function DrawTokens() | |
local LineBegin = floor(TextArea.CanvasPosition.Y / CharHeight) | |
local LineEnd = ceil((TextArea.CanvasPosition.Y + TextArea.AbsoluteWindowSize.Y) / CharHeight) | |
LineEnd = min(LineEnd, #Editor.Lines) | |
for LineNumber = 1, LineBegin - 1 do | |
if not depth[LineNumber] then | |
local line = Editor.Lines[LineNumber] or "" | |
if line:match("%[%=+%[") or line:match("%]%=+%]") then | |
local LexerStream = Lexer(line) | |
LexerStream.CommentDepth = depth[LineNumber - 1] or 0 | |
LexerStream.StringDepth = sdepth[LineNumber - 1] or 0 | |
while not LexerStream.EOF() do | |
LexerStream.Next() | |
end | |
sdepth[LineNumber] = LexerStream.StringDepth | |
depth[LineNumber] = LexerStream.CommentDepth | |
else | |
sdepth[LineNumber] = sdepth[LineNumber - 1] or 0 | |
depth[LineNumber] = depth[LineNumber - 1] or 0 | |
end | |
end | |
end | |
for LineNumber = LineBegin, LineEnd do | |
if not DrawnLines[LineNumber] then | |
DrawnLines[LineNumber] = true | |
local X, Y = 0, LineNumber - 1 | |
local LineLabel = newInst("TextLabel") | |
LineLabel.BorderSizePixel = 0 | |
LineLabel.TextColor3 = Color3.fromRGB(144, 145, 139) | |
LineLabel.BackgroundTransparency = 1 | |
LineLabel.Size = udim2(1, 0, 0, CharHeight) | |
LineLabel.Position = udim2(0, 0, 0, Y * CharHeight) | |
LineLabel.Font = Options.Font | |
LineLabel.TextSize = Options.FontSize | |
LineLabel.TextXAlignment = Enum.TextXAlignment.Right | |
LineLabel.Text = LineNumber | |
LineLabel.Parent = Gutter | |
LineLabel.ZIndex = baseZIndex | |
if Editor.Lines[Y + 1] then | |
local LexerStream = Lexer(Editor.Lines[Y + 1]) | |
LexerStream.CommentDepth = depth[LineNumber - 1] or 0 | |
LexerStream.StringDepth = sdepth[LineNumber - 1] or 0 | |
while not LexerStream.EOF() do | |
local Token = LexerStream.Next() | |
local Value = Token.Value | |
local TokenType = Token.TypeName | |
if TokenType == "Identifier" or TokenType == "Symbol" then | |
TokenType = "Text" | |
end | |
if (" \t\r\n"):find(Value, 1, true) == nil then | |
NewToken(gsub(Value, tab, TabText), TokenType, Place.new(X, Y), Tokens) | |
end | |
X = X + #gsub(Value, tab, TabText) | |
end | |
depth[LineNumber] = LexerStream.CommentDepth | |
sdepth[LineNumber] = LexerStream.StringDepth | |
end | |
end | |
end | |
end | |
TextArea.Changed:Connect(function(Property) | |
if Property == "CanvasPosition" or Property == "AbsoluteWindowSize" then | |
DrawTokens() | |
end | |
end) | |
local function ClearTokensAndSelection() | |
depth = {} | |
Tokens:ClearAllChildren() | |
Selection:ClearAllChildren() | |
Gutter:ClearAllChildren() | |
end | |
local function Write(Content, Start, End) | |
local InBetween = sub(Editor.Content, Start + 1, End) | |
local NoLN = find(InBetween, newline, 1, true) == nil and find(Content, newline, 1, true) == nil | |
local StartPlace, EndPlace | |
if NoLN then | |
StartPlace, EndPlace = Place.fromIndex(Editor, Start), Place.fromIndex(Editor, End) | |
end | |
Editor.Content = sub(Editor.Content, 1, Start) .. Content .. sub(Editor.Content, End + 1) | |
ContentChangedEvent:Fire(Editor.Content) | |
Editor.PlaceCache = {} | |
local CanvasWidth = TextArea.CanvasSize.X.Offset - 14 | |
Editor.Lines = Split(Editor.Content, newline) | |
for _, Res in ipairs(Editor.Lines) do | |
local width = #gsub(Res, tab, TabText) * CharWidth | |
if CanvasWidth < width then | |
CanvasWidth = width | |
end | |
end | |
ClearTokensAndSelection() | |
TextArea.CanvasSize = udim2(0, 3000, 0, select(2, gsub(Editor.Content, newline, "")) * CharHeight + TextArea.AbsoluteWindowSize.Y) | |
DrawnLines = {} | |
DrawTokens() | |
end | |
local function SetContent(Content) | |
Editor.Content = Content | |
ContentChangedEvent:Fire(Editor.Content) | |
Editor.PlaceCache = {} | |
Editor.Lines = Split(Editor.Content, newline) | |
ClearTokensAndSelection() | |
local CanvasWidth = TextArea.CanvasSize.X.Offset - 14 | |
for _, Res in ipairs(Editor.Lines) do | |
if CanvasWidth < #Res then | |
CanvasWidth = #Res * CharWidth | |
end | |
end | |
TextArea.CanvasSize = udim2(0, 3000, 0, select(2, gsub(Editor.Content, newline, "")) * CharHeight + TextArea.AbsoluteWindowSize.Y) | |
DrawnLines = {} | |
DrawTokens() | |
end | |
local function UpdateSelection() | |
Selection:ClearAllChildren() | |
if Themes[Options.Theme].SelectionColor then | |
Selection.ZIndex = 2 + baseZIndex | |
Tokens.ZIndex = 1 + baseZIndex | |
else | |
Selection.ZIndex = 1 + baseZIndex | |
Tokens.ZIndex = 2 + baseZIndex | |
end | |
if Editor.Selection.Start == Editor.Selection.End then | |
LineSelection.Visible = true | |
local CaretPlace = Place.fromIndex(Editor, Editor.Selection.Start) | |
LineSelection.Position = UDim2.new(0, 2, 0, CharHeight * CaretPlace.Y + 2) | |
else | |
LineSelection.Visible = false | |
end | |
local Index = 0 | |
local Start = #gsub(sub(Editor.Content, 1, Editor.Selection.Start), tab, TabText) | |
local End = #gsub(sub(Editor.Content, 1, Editor.Selection.End), tab, TabText) | |
for LineNumber, Line in ipairs(Editor.Lines) do | |
Line = gsub(Line, tab, TabText) | |
local StartX = Start - Index | |
local EndX = End - Index | |
local Y = LineNumber - 1 | |
local GoesOverLine = false | |
if StartX < 0 then | |
StartX = 0 | |
end | |
if EndX > #Line then | |
GoesOverLine = true | |
EndX = #Line | |
end | |
local Width = EndX - StartX | |
if GoesOverLine then | |
Width = Width + 0.5 | |
end | |
if Width > 0 then | |
local color = Themes[Options.Theme].SelectionColor | |
local SelectionSegment = newInst(color and "TextLabel" or "Frame") | |
SelectionSegment.BorderSizePixel = 0 | |
if color then | |
SelectionSegment.TextColor3 = color | |
SelectionSegment.Font = Options.Font | |
SelectionSegment.TextSize = Options.FontSize | |
SelectionSegment.Text = sub(Line, StartX + 1, EndX) | |
SelectionSegment.TextXAlignment = "Left" | |
SelectionSegment.ZIndex = baseZIndex | |
else | |
SelectionSegment.BorderSizePixel = 0 | |
end | |
SelectionSegment.BackgroundColor3 = Themes[Options.Theme].SelectionBackground | |
SelectionSegment.Size = udim2(0, CharWidth * Width, 0, CharHeight) | |
SelectionSegment.Position = udim2(0, StartX * CharWidth, 0, Y * CharHeight) | |
SelectionSegment.Parent = Selection | |
end | |
Index = Index + #Line + 1 | |
end | |
local NewY = Caret.Position.Y.Offset | |
local MinBoundsY = TextArea.CanvasPosition.Y | |
local MaxBoundsY = TextArea.CanvasPosition.Y + TextArea.AbsoluteWindowSize.Y - CharHeight | |
if NewY < MinBoundsY then | |
TextArea.CanvasPosition = Vector2.new(0, NewY) | |
end | |
if NewY > MaxBoundsY then | |
TextArea.CanvasPosition = Vector2.new(0, NewY - TextArea.AbsoluteWindowSize.Y + CharHeight) | |
end | |
end | |
TextBox.Parent = TextArea | |
Caret.Parent = TextArea | |
TextArea.Parent = Container | |
Gutter.Parent = Container | |
Container.Parent = Frame | |
local function updateCaret(CaretPlace) | |
Caret.Position = udim2(0, CaretPlace.X * CharWidth, 0, CaretPlace.Y * CharHeight) | |
local percent = CaretPlace.Y * CharHeight / TextArea.CanvasSize.Y.Offset | |
CaretIndicator.Position = udim2(0, 0, percent, -1) | |
end | |
local PressedKey, WorkingKey, LeftShift, RightShift, Shift, LeftCtrl, RightCtrl, Ctrl | |
local UIS = game:GetService("UserInputService") | |
local MovementTimeout = tick() | |
local BeginSelect, MoveCaret | |
local function SetVisibility(Visible) | |
Editor.Visible = Visible | |
end | |
local function selectWord() | |
local Index = Editor.Selection.Start | |
if Editor.Selection.Side == Side.Right then | |
Index = Editor.Selection.End | |
end | |
local code = Editor.Content | |
local left = max(Index - 1, 0) | |
local right = min(Index + 1, #code) | |
local Dable = "[A-Za-z0-9_]" | |
while left ~= 0 and match(sub(code, left + 1, left + 1), Dable) do | |
left = left - 1 | |
end | |
while right ~= #code and match(sub(code, right, right), Dable) do | |
right = right + 1 | |
end | |
if not match(sub(code, left + 1, left + 1), Dable) then | |
left = left + 1 | |
end | |
if not match(sub(code, right, right), Dable) then | |
right = right - 1 | |
end | |
if left < right then | |
Editor.Selection.Start = left | |
Editor.Selection.End = right | |
else | |
Editor.Selection.Start = Index | |
Editor.Selection.End = Index | |
end | |
end | |
local settledAt | |
local lastClick = 0 | |
local lastCaretPos = 0 | |
local function PushToUndoStack() | |
Editor.UndoStack[#Editor.UndoStack + 1] = { | |
Content = Editor.Content, | |
Selection = { | |
Start = Editor.Selection.Start, | |
End = Editor.Selection.End, | |
Side = Editor.Selection.Side | |
}, | |
LastKeyCode = false | |
} | |
if #Editor.RedoStack > 0 then | |
Editor.RedoStack = {} | |
end | |
end | |
local function Undo() | |
if #Editor.UndoStack > 1 then | |
local Thing = Editor.UndoStack[#Editor.UndoStack - 1] | |
for Key, Value in pairs(Thing) do | |
Editor[Key] = Value | |
end | |
Editor.SetContent(Thing.Content) | |
Editor.RedoStack[#Editor.RedoStack + 1] = Editor.UndoStack[#Editor.UndoStack] | |
Editor.UndoStack[#Editor.UndoStack] = nil | |
end | |
end | |
local function Redo() | |
if #Editor.RedoStack > 0 then | |
local Thing = Editor.RedoStack[#Editor.RedoStack] | |
for Key, Value in pairs(Thing) do | |
Editor[Key] = Value | |
end | |
Editor.SetContent(Thing.Content) | |
Editor.UndoStack[#Editor.UndoStack + 1] = Thing | |
Editor.RedoStack[#Editor.RedoStack] = nil | |
end | |
end | |
Mouse.Move:Connect(function() | |
if BeginSelect then | |
local Index = GetIndexAtMouse() | |
if type(BeginSelect) == "number" then | |
BeginSelect = {BeginSelect, BeginSelect} | |
end | |
Editor.Selection.Start = min(BeginSelect[1], Index) | |
Editor.Selection.End = max(BeginSelect[2], Index) | |
if Editor.Selection.Start ~= Editor.Selection.End then | |
if Editor.Selection.Start == Index then | |
Editor.Selection.Side = Side.Left | |
else | |
Editor.Selection.Side = Side.Right | |
end | |
end | |
if BeginSelect[3] then | |
selectWord() | |
Editor.Selection.Start = min(BeginSelect[1], Editor.Selection.Start) | |
Editor.Selection.End = max(BeginSelect[2], Editor.Selection.End) | |
end | |
local Ind = Editor.Selection.Start | |
if Editor.Selection.Side == Side.Right then | |
Ind = Editor.Selection.End | |
end | |
local CaretPlace = Place.fromIndex(Editor, Ind) | |
updateCaret(CaretPlace) | |
UpdateSelection() | |
end | |
end) | |
TextBox.Focused:Connect(function() | |
Editor.Focused = true | |
end) | |
TextBox.FocusLost:Connect(function() | |
Editor.Focused = false | |
FocusLostEvent:Fire() | |
PressedKey = nil | |
WorkingKey = nil | |
end) | |
function MoveCaret(Amount) | |
local Direction = Amount < 0 and -1 or 1 | |
if Amount < 0 then | |
Amount = -Amount | |
end | |
for Index = 1, Amount do | |
if Direction == -1 then | |
local Start = Editor.Selection.Start | |
local End = Editor.Selection.End | |
if Shift then | |
if Start == End then | |
if Start > 0 then | |
Editor.Selection.Start = Start - 1 | |
Editor.Selection.Side = Side.Left | |
end | |
elseif Editor.Selection.Side == Side.Left then | |
if Start > 0 then | |
Editor.Selection.Start = Start - 1 | |
end | |
elseif Editor.Selection.Side == Side.Right then | |
Editor.Selection.End = End - 1 | |
end | |
elseif Start ~= End then | |
Editor.Selection.End = Start | |
elseif Start > 0 then | |
Editor.Selection.Start = Start - 1 | |
Editor.Selection.End = End - 1 | |
end | |
elseif Direction == 1 then | |
local Start = Editor.Selection.Start | |
local End = Editor.Selection.End | |
if Shift then | |
if Start == End then | |
if Start < #Editor.Content then | |
Editor.Selection.End = End + 1 | |
Editor.Selection.Side = Side.Right | |
end | |
elseif Editor.Selection.Side == Side.Left then | |
Editor.Selection.Start = Start + 1 | |
elseif Editor.Selection.Side == Side.Right and End < #Editor.Content then | |
Editor.Selection.End = End + 1 | |
end | |
elseif Start ~= End then | |
Editor.Selection.Start = End | |
elseif Start < #Editor.Content then | |
Editor.Selection.Start = Start + 1 | |
Editor.Selection.End = End + 1 | |
end | |
end | |
end | |
end | |
local LastKeyCode | |
local function ProcessInput(Type, Data) | |
MovementTimeout = tick() + 0.25 | |
if Type == "Control+Key" then | |
LastKeyCode = nil | |
elseif Type == "KeyPress" then | |
local Dat = Data | |
if Dat == Enum.KeyCode.Up then | |
Dat = Enum.KeyCode.Down | |
end | |
if LastKeyCode ~= Dat then | |
Editor.StartingSelection.Start = Editor.Selection.Start | |
Editor.StartingSelection.End = Editor.Selection.End | |
Editor.StartingSelection.Side = Editor.Selection.Side | |
end | |
LastKeyCode = Dat | |
elseif Type == "StringInput" then | |
local Start = Editor.Selection.Start | |
local End = Editor.Selection.End | |
if Data == newline then | |
local CaretPlaceInd = Editor.Selection.Start | |
if Editor.Selection.Side == Side.Right then | |
CaretPlaceInd = Editor.Selection.End | |
end | |
local CaretPlace = Place.fromIndex(Editor, CaretPlaceInd) | |
local CaretLine = Editor.Lines | |
CaretLine = CaretLine[CaretPlace.Y + 1] | |
CaretLine = sub(CaretLine, 1, CaretPlace.X) | |
local TabAmount = 0 | |
while sub(CaretLine, TabAmount + 1, TabAmount + 1) == tab do | |
TabAmount = TabAmount + 1 | |
end | |
Data = Data .. tab:rep(TabAmount) | |
local SpTabAmount = 0 | |
while CaretLine:sub(SpTabAmount + 1, SpTabAmount + 1) == " " do | |
SpTabAmount = SpTabAmount + 1 | |
end | |
Data = Data .. gsub((" "):rep(SpTabAmount), TabText, tab) | |
Write(Data, Start, End) | |
Editor.Selection.Start = Start + #Data | |
Editor.Selection.End = Editor.Selection.Start | |
PushToUndoStack() | |
elseif Data == tab and Editor.Selection.Start ~= Editor.Selection.End then | |
local lstart = Place.fromIndex(Editor, Editor.Selection.Start) | |
local lend = Place.fromIndex(Editor, Editor.Selection.End) | |
local changes = 0 | |
local change1 = 0 | |
for i = lstart.Y + 1, lend.Y + 1 do | |
local line = Editor.Lines[i] | |
local change = 0 | |
if Shift then | |
if sub(line, 1, 1) == tab then | |
line = sub(line, 2) | |
change = -1 | |
end | |
else | |
line = tab .. line | |
change = 1 | |
end | |
changes = changes + change | |
if i == lstart.Y + 1 then | |
change1 = change | |
end | |
Editor.Lines[i] = line | |
end | |
SetContent(table.concat(Editor.Lines, newline)) | |
Editor.Selection.Start = Editor.Selection.Start + change1 | |
Editor.Selection.End = Editor.Selection.End + changes | |
PushToUndoStack() | |
else | |
Write(Data, Start, End) | |
Editor.Selection.Start = Start + #Data | |
Editor.Selection.End = Editor.Selection.Start | |
PushToUndoStack() | |
end | |
end | |
local CaretPlaceInd = Editor.Selection.Start | |
if Editor.Selection.Side == Side.Right then | |
CaretPlaceInd = Editor.Selection.End | |
end | |
local CaretPlace = Place.fromIndex(Editor, CaretPlaceInd) | |
updateCaret(CaretPlace) | |
UpdateSelection() | |
end | |
TextBox:GetPropertyChangedSignal("Text"):Connect(function() | |
if TextBox.Text ~= "" then | |
ProcessInput("StringInput", (gsub(TextBox.Text, "\r", ""))) | |
TextBox.Text = "" | |
--TextBox:CaptureFocus() | |
end | |
end) | |
UIS.InputBegan:Connect(function(Input) | |
if UIS:GetFocusedTextBox() == TextBox and Input.UserInputType ~= Enum.UserInputType.MouseButton1 then | |
local KeyCode = Input.KeyCode | |
if KeyCode == Enum.KeyCode.LeftShift then | |
LeftShift = true | |
Shift = true | |
elseif KeyCode == Enum.KeyCode.RightShift then | |
RightShift = true | |
Shift = true | |
elseif KeyCode == Enum.KeyCode.LeftControl then | |
LeftCtrl = true | |
Ctrl = true | |
elseif KeyCode == Enum.KeyCode.RightControl then | |
RightCtrl = true | |
Ctrl = true | |
else | |
PressedKey = KeyCode | |
ProcessInput(not (not Ctrl or Shift) and "Control+Key" or "KeyPress", KeyCode) | |
local UniqueID = newproxy(false) | |
WorkingKey = UniqueID | |
wait(0.25) | |
if WorkingKey == UniqueID then | |
WorkingKey = true | |
end | |
end | |
end | |
end) | |
UIS.InputEnded:Connect(function(Input) | |
if Input.UserInputType == Enum.UserInputType.MouseButton1 then | |
BeginSelect = nil | |
end | |
if Input.KeyCode == Enum.KeyCode.LeftShift then | |
LeftShift = false | |
end | |
if Input.KeyCode == Enum.KeyCode.RightShift then | |
RightShift = false | |
end | |
if Input.KeyCode == Enum.KeyCode.LeftControl then | |
LeftCtrl = false | |
end | |
if Input.KeyCode == Enum.KeyCode.RightControl then | |
RightCtrl = false | |
end | |
Shift = LeftShift or RightShift | |
Ctrl = LeftCtrl or RightCtrl | |
if PressedKey == Input.KeyCode then | |
PressedKey = nil | |
WorkingKey = nil | |
end | |
end) | |
local Count = 0 | |
game:GetService("RunService").Heartbeat:Connect(function() | |
if Count == 0 and WorkingKey == true then | |
ProcessInput(not (not Ctrl or Shift) and "Control+Key" or "KeyPress", PressedKey) | |
end | |
Count = (Count + 1) % 2 | |
end) | |
Editor.Write = Write | |
Editor.SetContent = SetContent | |
Editor.SetVisibility = SetVisibility | |
Editor.PushToUndoStack = PushToUndoStack | |
Editor.Undo = Undo | |
Editor.Redo = Redo | |
function Editor.UpdateTheme(theme) | |
for obj, v in pairs(themestuff) do | |
for key, value in pairs(v) do | |
obj[key] = Themes[theme][value] | |
end | |
end | |
Options.Theme = theme | |
ClearTokensAndSelection() | |
updateMarkers() | |
end | |
function Editor.HighlightError(Visible, Line, Msg) | |
if Visible then | |
ErrorHighlighter.Position = udim2(0, 2, 0, CharHeight * Line + 2 - CharHeight) | |
ErrorMessage.Text = "Line " .. Line .. " - " .. Msg | |
ErrorMessage.Size = udim2(0, ErrorMessage.TextBounds.X + 15, 0, ErrorMessage.TextBounds.Y + 8) | |
else | |
ErrorMessage.Visible = false | |
end | |
ErrorHighlighter.Visible = Visible | |
end | |
Editor.ContentChanged = ContentChangedEvent.Event | |
Editor.FocusLost = FocusLostEvent.Event | |
TextArea.CanvasPosition = Vector2.new(0, 0); | |
return Editor, TextBox, ClearTokensAndSelection, TextArea; | |
end | |
local ScriptEditor, EditorGrid, Clear, TxtArea = EditorLib.Initialize(editor:FindFirstChild("Editor"), { | |
Font = Enum.Font.Code, | |
TextSize = 16; | |
Language = "Lua", | |
CaretBlinkingRate = 0.5 | |
}) | |
local function openScript(o) | |
EditorGrid.Text = ""; | |
local id = GetDebugId(o); | |
if cache[id] then | |
ScriptEditor.SetContent(cache[id]) | |
else | |
local decompiled = decompile(o); | |
cache[id] = decompiled; | |
game:GetService("RunService").Heartbeat:wait(); | |
ScriptEditor.SetContent(cache[id]) | |
end | |
Title.Text = "[Script Viewer] Viewing: " .. o.Name; | |
end | |
bindable.Event:connect(function(object) | |
script.Parent.Visible = true; | |
openScript(object) | |
end) | |
SaveScript.MouseButton1Click:connect(function() | |
if ScriptEditor.Content ~= "" then | |
local fileName = FileName.Text; | |
if fileName == "File Name" or FileName == "" then | |
fileName = "LocalScript_" .. math.random(1, 5000) | |
end | |
fileName = fileName .. ".lua"; | |
writefile(fileName, ScriptEditor.Content); | |
end | |
end) | |
CopyScript.MouseButton1Click:connect(function() | |
local txt = ScriptEditor.Content; | |
if Clipboard then | |
Clipboard.set(txt) | |
else | |
setclipboard(txt) | |
end | |
end) | |
ClearScript.MouseButton1Click:connect(function() | |
--EditorGrid.Text = ""; | |
ScriptEditor.SetContent("") | |
TxtArea.CanvasPosition = Vector2.new(0, 0); | |
Title.Text = "[Script Viewer]"; | |
Clear(); | |
end) | |
CloseEditor.MouseButton1Click:connect(function() | |
script.Parent.Visible = false; | |
end) end,Reference=150,ClassName="LocalScript"},{Children={{Children={{Properties={LayoutOrder=2,FontFace=Font.new("rbxasset://fonts/families/Inconsolata.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Copy To Clipboard",Text="Copy To Clipboard",Name="CopyScript",BorderSizePixel=0,Size=UDim2.new(0,150,1,0),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(0.1764705926179886,0.1764705926179886,0.1764705926179886)},Reference=160,ClassName="TextButton"},{Properties={SortOrder=Enum.SortOrder.LayoutOrder,FillDirection=Enum.FillDirection.Horizontal},Reference=158,ClassName="UIListLayout"},{Properties={FontFace=Font.new("rbxasset://fonts/families/Inconsolata.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save Script",Text="Save Script",Name="SaveScript",BorderSizePixel=0,Size=UDim2.new(0,125,1,0),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(0.1764705926179886,0.1764705926179886,0.1764705926179886)},Reference=159,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/Inconsolata.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="File Name",Name="FileName",BorderSizePixel=0,Size=UDim2.new(0,125,1,0),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(0.09803922474384308,0.09803922474384308,0.09803922474384308)},Reference=157,ClassName="TextBox"},{Properties={LayoutOrder=2,FontFace=Font.new("rbxasset://fonts/families/Inconsolata.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Clear Editor",Text="Clear Editor",Name="ClearScript",BorderSizePixel=0,Size=UDim2.new(0,125,1,0),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(0.1764705926179886,0.1764705926179886,0.1764705926179886)},Reference=161,ClassName="TextButton"}},Properties={Name="Other",Position=UDim2.new(0,0,1,0),Size=UDim2.new(1,0,1,0),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.1372549086809158,0.1372549086809158,0.1372549086809158)},Reference=156,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.SemiBold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="X",Text="X",BackgroundTransparency=1,Position=UDim2.new(1,-25,0,0),Name="Close",Size=UDim2.new(0,25,1,0),TextSize=20,BackgroundColor3=Color3.new(1,1,1)},Reference=155,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/Inconsolata.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="[Script Viewer]",Text="[Script Viewer]",BackgroundTransparency=1,Name="title",Size=UDim2.new(1,0,1,0),TextSize=16,BackgroundColor3=Color3.new(1,1,1)},Reference=154,ClassName="TextLabel"}},Properties={Name="TopBar",Size=UDim2.new(1,0,1,0),BorderSizePixel=0,BackgroundColor3=Color3.new(0.1176470667123795,0.1176470667123795,0.1176470667123795)},Reference=153,ClassName="Frame"},{Properties={Name="OpenScript"},Reference=151,ClassName="BindableEvent"},{Properties={Name="Editor",Position=UDim2.new(0,0,1,25),Size=UDim2.new(0,642,0,436),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.1568627506494522,0.1568627506494522,0.1568627506494522)},Reference=152,ClassName="Frame"}},Properties={Draggable=true,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Name="ScriptEditor",Size=UDim2.new(0,642,0,25),BackgroundTransparency=1,Position=UDim2.new(0.5,-368,0.5,-216),Visible=false,ZIndex=5,BorderSizePixel=0,BackgroundColor3=Color3.new(0.1176470667123795,0.1176470667123795,0.1176470667123795)},Reference=149,ClassName="Frame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Created by: Moon\nEdited by: wally, ic3",Text="Created by: Moon\nEdited by: wally, ic3",TextStrokeTransparency=0.5,Name="Creator",BackgroundTransparency=1,Position=UDim2.new(0,80,0,300),Size=UDim2.new(0,140,0,30),ZIndex=2,TextSize=28,BackgroundColor3=Color3.new(1,1,1)},Reference=145,ClassName="TextLabel"},{Properties={Name="Main",Position=UDim2.new(0,-30,0,0),Size=UDim2.new(0,30,0,90),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.1960784494876862,0.1960784494876862,0.1960784494876862)},Reference=147,ClassName="Frame"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="Dex",Text="Dex",TextStrokeTransparency=0.5,Name="Title",FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),BackgroundTransparency=1,Position=UDim2.new(0,100,0,150),Size=UDim2.new(0,100,0,60),ZIndex=2,TextSize=60,BackgroundColor3=Color3.new(1,1,1)},Reference=144,ClassName="TextLabel"},{Properties={ImageColor3=Color3.new(0.1960784494876862,0.1960784494876862,0.1960784494876862),Rotation=180,Image="rbxassetid://1513966937",BackgroundTransparency=1,Position=UDim2.new(0,-30,0,90),Name="Slant",ZIndex=2,Size=UDim2.new(0,30,0,30),BackgroundColor3=Color3.new(0.1960784494876862,0.1960784494876862,0.1960784494876862)},Reference=148,ClassName="ImageLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Synapse Edition",Text="Synapse Edition",TextStrokeTransparency=0.5,Name="Version",BackgroundTransparency=1,Position=UDim2.new(0,100,0,210),Size=UDim2.new(0,100,0,30),ZIndex=2,TextSize=28,BackgroundColor3=Color3.new(1,1,1)},Reference=143,ClassName="TextLabel"},{Properties={Visible=false,Name="Sad",Image="rbxassetid://483437370",BackgroundTransparency=1,Position=UDim2.new(0,50,1,-250),ImageColor3=Color3.new(0.960784375667572,0.960784375667572,0.960784375667572),ZIndex=2,Size=UDim2.new(0,200,0,200),BackgroundColor3=Color3.new(1,1,1)},Reference=146,ClassName="ImageLabel"}},Properties={Name="IntroFrame",Position=UDim2.new(1,30,0,0),Size=UDim2.new(0,301,1,0),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.1960784494876862,0.1960784494876862,0.1960784494876862)},Reference=142,ClassName="Frame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Dex",Text="Dex",TextStrokeTransparency=0.75,Name="Title",BackgroundTransparency=1,Position=UDim2.new(0,0,0,150),Size=UDim2.new(1,0,0,60),ZIndex=2,TextSize=60,BackgroundColor3=Color3.new(1,1,1)},Reference=138,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Synapse Edition",Text="Synapse Edition",TextStrokeTransparency=0.75,Name="Version",BackgroundTransparency=1,Position=UDim2.new(0,100,0,210),Size=UDim2.new(0,100,0,30),ZIndex=2,TextSize=28,BackgroundColor3=Color3.new(1,1,1)},Reference=139,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Created by: Moon\nEdited by: wally, ic3",Text="Created by: Moon\nEdited by: wally, ic3",TextStrokeTransparency=0.75,Name="Creator",BackgroundTransparency=1,Position=UDim2.new(0,0,0,300),Size=UDim2.new(1,0,0,30),ZIndex=2,TextSize=28,BackgroundColor3=Color3.new(1,1,1)},Reference=137,ClassName="TextLabel"}},Properties={Draggable=true,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Name="About",Position=UDim2.new(1,0,0,0),Size=UDim2.new(0,300,1,0),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=136,ClassName="Frame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Confirm",Text="Confirm",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Title",ZIndex=3,TextSize=14,Size=UDim2.new(1,0,1,0)},Reference=60,ClassName="TextLabel"},{Children={{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="The file, FILENAME, already exists. Overwrite?",Text="The file, FILENAME, already exists. Overwrite?",TextStrokeTransparency=0.75,Name="Desc",FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,40),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(0.3450980484485626,0.3450980484485626,0.3450980484485626)},Reference=63,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="No",Text="No",TextStrokeTransparency=0.75,Name="No",BorderColor3=Color3.new(0,0,0),BackgroundTransparency=0.5,Position=UDim2.new(0.5249999761581421,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),ZIndex=2,TextSize=18,BackgroundColor3=Color3.new(0.3450980484485626,0.3450980484485626,0.3450980484485626)},Reference=64,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Yes",Text="Yes",TextStrokeTransparency=0.75,Name="Yes",BorderColor3=Color3.new(0,0,0),BackgroundTransparency=0.5,Position=UDim2.new(0.07500000298023224,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),ZIndex=2,TextSize=18,BackgroundColor3=Color3.new(0.3450980484485626,0.3450980484485626,0.3450980484485626)},Reference=62,ClassName="TextButton"}},Properties={BackgroundTransparency=0.1000000014901161,Name="MainWindow",BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),ZIndex=2,Size=UDim2.new(1,0,0,150),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=61,ClassName="Frame"}},Properties={Visible=false,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,350,0,20),Name="Confirmation",Position=UDim2.new(0.5,-175,0.5,-75),Draggable=true,ZIndex=3,BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=59,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Remote Debugger",Text="Remote Debugger",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Position=UDim2.new(0,4,0,0),TextSize=14,Size=UDim2.new(1,-4,1,0)},Reference=133,ClassName="TextLabel"}},Properties={BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(1,0,0,17),Name="Header",BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=132,ClassName="Frame"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="Have fun with remotes",Text="Have fun with remotes",TextStrokeTransparency=0.75,Name="Desc",BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,40),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextSize=32,BackgroundColor3=Color3.new(1,1,1)},Reference=135,ClassName="TextLabel"},{Properties={Name="GetSetting"},Reference=134,ClassName="BindableFunction"}},Properties={Name="RemoteDebugWindow",BackgroundTransparency=0.1000000014901161,Position=UDim2.new(1,0,0,0),BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Size=UDim2.new(0,300,1,0),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=131,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Ok",Text="Ok",TextStrokeTransparency=0.75,Name="Ok",BorderColor3=Color3.new(0,0,0),BackgroundTransparency=0.5,Position=UDim2.new(0.300000011920929,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),ZIndex=4,TextSize=18,BackgroundColor3=Color3.new(0.3921568989753723,0.3921568989753723,0.3921568989753723)},Reference=69,ClassName="TextButton"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="The file, FILENAME, already exists. Overwrite?",Text="The file, FILENAME, already exists. Overwrite?",TextStrokeTransparency=0.75,Name="Desc",FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,42),ZIndex=4,TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=68,ClassName="TextLabel"}},Properties={BackgroundTransparency=0.1000000014901161,Name="MainWindow",BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),ZIndex=4,Size=UDim2.new(1,0,0,150),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=67,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Caution",Text="Caution",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Title",ZIndex=5,TextSize=14,Size=UDim2.new(1,0,1,0)},Reference=66,ClassName="TextLabel"}},Properties={Visible=false,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,350,0,20),Name="Caution",Position=UDim2.new(0.5,-175,0.5,-75),Draggable=true,ZIndex=5,BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=65,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Workspace",Text="Workspace",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Info",Position=UDim2.new(0,40,0,0),TextSize=18,Size=UDim2.new(1,-40,0,22)},Reference=130,ClassName="TextLabel"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",Name="enabled",BackgroundTransparency=0.4000000059604645,Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,14,0,14),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0.3803921937942505,0.3803921937942505,0.3803921937942505)},Reference=129,ClassName="TextLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",Name="Change",BackgroundTransparency=0.6000000238418579,Position=UDim2.new(0,10,0,1),Size=UDim2.new(0,20,0,20),ZIndex=2,TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=128,ClassName="TextButton"}},Properties={Visible=false,BackgroundTransparency=1,Name="Entry",Size=UDim2.new(1,0,0,22),BackgroundColor3=Color3.new(1,1,1)},Reference=127,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="PlaceName",TextStrokeTransparency=0.75,Name="FileName",Size=UDim2.new(1,0,0,25),BackgroundTransparency=0.6000000238418579,PlaceholderColor3=Color3.new(0.6980392336845398,0.6980392336845398,0.6980392336845398),Position=UDim2.new(0,0,1,-105),TextXAlignment=Enum.TextXAlignment.Left,TextSize=18,BackgroundColor3=Color3.new(0.9411765336990356,0.9411765336990356,0.9411765336990356)},Reference=126,ClassName="TextBox"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Map Downloader",Text="Map Downloader",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,BorderSizePixel=0,Position=UDim2.new(0,4,0,0),TextSize=14,Size=UDim2.new(1,-4,1,0)},Reference=95,ClassName="TextLabel"}},Properties={Name="Header",BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(1,0,0,17),BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=94,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save",Text="Save",TextStrokeTransparency=0.75,Name="Save",BackgroundTransparency=0.800000011920929,Position=UDim2.new(0,0,1,-80),Size=UDim2.new(1,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(0.9411765336990356,0.9411765336990356,0.9411765336990356)},Reference=125,ClassName="TextButton"},{Children={{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="After the map saves, open a new place on studio, then right click Lighting and \"Insert from file...\", then select your file and run the unpacker script inside the folder.",Text="After the map saves, open a new place on studio, then right click Lighting and \"Insert from file...\", then select your file and run the unpacker script inside the folder.",TextStrokeTransparency=0.800000011920929,FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Position=UDim2.new(0,4,0,0),TextYAlignment=Enum.TextYAlignment.Top,TextSize=14,Size=UDim2.new(1,-4,1,0)},Reference=124,ClassName="TextLabel"}},Properties={Name="Bottom",Position=UDim2.new(0,0,1,-50),BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(1,0,0,50),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=123,ClassName="Frame"},{Children={{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="OnBar",Size=UDim2.new(0,0,0,15),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0,0.5764706134796143,0.8627451658248901)},Reference=119,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),ClipsDescendants=true,Text="",Name="Bar",Position=UDim2.new(0,-2,0,-2),Size=UDim2.new(0,10,0,19),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0,0,0)},Reference=120,ClassName="TextLabel"}},Properties={Size=UDim2.new(0,40,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="Change",Position=UDim2.new(0,10,0,30),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0.8627451658248901,0.8627451658248901,0.8627451658248901)},Reference=118,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Off",Text="Off",TextStrokeTransparency=0.75,Name="Status",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0,50,0,15),Position=UDim2.new(0,60,0,30),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=117,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save Scripts",Text="Save Scripts",TextStrokeTransparency=0.75,Name="SName",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,-20,0,30),Position=UDim2.new(0,10,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=116,ClassName="TextLabel"}},Properties={Name="Scripts",Size=UDim2.new(1,0,0,60),BackgroundTransparency=1,BackgroundColor3=Color3.new(1,1,1)},Reference=115,ClassName="Frame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Off",Text="Off",TextStrokeTransparency=0.75,Name="Status",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0,50,0,15),Position=UDim2.new(0,60,0,30),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=105,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Lighting Properties",Text="Lighting Properties",TextStrokeTransparency=0.75,Name="SName",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,-20,0,30),Position=UDim2.new(0,10,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=104,ClassName="TextLabel"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="OnBar",Size=UDim2.new(0,0,0,15),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0,0.5764706134796143,0.8627451658248901)},Reference=107,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),ClipsDescendants=true,Text="",Name="Bar",Position=UDim2.new(0,-2,0,-2),Size=UDim2.new(0,10,0,19),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0,0,0)},Reference=108,ClassName="TextLabel"}},Properties={Size=UDim2.new(0,40,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="Change",Position=UDim2.new(0,10,0,30),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0.8627451658248901,0.8627451658248901,0.8627451658248901)},Reference=106,ClassName="TextButton"}},Properties={Visible=false,BackgroundTransparency=1,Position=UDim2.new(0,0,0,120),Name="Lighting",Size=UDim2.new(1,0,0,60),BackgroundColor3=Color3.new(1,1,1)},Reference=103,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),ClipsDescendants=true,Text="",Name="Bar",Position=UDim2.new(0,-2,0,-2),Size=UDim2.new(0,10,0,19),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0,0,0)},Reference=114,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="OnBar",Size=UDim2.new(0,0,0,15),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0,0.5764706134796143,0.8627451658248901)},Reference=113,ClassName="TextLabel"}},Properties={Size=UDim2.new(0,40,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="Change",Position=UDim2.new(0,10,0,30),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0.8627451658248901,0.8627451658248901,0.8627451658248901)},Reference=112,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Off",Text="Off",TextStrokeTransparency=0.75,Name="Status",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0,50,0,15),Position=UDim2.new(0,60,0,30),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=111,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Camera Instances",Text="Camera Instances",TextStrokeTransparency=0.75,Name="SName",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,-20,0,30),Position=UDim2.new(0,10,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=110,ClassName="TextLabel"}},Properties={Visible=false,BackgroundTransparency=1,Position=UDim2.new(0,0,0,180),Name="CameraInstances",Size=UDim2.new(1,0,0,60),BackgroundColor3=Color3.new(1,1,1)},Reference=109,ClassName="Frame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Off",Text="Off",TextStrokeTransparency=0.75,Name="Status",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0,50,0,15),Position=UDim2.new(0,60,0,30),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=99,ClassName="TextLabel"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="OnBar",Size=UDim2.new(0,0,0,15),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0,0.5764706134796143,0.8627451658248901)},Reference=101,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),ClipsDescendants=true,Text="",Name="Bar",Position=UDim2.new(0,-2,0,-2),Size=UDim2.new(0,10,0,19),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0,0,0)},Reference=102,ClassName="TextLabel"}},Properties={Size=UDim2.new(0,40,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="Change",Position=UDim2.new(0,10,0,30),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0.8627451658248901,0.8627451658248901,0.8627451658248901)},Reference=100,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save Terrain",Text="Save Terrain",TextStrokeTransparency=0.75,Name="SName",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,-20,0,30),Position=UDim2.new(0,10,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=98,ClassName="TextLabel"}},Properties={Visible=false,BackgroundTransparency=1,Position=UDim2.new(0,0,0,60),Name="Terrain",Size=UDim2.new(1,0,0,60),BackgroundColor3=Color3.new(1,1,1)},Reference=97,ClassName="Frame"}},Properties={BackgroundTransparency=1,Position=UDim2.new(0,0,0,200),Name="MapSettings",Size=UDim2.new(1,0,0,240),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=96,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="To Save",Text="To Save",TextStrokeTransparency=0.75,BackgroundTransparency=1,Position=UDim2.new(0,0,0,17),Name="ToSave",TextSize=18,Size=UDim2.new(1,0,0,20)},Reference=121,ClassName="TextLabel"},{Properties={BackgroundTransparency=0.800000011920929,Position=UDim2.new(0,0,0,37),Name="CopyList",Size=UDim2.new(1,0,0,163),BackgroundColor3=Color3.new(0.6078431606292725,0.6078431606292725,0.6078431606292725)},Reference=122,ClassName="Frame"}},Properties={Name="SaveMapWindow",BackgroundTransparency=0.1000000014901161,Position=UDim2.new(1,0,0,0),BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Size=UDim2.new(0,300,1,0),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=93,ClassName="Frame"},{Closure=function() local Gui = script.Parent | |
local HttpService = game:GetService'HttpService'; | |
local IntroFrame = Gui:WaitForChild("IntroFrame") | |
local SideMenu = Gui:WaitForChild("SideMenu") | |
local OpenToggleButton = Gui:WaitForChild("Toggle") | |
local CloseToggleButton = SideMenu:WaitForChild("Toggle") | |
local OpenScriptEditorButton = SideMenu:WaitForChild("OpenScriptEditor") | |
local ScriptEditor = Gui:WaitForChild("ScriptEditor") | |
local SlideOut = SideMenu:WaitForChild("SlideOut") | |
local SlideFrame = SlideOut:WaitForChild("SlideFrame") | |
local Slant = SideMenu:WaitForChild("Slant") | |
local ExplorerButton = SlideFrame:WaitForChild("Explorer") | |
local SettingsButton = SlideFrame:WaitForChild("Settings") | |
local ExplorerPanel = Gui:WaitForChild("ExplorerPanel") | |
local PropertiesFrame = Gui:WaitForChild("PropertiesFrame") | |
local SaveMapWindow = Gui:WaitForChild("SaveMapWindow") | |
local RemoteDebugWindow = Gui:WaitForChild("RemoteDebugWindow") | |
local SettingsPanel = Gui:WaitForChild("SettingsPanel") | |
local AboutPanel = Gui:WaitForChild("About") | |
local SettingsListener = SettingsPanel:WaitForChild("GetSetting") | |
local SettingTemplate = SettingsPanel:WaitForChild("SettingTemplate") | |
local SettingList = SettingsPanel:WaitForChild("SettingList") | |
local SaveMapCopyList = SaveMapWindow:WaitForChild("CopyList") | |
local SaveMapSettingFrame = SaveMapWindow:WaitForChild("MapSettings") | |
local SaveMapName = SaveMapWindow:WaitForChild("FileName") | |
local SaveMapButton = SaveMapWindow:WaitForChild("Save") | |
local SaveMapCopyTemplate = SaveMapWindow:WaitForChild("Entry") | |
local SaveMapSettings = { | |
CopyWhat = { | |
Workspace = true, | |
Lighting = true, | |
ReplicatedStorage = true, | |
ReplicatedFirst = true, | |
StarterPack = true, | |
StarterGui = true, | |
StarterPlayer = true | |
}, | |
SaveScripts = true, | |
SaveTerrain = true, | |
LightingProperties = true, | |
CameraInstances = true | |
} | |
--[[ | |
local ClickSelectOption = SettingsPanel:WaitForChild("ClickSelect"):WaitForChild("Change") | |
local SelectionBoxOption = SettingsPanel:WaitForChild("SelectionBox"):WaitForChild("Change") | |
local ClearPropsOption = SettingsPanel:WaitForChild("ClearProperties"):WaitForChild("Change") | |
local SelectUngroupedOption = SettingsPanel:WaitForChild("SelectUngrouped"):WaitForChild("Change") | |
--]] | |
local SelectionObjectChanged = ExplorerPanel:WaitForChild("SelectionObjectChanged") | |
local GetSelection = ExplorerPanel:WaitForChild("GetSelection") | |
local SetSelection = ExplorerPanel:WaitForChild("SetSelection") | |
local Player = game:GetService("Players").LocalPlayer | |
local Mouse = Player:GetMouse() | |
local CurrentWindow = "Nothing c:" | |
local Windows = { | |
Explorer = { | |
ExplorerPanel, | |
PropertiesFrame | |
}, | |
Settings = {SettingsPanel}, | |
SaveMap = {SaveMapWindow}, | |
Remotes = {RemoteDebugWindow}, | |
About = {AboutPanel}, | |
} | |
function switchWindows(wName,over) | |
if CurrentWindow == wName and not over then return end | |
local count = 0 | |
for i,v in pairs(Windows) do | |
count = 0 | |
if i ~= wName then | |
for _,c in pairs(v) do c:TweenPosition(UDim2.new(1, 30, count * 0.5, count * 36), "Out", "Quad", 0.5, true) count = count + 1 end | |
end | |
end | |
count = 0 | |
if Windows[wName] then | |
for _,c in pairs(Windows[wName]) do c:TweenPosition(UDim2.new(1, -300, count * 0.5, count * 36), "Out", "Quad", 0.5, true) count = count + 1 end | |
end | |
if wName ~= "Nothing c:" then | |
CurrentWindow = wName | |
for i,v in pairs(SlideFrame:GetChildren()) do | |
v.BackgroundTransparency = 1 | |
v.Icon.ImageColor3 = Color3.new(0.6, 0.6, 0.6) | |
end | |
if SlideFrame:FindFirstChild(wName) then | |
SlideFrame[wName].BackgroundTransparency = 1 | |
SlideFrame[wName].Icon.ImageColor3 = Color3.new(1,1,1) | |
end | |
end | |
end | |
function toggleDex(on) | |
if on then | |
SideMenu:TweenPosition(UDim2.new(1, -330, 0, 0), "Out", "Quad", 0.5, true) | |
OpenToggleButton:TweenPosition(UDim2.new(1,0,0,0), "Out", "Quad", 0.5, true) | |
switchWindows(CurrentWindow,true) | |
else | |
SideMenu:TweenPosition(UDim2.new(1, 0, 0, 0), "Out", "Quad", 0.5, true) | |
OpenToggleButton:TweenPosition(UDim2.new(1,-40,0,0), "Out", "Quad", 0.5, true) | |
switchWindows("Nothing c:") | |
end | |
end | |
local Settings = { | |
ClickSelect = false, | |
SelBox = false, | |
ClearProps = false, | |
SelectUngrouped = true, | |
SaveInstanceScripts = true, | |
UseNewDecompiler = true | |
} | |
pcall(function() | |
local content = readfile('dexv3_settings.json'); | |
if content ~= nil and content ~= '' then | |
local Saved = HttpService:JSONDecode(content); | |
for i, v in pairs(Saved) do | |
if Settings[i] ~= nil then | |
Settings[i] = v; | |
end | |
end | |
end | |
end) | |
function SaveSettings() | |
local JSON = HttpService:JSONEncode(Settings); | |
writefile('dexv3_settings.json', JSON); | |
end | |
local _decompile = decompile; | |
function decompile(s, ...) | |
if Settings.UseNewDecompiler then | |
return _decompile(s, 'new'); | |
else | |
return _decompile(s, 'legacy'); | |
end | |
end | |
function ReturnSetting(set) | |
if set == 'ClearProps' then | |
return Settings.ClearProps | |
elseif set == 'SelectUngrouped' then | |
return Settings.SelectUngrouped | |
elseif set == 'UseNewDecompiler' then | |
return Settings.UseNewDecompiler | |
end | |
end | |
OpenToggleButton.MouseButton1Up:connect(function() | |
toggleDex(true) | |
end) | |
OpenScriptEditorButton.MouseButton1Up:connect(function() | |
if OpenScriptEditorButton.Active then | |
ScriptEditor.Visible = true | |
end | |
end) | |
CloseToggleButton.MouseButton1Up:connect(function() | |
if CloseToggleButton.Active then | |
toggleDex(false) | |
end | |
end) | |
--[[ | |
OpenToggleButton.MouseButton1Up:connect(function() | |
SideMenu:TweenPosition(UDim2.new(1, -330, 0, 0), "Out", "Quad", 0.5, true) | |
if CurrentWindow == "Explorer" then | |
ExplorerPanel:TweenPosition(UDim2.new(1, -300, 0, 0), "Out", "Quad", 0.5, true) | |
PropertiesFrame:TweenPosition(UDim2.new(1, -300, 0.5, 36), "Out", "Quad", 0.5, true) | |
else | |
SettingsPanel:TweenPosition(UDim2.new(1, -300, 0, 0), "Out", "Quad", 0.5, true) | |
end | |
OpenToggleButton:TweenPosition(UDim2.new(1,0,0,0), "Out", "Quad", 0.5, true) | |
end) | |
CloseToggleButton.MouseButton1Up:connect(function() | |
SideMenu:TweenPosition(UDim2.new(1, 0, 0, 0), "Out", "Quad", 0.5, true) | |
ExplorerPanel:TweenPosition(UDim2.new(1, 30, 0, 0), "Out", "Quad", 0.5, true) | |
PropertiesFrame:TweenPosition(UDim2.new(1, 30, 0.5, 36), "Out", "Quad", 0.5, true) | |
SettingsPanel:TweenPosition(UDim2.new(1, 30, 0, 0), "Out", "Quad", 0.5, true) | |
OpenToggleButton:TweenPosition(UDim2.new(1,-30,0,0), "Out", "Quad", 0.5, true) | |
end) | |
--]] | |
--[[ | |
ExplorerButton.MouseButton1Up:connect(function() | |
switchWindows("Explorer") | |
end) | |
SettingsButton.MouseButton1Up:connect(function() | |
switchWindows("Settings") | |
end) | |
--]] | |
for i,v in pairs(SlideFrame:GetChildren()) do | |
v.MouseButton1Click:connect(function() | |
switchWindows(v.Name) | |
end) | |
-- v.MouseEnter:connect(function()v.BackgroundTransparency = 0.5 end) | |
-- v.MouseLeave:connect(function()if CurrentWindow~=v.Name then v.BackgroundTransparency = 1 end end) | |
end | |
--[[ | |
ExplorerButton.MouseButton1Up:connect(function() | |
if CurrentWindow ~= "Explorer" then | |
CurrentWindow = "Explorer" | |
ExplorerPanel:TweenPosition(UDim2.new(1, -300, 0, 0), "Out", "Quad", 0.5, true) | |
PropertiesFrame:TweenPosition(UDim2.new(1, -300, 0.5, 36), "Out", "Quad", 0.5, true) | |
SettingsPanel:TweenPosition(UDim2.new(1, 0, 0, 0), "Out", "Quad", 0.5, true) | |
end | |
end) | |
SettingsButton.MouseButton1Up:connect(function() | |
if CurrentWindow ~= "Settings" then | |
CurrentWindow = "Settings" | |
ExplorerPanel:TweenPosition(UDim2.new(1, 0, 0, 0), "Out", "Quad", 0.5, true) | |
PropertiesFrame:TweenPosition(UDim2.new(1, 0, 0.5, 36), "Out", "Quad", 0.5, true) | |
SettingsPanel:TweenPosition(UDim2.new(1, -300, 0, 0), "Out", "Quad", 0.5, true) | |
end | |
end) | |
--]] | |
function createSetting(name,interName,defaultOn) | |
local newSetting = SettingTemplate:Clone() | |
newSetting.Position = UDim2.new(0,0,0,#SettingList:GetChildren() * 60) | |
newSetting.SName.Text = name | |
local function toggle(on) | |
if on then | |
newSetting.Change.Bar:TweenPosition(UDim2.new(0,32,0,-2),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
newSetting.Change.OnBar:TweenSize(UDim2.new(0,34,0,15),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
newSetting.Status.Text = "On" | |
Settings[interName] = true | |
else | |
newSetting.Change.Bar:TweenPosition(UDim2.new(0,-2,0,-2),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
newSetting.Change.OnBar:TweenSize(UDim2.new(0,0,0,15),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
newSetting.Status.Text = "Off" | |
Settings[interName] = false | |
end | |
end | |
newSetting.Change.MouseButton1Click:connect(function() | |
toggle(not Settings[interName]) | |
wait(1 / 12); | |
pcall(SaveSettings); | |
end) | |
newSetting.Visible = true | |
newSetting.Parent = SettingList | |
if defaultOn then | |
toggle(true) | |
end | |
end | |
createSetting("Click part to select","ClickSelect",false) | |
createSetting("Selection Box","SelBox",false) | |
createSetting("Clear property value on focus","ClearProps",false) | |
createSetting("Select ungrouped models","SelectUngrouped",true) | |
createSetting("SaveInstance decompiles scripts","SaveInstanceScripts",true) | |
createSetting("Use New Decompiler","UseNewDecompiler",false) | |
--[[ | |
ClickSelectOption.MouseButton1Up:connect(function() | |
if Settings.ClickSelect then | |
Settings.ClickSelect = false | |
ClickSelectOption.Text = "OFF" | |
else | |
Settings.ClickSelect = true | |
ClickSelectOption.Text = "ON" | |
end | |
end) | |
SelectionBoxOption.MouseButton1Up:connect(function() | |
if Settings.SelBox then | |
Settings.SelBox = false | |
SelectionBox.Adornee = nil | |
SelectionBoxOption.Text = "OFF" | |
else | |
Settings.SelBox = true | |
SelectionBoxOption.Text = "ON" | |
end | |
end) | |
ClearPropsOption.MouseButton1Up:connect(function() | |
if Settings.ClearProps then | |
Settings.ClearProps = false | |
ClearPropsOption.Text = "OFF" | |
else | |
Settings.ClearProps = true | |
ClearPropsOption.Text = "ON" | |
end | |
end) | |
SelectUngroupedOption.MouseButton1Up:connect(function() | |
if Settings.SelectUngrouped then | |
Settings.SelectUngrouped = false | |
SelectUngroupedOption.Text = "OFF" | |
else | |
Settings.SelectUngrouped = true | |
SelectUngroupedOption.Text = "ON" | |
end | |
end) | |
--]] | |
local function getSelection() | |
local t = GetSelection:Invoke() | |
if t and #t > 0 then | |
return t[1] | |
else | |
return nil | |
end | |
end | |
Mouse.Button1Down:connect(function() | |
if CurrentWindow == "Explorer" and Settings.ClickSelect then | |
local target = Mouse.Target | |
if target then | |
SetSelection:Invoke({target}) | |
end | |
end | |
end) | |
SelectionObjectChanged.Event:connect(function() | |
end) | |
SettingsListener.OnInvoke = ReturnSetting | |
-- Map Copier | |
function createMapSetting(obj,interName,defaultOn) | |
local function toggle(on) | |
if on then | |
obj.Change.Bar:TweenPosition(UDim2.new(0,32,0,-2),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
obj.Change.OnBar:TweenSize(UDim2.new(0,34,0,15),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
obj.Status.Text = "On" | |
SaveMapSettings[interName] = true | |
else | |
obj.Change.Bar:TweenPosition(UDim2.new(0,-2,0,-2),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
obj.Change.OnBar:TweenSize(UDim2.new(0,0,0,15),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true) | |
obj.Status.Text = "Off" | |
SaveMapSettings[interName] = false | |
end | |
end | |
obj.Change.MouseButton1Click:connect(function() | |
toggle(not SaveMapSettings[interName]) | |
end) | |
obj.Visible = true | |
obj.Parent = SaveMapSettingFrame | |
if defaultOn then | |
toggle(true) | |
end | |
end | |
function createCopyWhatSetting(serv) | |
if SaveMapSettings.CopyWhat[serv] then | |
local newSetting = SaveMapCopyTemplate:Clone() | |
newSetting.Position = UDim2.new(0,0,0,#SaveMapCopyList:GetChildren() * 22 + 5) | |
newSetting.Info.Text = serv | |
local function toggle(on) | |
if on then | |
newSetting.Change.enabled.Visible = true | |
SaveMapSettings.CopyWhat[serv] = true | |
else | |
newSetting.Change.enabled.Visible = false | |
SaveMapSettings.CopyWhat[serv] = false | |
end | |
end | |
newSetting.Change.MouseButton1Click:connect(function() | |
toggle(not SaveMapSettings.CopyWhat[serv]) | |
end) | |
newSetting.Visible = true | |
newSetting.Parent = SaveMapCopyList | |
end | |
end | |
createMapSetting(SaveMapSettingFrame.Scripts,"SaveScripts",true) | |
-- createMapSetting(SaveMapSettingFrame.Terrain,"SaveTerrain",true) | |
-- createMapSetting(SaveMapSettingFrame.Lighting,"LightingProperties",true) | |
-- createMapSetting(SaveMapSettingFrame.CameraInstances,"CameraInstances",true) | |
createCopyWhatSetting("Workspace") | |
createCopyWhatSetting("Lighting") | |
createCopyWhatSetting("ReplicatedStorage") | |
createCopyWhatSetting("ReplicatedFirst") | |
createCopyWhatSetting("StarterPack") | |
createCopyWhatSetting("StarterGui") | |
createCopyWhatSetting("StarterPlayer") | |
SaveMapName.Text = tostring(game.PlaceId).."MapCopy" | |
SaveMapButton.MouseButton1Click:connect(function() | |
local copyWhat = {} | |
local copyGroup = Instance.new("Model",game:GetService('ReplicatedStorage')) | |
local copyScripts = SaveMapSettings.SaveScripts | |
-- local copyTerrain = SaveMapSettings.SaveTerrain | |
-- local lightingProperties = SaveMapSettings.LightingProperties | |
-- local cameraInstances = SaveMapSettings.CameraInstances | |
-- local PlaceName = game:GetService'MarketplaceService':GetProductInfo(game.PlaceId).Name; | |
-- PlaceName = PlaceName:gsub('%p', ''); | |
if copyScripts then | |
saveinstance{ noscripts = false, mode = "optimized" } | |
else | |
saveinstance{ noscripts = true, mode = "optimized" } | |
end | |
----------------------------------------------------------------------------------- | |
--[[for i,v in pairs(SaveMapSettings.CopyWhat) do | |
if v then | |
table.insert(copyWhat,i) | |
end | |
end | |
local consoleFunc = printconsole or writeconsole | |
if consoleFunc then | |
consoleFunc("Moon's place copier loaded.") | |
consoleFunc("Copying map of game "..tostring(game.PlaceId)..".") | |
end | |
function archivable(root) | |
for i,v in pairs(root:GetChildren()) do | |
if not game:GetService('Players'):GetPlayerFromCharacter(v) then | |
v.Archivable = true | |
archivable(v) | |
end | |
end | |
end | |
function decompileS(root) | |
for i,v in pairs(root:GetChildren()) do | |
pcall(function() | |
if v:IsA("LocalScript") then | |
local isDisabled = v.Disabled | |
v.Disabled = true | |
v.Source = decompile(v) | |
v.Disabled = isDisabled | |
if v.Source == "" then | |
if consoleFunc then consoleFunc("LocalScript "..v.Name.." had a problem decompiling.") end | |
else | |
if consoleFunc then consoleFunc("LocalScript "..v.Name.." decompiled.") end | |
end | |
elseif v:IsA("ModuleScript") then | |
v.Source = decompile(v) | |
if v.Source == "" then | |
if consoleFunc then consoleFunc("ModuleScript "..v.Name.." had a problem decompiling.") end | |
else | |
if consoleFunc then consoleFunc("ModuleScript "..v.Name.." decompiled.") end | |
end | |
end | |
end) | |
decompileS(v) | |
end | |
end | |
for i,v in pairs(copyWhat) do archivable(game[v]) end | |
for j,obj in pairs(copyWhat) do | |
if obj ~= "StarterPlayer" then | |
local newFolder = Instance.new("Folder",copyGroup) | |
newFolder.Name = obj | |
for i,v in pairs(game[obj]:GetChildren()) do | |
if v ~= copyGroup then | |
pcall(function() | |
v:Clone().Parent = newFolder | |
end) | |
end | |
end | |
else | |
local newFolder = Instance.new("Model",copyGroup) | |
newFolder.Name = "StarterPlayer" | |
for i,v in pairs(game[obj]:GetChildren()) do | |
local newObj = Instance.new("Folder",newFolder) | |
newObj.Name = v.Name | |
for _,c in pairs(v:GetChildren()) do | |
if c.Name ~= "ControlScript" and c.Name ~= "CameraScript" then | |
c:Clone().Parent = newObj | |
end | |
end | |
end | |
end | |
end | |
if workspace.CurrentCamera and cameraInstances then | |
local cameraFolder = Instance.new("Model",copyGroup) | |
cameraFolder.Name = "CameraItems" | |
for i,v in pairs(workspace.CurrentCamera:GetChildren()) do v:Clone().Parent = cameraFolder end | |
end | |
if copyTerrain then | |
local myTerrain = workspace.Terrain:CopyRegion(workspace.Terrain.MaxExtents) | |
myTerrain.Parent = copyGroup | |
end | |
function saveProp(obj,prop,par) | |
local myProp = obj[prop] | |
if type(myProp) == "boolean" then | |
local newProp = Instance.new("BoolValue",par) | |
newProp.Name = prop | |
newProp.Value = myProp | |
elseif type(myProp) == "number" then | |
local newProp = Instance.new("IntValue",par) | |
newProp.Name = prop | |
newProp.Value = myProp | |
elseif type(myProp) == "string" then | |
local newProp = Instance.new("StringValue",par) | |
newProp.Name = prop | |
newProp.Value = myProp | |
elseif type(myProp) == "userdata" then -- Assume Color3 | |
pcall(function() | |
local newProp = Instance.new("Color3Value",par) | |
newProp.Name = prop | |
newProp.Value = myProp | |
end) | |
end | |
end | |
if lightingProperties then | |
local lightingProps = Instance.new("Model",copyGroup) | |
lightingProps.Name = "LightingProperties" | |
saveProp(game:GetService('Lighting'),"Ambient",lightingProps) | |
saveProp(game:GetService('Lighting'),"Brightness",lightingProps) | |
saveProp(game:GetService('Lighting'),"ColorShift_Bottom",lightingProps) | |
saveProp(game:GetService('Lighting'),"ColorShift_Top",lightingProps) | |
saveProp(game:GetService('Lighting'),"GlobalShadows",lightingProps) | |
saveProp(game:GetService('Lighting'),"OutdoorAmbient",lightingProps) | |
saveProp(game:GetService('Lighting'),"Outlines",lightingProps) | |
saveProp(game:GetService('Lighting'),"GeographicLatitude",lightingProps) | |
saveProp(game:GetService('Lighting'),"TimeOfDay",lightingProps) | |
saveProp(game:GetService('Lighting'),"FogColor",lightingProps) | |
saveProp(game:GetService('Lighting'),"FogEnd",lightingProps) | |
saveProp(game:GetService('Lighting'),"FogStart",lightingProps) | |
end | |
if decompile and copyScripts then | |
-- decompileS(copyGroup) | |
end | |
if SaveInstance then | |
SaveInstance(copyGroup,SaveMapName.Text..".rbxm") | |
elseif saveinstance then | |
saveinstance(getelysianpath()..SaveMapName.Text..".rbxm",copyGroup) | |
end | |
--print("Saved!") | |
if consoleFunc then | |
consoleFunc("The map has been copied.") | |
end | |
SaveMapButton.Text = "The map has been saved" | |
wait(5) | |
SaveMapButton.Text = "Save" | |
]] | |
end) | |
-- End Copier | |
wait() | |
IntroFrame:TweenPosition(UDim2.new(1,-301,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true) | |
switchWindows("Explorer") | |
wait(1) | |
SideMenu.Visible = true | |
for i = 0,1,0.1 do | |
IntroFrame.BackgroundTransparency = i | |
IntroFrame.Main.BackgroundTransparency = i | |
IntroFrame.Slant.ImageTransparency = i | |
IntroFrame.Title.TextTransparency = i | |
IntroFrame.Version.TextTransparency = i | |
IntroFrame.Creator.TextTransparency = i | |
IntroFrame.Sad.ImageTransparency = i | |
wait() | |
end | |
IntroFrame.Visible = false | |
SlideFrame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true) | |
OpenScriptEditorButton:TweenPosition(UDim2.new(0,0,0,150),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true) | |
CloseToggleButton:TweenPosition(UDim2.new(0,0,0,180),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true) | |
Slant:TweenPosition(UDim2.new(0,0,0,210),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true) | |
wait(0.5) | |
for i = 1,0,-0.1 do | |
OpenScriptEditorButton.Icon.ImageTransparency = i | |
CloseToggleButton.TextTransparency = i | |
wait() | |
end | |
CloseToggleButton.Active = true | |
CloseToggleButton.AutoButtonColor = false | |
OpenScriptEditorButton.Active = true | |
OpenScriptEditorButton.AutoButtonColor = false end,Properties={Disabled=true,Name="Selection"},Reference=19,ClassName="LocalScript"},{Children={{Closure=function() -- initial states | |
local Option = { | |
-- can modify object parents in the hierarchy | |
Modifiable = false; | |
-- can select objects | |
Selectable = true; | |
} | |
-- MERELY | |
Option.Modifiable = true | |
-- END MERELY | |
-- general size of GUI objects, in pixels | |
local GUI_SIZE = 16 | |
-- padding between items within each entry | |
local ENTRY_PADDING = 1 | |
-- padding between each entry | |
local ENTRY_MARGIN = 1 | |
local explorerPanel = script.Parent | |
local Input = game:GetService("UserInputService") | |
local HoldingCtrl = false | |
local HoldingShift = false | |
local DexOutput = Instance.new("Folder") | |
DexOutput.Name = "Output" | |
local DexOutputMain = Instance.new("ScreenGui", DexOutput) | |
DexOutputMain.Name = "Dex Output" | |
function print(...) | |
local Obj = Instance.new("Dialog") | |
Obj.Parent = DexOutputMain | |
Obj.Name = "" | |
for i,v in pairs({...}) do | |
Obj.Name = Obj.Name .. tostring(v) .. " " | |
end | |
end | |
explorerPanel:WaitForChild("GetPrint").OnInvoke = function() | |
return print | |
end | |
--[[ | |
# Explorer Panel | |
A GUI panel that displays the game hierarchy. | |
## Selection Bindables | |
- `Function GetSelection ( )` | |
Returns an array of objects representing the objects currently | |
selected in the panel. | |
- `Function SetSelection ( Objects selection )` | |
Sets the objects that are selected in the panel. `selection` is an array | |
of objects. | |
- `Event SelectionObjectChanged ( )` | |
Fired after the selection changes. | |
## Option Bindables | |
- `Function GetOption ( string optionName )` | |
If `optionName` is given, returns the value of that option. Otherwise, | |
returns a table of options and their current values. | |
- `Function SetOption ( string optionName, bool value )` | |
Sets `optionName` to `value`. | |
Options: | |
- Modifiable | |
Whether objects can be modified by the panel. | |
Note that modifying objects depends on being able to select them. If | |
Selectable is false, then Actions will not be available. Reparenting | |
is still possible, but only for the dragged object. | |
- Selectable | |
Whether objects can be selected. | |
If Modifiable is false, then left-clicking will perform a drag | |
selection. | |
## Updates | |
- 2013-09-18 | |
- Fixed explorer icons to match studio explorer. | |
- 2013-09-14 | |
- Added GetOption and SetOption bindables. | |
- Option: Modifiable; sets whether objects can be modified by the panel. | |
- Option: Selectable; sets whether objects can be selected. | |
- Slight modification to left-click selection behavior. | |
- Improved layout and scaling. | |
- 2013-09-13 | |
- Added drag to reparent objects. | |
- Left-click to select/deselect object. | |
- Left-click and drag unselected object to reparent single object. | |
- Left-click and drag selected object to move reparent entire selection. | |
- Right-click while dragging to cancel. | |
- 2013-09-11 | |
- Added explorer panel header with actions. | |
- Added Cut action. | |
- Added Copy action. | |
- Added Paste action. | |
- Added Delete action. | |
- Added drag selection. | |
- Left-click: Add to selection on drag. | |
- Right-click: Add to or remove from selection on drag. | |
- Ensured SelectionObjectChanged fires only when the selection actually changes. | |
- Added documentation and change log. | |
- Fixed thread issue. | |
- 2013-09-09 | |
- Added basic multi-selection. | |
- Left-click to set selection. | |
- Right-click to add to or remove from selection. | |
- Removed "Selection" ObjectValue. | |
- Added GetSelection BindableFunction. | |
- Added SetSelection BindableFunction. | |
- Added SelectionObjectChanged BindableEvent. | |
- Changed font to SourceSans. | |
- 2013-08-31 | |
- Improved GUI sizing based off of `GUI_SIZE` constant. | |
- Automatic font size detection. | |
- 2013-08-27 | |
- Initial explorer panel. | |
## Todo | |
- Sorting | |
- by ExplorerOrder | |
- by children | |
- by name | |
- Drag objects to reparent | |
]] | |
local ENTRY_SIZE = GUI_SIZE + ENTRY_PADDING*2 | |
local ENTRY_BOUND = ENTRY_SIZE + ENTRY_MARGIN | |
local HEADER_SIZE = ENTRY_SIZE*2 | |
local FONT = 'SourceSans' | |
local FONT_SIZE do | |
local size = {8,9,10,11,12,14,18,24,36,48} | |
local s | |
local n = math.huge | |
for i = 1,#size do | |
if size[i] <= GUI_SIZE then | |
FONT_SIZE = i - 1 | |
end | |
end | |
end | |
local GuiColor = { | |
Background = Color3.fromRGB(43, 43, 43); | |
Border = Color3.fromRGB(20, 20, 20); | |
Selected = Color3.fromRGB(5, 102, 141); | |
BorderSelected = Color3.fromRGB(2, 128, 144); | |
Text = Color3.fromRGB(245, 245, 245); | |
TextDisabled = Color3.fromRGB(188, 188, 188); | |
TextSelected = Color3.fromRGB(255, 255, 255); | |
Button = Color3.fromRGB(33, 33, 33); | |
ButtonBorder = Color3.fromRGB(133, 133, 133); | |
ButtonSelected = Color3.fromRGB(0, 168, 150); | |
Field = Color3.fromRGB(43, 43, 43); | |
FieldBorder = Color3.fromRGB(50, 50, 50); | |
TitleBackground = Color3.fromRGB(11, 11, 11); | |
} | |
--[[ | |
local GuiColor = { | |
Background = Color3.new(233/255, 233/255, 233/255); | |
Border = Color3.new(149/255, 149/255, 149/255); | |
Selected = Color3.new( 96/255, 140/255, 211/255); | |
BorderSelected = Color3.new( 86/255, 125/255, 188/255); | |
Text = Color3.new( 0/255, 0/255, 0/255); | |
TextDisabled = Color3.new(128/255, 128/255, 128/255); | |
TextSelected = Color3.new(255/255, 255/255, 255/255); | |
Button = Color3.new(221/255, 221/255, 221/255); | |
ButtonBorder = Color3.new(149/255, 149/255, 149/255); | |
ButtonSelected = Color3.new(255/255, 0/255, 0/255); | |
Field = Color3.new(255/255, 255/255, 255/255); | |
FieldBorder = Color3.new(191/255, 191/255, 191/255); | |
TitleBackground = Color3.new(178/255, 178/255, 178/255); | |
} | |
]] | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- Icon map constants | |
local MAP_ID = 483448923 | |
-- Indices based on implementation of Icon function. | |
local ACTION_CUT = 160 | |
local ACTION_COPY = 161 | |
local ACTION_PASTE = 162 | |
local ACTION_DELETE = 163 | |
local ACTION_SORT = 164 | |
local ACTION_CUT_OVER = 174 | |
local ACTION_COPY_OVER = 175 | |
local ACTION_PASTE_OVER = 176 | |
local ACTION_DELETE_OVER = 177 | |
local ACTION_SORT_OVER = 178 | |
local ACTION_EDITQUICKACCESS = 190 | |
local ACTION_FREEZE = 188 | |
local ACTION_STARRED = 189 | |
local ACTION_ADDSTAR = 184 | |
local ACTION_ADDSTAR_OVER = 187 | |
local NODE_COLLAPSED = 165 | |
local NODE_EXPANDED = 166 | |
local NODE_COLLAPSED_OVER = 179 | |
local NODE_EXPANDED_OVER = 180 | |
local ExplorerIndex = { | |
["Accessory"] = 32; | |
["Accoutrement"] = 32; | |
["AdService"] = 73; | |
["Animation"] = 60; | |
["AnimationController"] = 60; | |
["AnimationTrack"] = 60; | |
["Animator"] = 60; | |
["ArcHandles"] = 56; | |
["AssetService"] = 72; | |
["Attachment"] = 34; | |
["Backpack"] = 20; | |
["BadgeService"] = 75; | |
["BallSocketConstraint"] = 89; | |
["BillboardGui"] = 64; | |
["BinaryStringValue"] = 4; | |
["BindableEvent"] = 67; | |
["BindableFunction"] = 66; | |
["BlockMesh"] = 8; | |
["BloomEffect"] = 90; | |
["BlurEffect"] = 90; | |
["BodyAngularVelocity"] = 14; | |
["BodyForce"] = 14; | |
["BodyGyro"] = 14; | |
["BodyPosition"] = 14; | |
["BodyThrust"] = 14; | |
["BodyVelocity"] = 14; | |
["BoolValue"] = 4; | |
["BoxHandleAdornment"] = 54; | |
["BrickColorValue"] = 4; | |
["Camera"] = 5; | |
["CFrameValue"] = 4; | |
["CharacterMesh"] = 60; | |
["Chat"] = 33; | |
["ClickDetector"] = 41; | |
["CollectionService"] = 30; | |
["Color3Value"] = 4; | |
["ColorCorrectionEffect"] = 90; | |
["ConeHandleAdornment"] = 54; | |
["Configuration"] = 58; | |
["ContentProvider"] = 72; | |
["ContextActionService"] = 41; | |
["CoreGui"] = 46; | |
["CoreScript"] = 18; | |
["CornerWedgePart"] = 1; | |
["CustomEvent"] = 4; | |
["CustomEventReceiver"] = 4; | |
["CylinderHandleAdornment"] = 54; | |
["CylinderMesh"] = 8; | |
["CylindricalConstraint"] = 89; | |
["Debris"] = 30; | |
["Decal"] = 7; | |
["Dialog"] = 62; | |
["DialogChoice"] = 63; | |
["DoubleConstrainedValue"] = 4; | |
["Explosion"] = 36; | |
["FileMesh"] = 8; | |
["Fire"] = 61; | |
["Flag"] = 38; | |
["FlagStand"] = 39; | |
["FloorWire"] = 4; | |
["Folder"] = 70; | |
["ForceField"] = 37; | |
["Frame"] = 48; | |
["GamePassService"] = 19; | |
["Glue"] = 34; | |
["GuiButton"] = 52; | |
["GuiMain"] = 47; | |
["GuiService"] = 47; | |
["Handles"] = 53; | |
["HapticService"] = 84; | |
["Hat"] = 45; | |
["HingeConstraint"] = 89; | |
["Hint"] = 33; | |
["HopperBin"] = 22; | |
["HttpService"] = 76; | |
["Humanoid"] = 9; | |
["ImageButton"] = 52; | |
["ImageLabel"] = 49; | |
["InsertService"] = 72; | |
["IntConstrainedValue"] = 4; | |
["IntValue"] = 4; | |
["JointInstance"] = 34; | |
["JointsService"] = 34; | |
["Keyframe"] = 60; | |
["KeyframeSequence"] = 60; | |
["KeyframeSequenceProvider"] = 60; | |
["Lighting"] = 13; | |
["LineHandleAdornment"] = 54; | |
["LocalScript"] = 18; | |
["LogService"] = 87; | |
["MarketplaceService"] = 46; | |
["Message"] = 33; | |
["Model"] = 2; | |
["ModuleScript"] = 71; | |
["Motor"] = 34; | |
["Motor6D"] = 34; | |
["MoveToConstraint"] = 89; | |
["NegateOperation"] = 78; | |
["NetworkClient"] = 16; | |
["NetworkReplicator"] = 29; | |
["NetworkServer"] = 15; | |
["NumberValue"] = 4; | |
["ObjectValue"] = 4; | |
["Pants"] = 44; | |
["ParallelRampPart"] = 1; | |
["Part"] = 1; | |
["ParticleEmitter"] = 69; | |
["PartPairLasso"] = 57; | |
["PathfindingService"] = 37; | |
["Platform"] = 35; | |
["Player"] = 12; | |
["PlayerGui"] = 46; | |
["Players"] = 21; | |
["PlayerScripts"] = 82; | |
["PointLight"] = 13; | |
["PointsService"] = 83; | |
["Pose"] = 60; | |
["PrismaticConstraint"] = 89; | |
["PrismPart"] = 1; | |
["PyramidPart"] = 1; | |
["RayValue"] = 4; | |
["ReflectionMetadata"] = 86; | |
["ReflectionMetadataCallbacks"] = 86; | |
["ReflectionMetadataClass"] = 86; | |
["ReflectionMetadataClasses"] = 86; | |
["ReflectionMetadataEnum"] = 86; | |
["ReflectionMetadataEnumItem"] = 86; | |
["ReflectionMetadataEnums"] = 86; | |
["ReflectionMetadataEvents"] = 86; | |
["ReflectionMetadataFunctions"] = 86; | |
["ReflectionMetadataMember"] = 86; | |
["ReflectionMetadataProperties"] = 86; | |
["ReflectionMetadataYieldFunctions"] = 86; | |
["RemoteEvent"] = 80; | |
["RemoteFunction"] = 79; | |
["ReplicatedFirst"] = 72; | |
["ReplicatedStorage"] = 72; | |
["RightAngleRampPart"] = 1; | |
["RocketPropulsion"] = 14; | |
["RodConstraint"] = 89; | |
["RopeConstraint"] = 89; | |
["Rotate"] = 34; | |
["RotateP"] = 34; | |
["RotateV"] = 34; | |
["RunService"] = 66; | |
["ScreenGui"] = 47; | |
["Script"] = 6; | |
["ScrollingFrame"] = 48; | |
["Seat"] = 35; | |
["Selection"] = 55; | |
["SelectionBox"] = 54; | |
["SelectionPartLasso"] = 57; | |
["SelectionPointLasso"] = 57; | |
["SelectionSphere"] = 54; | |
["ServerScriptService"] = 0; | |
["Shirt"] = 43; | |
["ShirtGraphic"] = 40; | |
["SkateboardPlatform"] = 35; | |
["Sky"] = 28; | |
["SlidingBallConstraint"] = 89; | |
["Smoke"] = 59; | |
["Snap"] = 34; | |
["Sound"] = 11; | |
["SoundService"] = 31; | |
["Sparkles"] = 42; | |
["SpawnLocation"] = 25; | |
["SpecialMesh"] = 8; | |
["SphereHandleAdornment"] = 54; | |
["SpotLight"] = 13; | |
["SpringConstraint"] = 89; | |
["StarterCharacterScripts"] = 82; | |
["StarterGear"] = 20; | |
["StarterGui"] = 46; | |
["StarterPack"] = 20; | |
["StarterPlayer"] = 88; | |
["StarterPlayerScripts"] = 82; | |
["Status"] = 2; | |
["StringValue"] = 4; | |
["SunRaysEffect"] = 90; | |
["SurfaceGui"] = 64; | |
["SurfaceLight"] = 13; | |
["SurfaceSelection"] = 55; | |
["Team"] = 24; | |
["Teams"] = 23; | |
["TeleportService"] = 81; | |
["Terrain"] = 65; | |
["TerrainRegion"] = 65; | |
["TestService"] = 68; | |
["TextBox"] = 51; | |
["TextButton"] = 51; | |
["TextLabel"] = 50; | |
["Texture"] = 10; | |
["TextureTrail"] = 4; | |
["Tool"] = 17; | |
["TouchTransmitter"] = 37; | |
["TrussPart"] = 1; | |
["UnionOperation"] = 77; | |
["UserInputService"] = 84; | |
["Vector3Value"] = 4; | |
["VehicleSeat"] = 35; | |
["VelocityMotor"] = 34; | |
["WedgePart"] = 1; | |
["Weld"] = 34; | |
["Workspace"] = 19; | |
} | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
function Create(ty,data) | |
local obj | |
if type(ty) == 'string' then | |
obj = Instance.new(ty) | |
else | |
obj = ty | |
end | |
for k, v in pairs(data) do | |
if type(k) == 'number' then | |
v.Parent = obj | |
else | |
obj[k] = v | |
end | |
end | |
return obj | |
end | |
local barActive = false | |
local activeOptions = {} | |
function createDDown(dBut, callback,...) | |
if barActive then | |
for i,v in pairs(activeOptions) do | |
v:Destroy() | |
end | |
activeOptions = {} | |
barActive = false | |
return | |
else | |
barActive = true | |
end | |
local slots = {...} | |
local base = dBut | |
for i,v in pairs(slots) do | |
local newOption = base:Clone() | |
newOption.ZIndex = 5 | |
newOption.Name = "Option "..tostring(i) | |
newOption.Parent = base.Parent.Parent.Parent | |
newOption.BackgroundTransparency = 0 | |
newOption.ZIndex = 2 | |
table.insert(activeOptions,newOption) | |
newOption.Position = UDim2.new(-0.4, dBut.Position.X.Offset, dBut.Position.Y.Scale, dBut.Position.Y.Offset + (#activeOptions * dBut.Size.Y.Offset)) | |
newOption.Text = slots[i] | |
newOption.MouseButton1Down:connect(function() | |
dBut.Text = slots[i] | |
callback(slots[i]) | |
for i,v in pairs(activeOptions) do | |
v:Destroy() | |
end | |
activeOptions = {} | |
barActive = false | |
end) | |
end | |
end | |
-- Connects a function to an event such that it fires asynchronously | |
function Connect(event,func) | |
return event:connect(function(...) | |
local a = {...} | |
spawn(function() func(unpack(a)) end) | |
end) | |
end | |
-- returns the ascendant ScreenGui of an object | |
function GetScreen(screen) | |
if screen == nil then return nil end | |
while not screen:IsA("ScreenGui") do | |
screen = screen.Parent | |
if screen == nil then return nil end | |
end | |
return screen | |
end | |
do | |
local ZIndexLock = {} | |
-- Sets the ZIndex of an object and its descendants. Objects are locked so | |
-- that SetZIndexOnChanged doesn't spawn multiple threads that set the | |
-- ZIndex of the same object. | |
function SetZIndex(object,z) | |
if not ZIndexLock[object] then | |
ZIndexLock[object] = true | |
if object:IsA'GuiObject' then | |
object.ZIndex = z | |
end | |
local children = object:GetChildren() | |
for i = 1,#children do | |
SetZIndex(children[i],z) | |
end | |
ZIndexLock[object] = nil | |
end | |
end | |
function SetZIndexOnChanged(object) | |
return object.Changed:connect(function(p) | |
if p == "ZIndex" then | |
SetZIndex(object,object.ZIndex) | |
end | |
end) | |
end | |
end | |
---- IconMap ---- | |
-- Image size: 256px x 256px | |
-- Icon size: 16px x 16px | |
-- Padding between each icon: 2px | |
-- Padding around image edge: 1px | |
-- Total icons: 14 x 14 (196) | |
local Icon do | |
local iconMap = 'http://www.roblox.com/asset/?id=' .. MAP_ID | |
game:GetService('ContentProvider'):Preload(iconMap) | |
local iconDehash do | |
-- 14 x 14, 0-based input, 0-based output | |
local f=math.floor | |
function iconDehash(h) | |
return f(h/14%14),f(h%14) | |
end | |
end | |
function Icon(IconFrame,index) | |
local row,col = iconDehash(index) | |
local mapSize = Vector2.new(256,256) | |
local pad,border = 2,1 | |
local iconSize = 16 | |
local class = 'Frame' | |
if type(IconFrame) == 'string' then | |
class = IconFrame | |
IconFrame = nil | |
end | |
if not IconFrame then | |
IconFrame = Create(class,{ | |
Name = "Icon"; | |
BackgroundTransparency = 1; | |
ClipsDescendants = true; | |
Create('ImageLabel',{ | |
Name = "IconMap"; | |
Active = false; | |
BackgroundTransparency = 1; | |
Image = iconMap; | |
Size = UDim2.new(mapSize.x/iconSize,0,mapSize.y/iconSize,0); | |
}); | |
}) | |
end | |
IconFrame.IconMap.Position = UDim2.new(-col - (pad*(col+1) + border)/iconSize,0,-row - (pad*(row+1) + border)/iconSize,0) | |
return IconFrame | |
end | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- ScrollBar | |
do | |
-- AutoButtonColor doesn't always reset properly | |
local function ResetButtonColor(button) | |
local active = button.Active | |
button.Active = not active | |
button.Active = active | |
end | |
local function ArrowGraphic(size,dir,scaled,template) | |
local Frame = Create('Frame',{ | |
Name = "Arrow Graphic"; | |
BorderSizePixel = 0; | |
Size = UDim2.new(0,size,0,size); | |
Transparency = 1; | |
}) | |
if not template then | |
template = Instance.new("Frame") | |
template.BorderSizePixel = 0 | |
end | |
template.BackgroundColor3 = Color3.new(1, 1, 1); | |
local transform | |
if dir == nil or dir == 'Up' then | |
function transform(p,s) return p,s end | |
elseif dir == 'Down' then | |
function transform(p,s) return UDim2.new(0,p.X.Offset,0,size-p.Y.Offset-1),s end | |
elseif dir == 'Left' then | |
function transform(p,s) return UDim2.new(0,p.Y.Offset,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end | |
elseif dir == 'Right' then | |
function transform(p,s) return UDim2.new(0,size-p.Y.Offset-1,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end | |
end | |
local scale | |
if scaled then | |
function scale(p,s) return UDim2.new(p.X.Offset/size,0,p.Y.Offset/size,0),UDim2.new(s.X.Offset/size,0,s.Y.Offset/size,0) end | |
else | |
function scale(p,s) return p,s end | |
end | |
local o = math.floor(size/4) | |
if size%2 == 0 then | |
local n = size/2-1 | |
for i = 0,n do | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,n-i,0,o+i), | |
UDim2.new(0,(i+1)*2,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
else | |
local n = (size-1)/2 | |
for i = 0,n do | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,n-i,0,o+i), | |
UDim2.new(0,i*2+1,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
end | |
if size%4 > 1 then | |
local t = template:Clone() | |
local p,s = scale(transform( | |
UDim2.new(0,0,0,size-o-1), | |
UDim2.new(0,size,0,1) | |
)) | |
t.Position = p | |
t.Size = s | |
t.Parent = Frame | |
end | |
for i,v in pairs(Frame:GetChildren()) do | |
v.BackgroundColor3 = Color3.new(1, 1, 1); | |
end | |
return Frame | |
end | |
local function GripGraphic(size,dir,spacing,scaled,template) | |
local Frame = Create('Frame',{ | |
Name = "Grip Graphic"; | |
BorderSizePixel = 0; | |
Size = UDim2.new(0,size.x,0,size.y); | |
Transparency = 1; | |
}) | |
if not template then | |
template = Instance.new("Frame") | |
template.BorderSizePixel = 0 | |
end | |
spacing = spacing or 2 | |
local scale | |
if scaled then | |
function scale(p) return UDim2.new(p.X.Offset/size.x,0,p.Y.Offset/size.y,0) end | |
else | |
function scale(p) return p end | |
end | |
if dir == 'Vertical' then | |
for i=0,size.x-1,spacing do | |
local t = template:Clone() | |
t.Size = scale(UDim2.new(0,1,0,size.y)) | |
t.Position = scale(UDim2.new(0,i,0,0)) | |
t.Parent = Frame | |
end | |
elseif dir == nil or dir == 'Horizontal' then | |
for i=0,size.y-1,spacing do | |
local t = template:Clone() | |
t.Size = scale(UDim2.new(0,size.x,0,1)) | |
t.Position = scale(UDim2.new(0,0,0,i)) | |
t.Parent = Frame | |
end | |
end | |
return Frame | |
end | |
local mt = { | |
__index = { | |
GetScrollPercent = function(self) | |
return self.ScrollIndex/(self.TotalSpace-self.VisibleSpace) | |
end; | |
CanScrollDown = function(self) | |
return self.ScrollIndex + self.VisibleSpace < self.TotalSpace | |
end; | |
CanScrollUp = function(self) | |
return self.ScrollIndex > 0 | |
end; | |
ScrollDown = function(self) | |
self.ScrollIndex = self.ScrollIndex + self.PageIncrement | |
self:Update() | |
end; | |
ScrollUp = function(self) | |
self.ScrollIndex = self.ScrollIndex - self.PageIncrement | |
self:Update() | |
end; | |
ScrollTo = function(self,index) | |
self.ScrollIndex = index | |
self:Update() | |
end; | |
SetScrollPercent = function(self,percent) | |
self.ScrollIndex = math.floor((self.TotalSpace - self.VisibleSpace)*percent + 0.5) | |
self:Update() | |
end; | |
}; | |
} | |
mt.__index.CanScrollRight = mt.__index.CanScrollDown | |
mt.__index.CanScrollLeft = mt.__index.CanScrollUp | |
mt.__index.ScrollLeft = mt.__index.ScrollUp | |
mt.__index.ScrollRight = mt.__index.ScrollDown | |
function ScrollBar(horizontal) | |
-- create row scroll bar | |
local ScrollFrame = Create('Frame',{ | |
Name = "ScrollFrame"; | |
BorderSizePixel = 0; | |
Position = horizontal and UDim2.new(0,0,1,-GUI_SIZE) or UDim2.new(1,-GUI_SIZE,0,0); | |
Size = horizontal and UDim2.new(1,0,0,GUI_SIZE) or UDim2.new(0,GUI_SIZE,1,0); | |
BackgroundTransparency = 1; | |
Create('ImageButton',{ | |
Name = "ScrollDown"; | |
Position = horizontal and UDim2.new(1,-GUI_SIZE,0,0) or UDim2.new(0,0,1,-GUI_SIZE); | |
Size = UDim2.new(0, GUI_SIZE, 0, GUI_SIZE); | |
BackgroundColor3 = GuiColor.Button; | |
BorderColor3 = GuiColor.Border; | |
--BorderSizePixel = 0; | |
}); | |
Create('ImageButton',{ | |
Name = "ScrollUp"; | |
Size = UDim2.new(0, GUI_SIZE, 0, GUI_SIZE); | |
BackgroundColor3 = GuiColor.Button; | |
BorderColor3 = GuiColor.Border; | |
--BorderSizePixel = 0; | |
}); | |
Create('ImageButton',{ | |
Name = "ScrollBar"; | |
Size = horizontal and UDim2.new(1,-GUI_SIZE*2,1,0) or UDim2.new(1,0,1,-GUI_SIZE*2); | |
Position = horizontal and UDim2.new(0,GUI_SIZE,0,0) or UDim2.new(0,0,0,GUI_SIZE); | |
AutoButtonColor = false; | |
BackgroundColor3 = Color3.new(1/4, 1/4, 1/4); | |
BorderColor3 = GuiColor.Border; | |
--BorderSizePixel = 0; | |
Create('ImageButton',{ | |
Name = "ScrollThumb"; | |
AutoButtonColor = false; | |
Size = UDim2.new(0, GUI_SIZE, 0, GUI_SIZE); | |
BackgroundColor3 = GuiColor.Button; | |
BorderColor3 = GuiColor.Border; | |
--BorderSizePixel = 0; | |
}); | |
}); | |
}) | |
local graphicTemplate = Create('Frame',{ | |
Name="Graphic"; | |
BorderSizePixel = 0; | |
BackgroundColor3 = GuiColor.Border; | |
}) | |
local graphicSize = GUI_SIZE/2 | |
local ScrollDownFrame = ScrollFrame.ScrollDown | |
local ScrollDownGraphic = ArrowGraphic(graphicSize,horizontal and 'Right' or 'Down',true,graphicTemplate) | |
ScrollDownGraphic.Position = UDim2.new(0.5,-graphicSize/2,0.5,-graphicSize/2) | |
ScrollDownGraphic.Parent = ScrollDownFrame | |
local ScrollUpFrame = ScrollFrame.ScrollUp | |
local ScrollUpGraphic = ArrowGraphic(graphicSize,horizontal and 'Left' or 'Up',true,graphicTemplate) | |
ScrollUpGraphic.Position = UDim2.new(0.5,-graphicSize/2,0.5,-graphicSize/2) | |
ScrollUpGraphic.Parent = ScrollUpFrame | |
local ScrollBarFrame = ScrollFrame.ScrollBar | |
local ScrollThumbFrame = ScrollBarFrame.ScrollThumb | |
do | |
local size = GUI_SIZE*3/8 | |
local Decal = GripGraphic(Vector2.new(size,size),horizontal and 'Vertical' or 'Horizontal',2,graphicTemplate) | |
Decal.Position = UDim2.new(0.5,-size/2,0.5,-size/2) | |
Decal.Parent = ScrollThumbFrame | |
end | |
local Class = setmetatable({ | |
GUI = ScrollFrame; | |
ScrollIndex = 0; | |
VisibleSpace = 0; | |
TotalSpace = 0; | |
PageIncrement = 1; | |
},mt) | |
local UpdateScrollThumb | |
if horizontal then | |
function UpdateScrollThumb() | |
ScrollThumbFrame.Size = UDim2.new(Class.VisibleSpace/Class.TotalSpace,0,0,GUI_SIZE) | |
if ScrollThumbFrame.AbsoluteSize.x < GUI_SIZE then | |
ScrollThumbFrame.Size = UDim2.new(0,GUI_SIZE,0,GUI_SIZE) | |
end | |
local barSize = ScrollBarFrame.AbsoluteSize.x | |
ScrollThumbFrame.Position = UDim2.new(Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.x)/barSize,0,0,0) | |
end | |
else | |
function UpdateScrollThumb() | |
ScrollThumbFrame.Size = UDim2.new(0,GUI_SIZE,Class.VisibleSpace/Class.TotalSpace,0) | |
if ScrollThumbFrame.AbsoluteSize.y < GUI_SIZE then | |
ScrollThumbFrame.Size = UDim2.new(0,GUI_SIZE,0,GUI_SIZE) | |
end | |
local barSize = ScrollBarFrame.AbsoluteSize.y | |
ScrollThumbFrame.Position = UDim2.new(0,0,Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.y)/barSize,0) | |
end | |
end | |
local lastDown | |
local lastUp | |
local scrollStyle = {BackgroundColor3=Color3.new(1, 1, 1),BackgroundTransparency=0} | |
local scrollStyle_ds = {BackgroundColor3=Color3.new(1, 1, 1),BackgroundTransparency=0.7} | |
local function Update() | |
local t = Class.TotalSpace | |
local v = Class.VisibleSpace | |
local s = Class.ScrollIndex | |
if v <= t then | |
if s > 0 then | |
if s + v > t then | |
Class.ScrollIndex = t - v | |
end | |
else | |
Class.ScrollIndex = 0 | |
end | |
else | |
Class.ScrollIndex = 0 | |
end | |
if Class.UpdateCallback then | |
if Class.UpdateCallback(Class) == false then | |
return | |
end | |
end | |
local down = Class:CanScrollDown() | |
local up = Class:CanScrollUp() | |
if down ~= lastDown then | |
lastDown = down | |
ScrollDownFrame.Active = down | |
ScrollDownFrame.AutoButtonColor = down | |
local children = ScrollDownGraphic:GetChildren() | |
local style = down and scrollStyle or scrollStyle_ds | |
for i = 1,#children do | |
Create(children[i],style) | |
end | |
end | |
if up ~= lastUp then | |
lastUp = up | |
ScrollUpFrame.Active = up | |
ScrollUpFrame.AutoButtonColor = up | |
local children = ScrollUpGraphic:GetChildren() | |
local style = up and scrollStyle or scrollStyle_ds | |
for i = 1,#children do | |
Create(children[i],style) | |
end | |
end | |
ScrollThumbFrame.Visible = down or up | |
UpdateScrollThumb() | |
end | |
Class.Update = Update | |
SetZIndexOnChanged(ScrollFrame) | |
local MouseDrag = Create('ImageButton',{ | |
Name = "MouseDrag"; | |
Position = UDim2.new(-0.25,0,-0.25,0); | |
Size = UDim2.new(1.5,0,1.5,0); | |
Transparency = 1; | |
AutoButtonColor = false; | |
Active = true; | |
ZIndex = 10; | |
}) | |
local scrollEventID = 0 | |
ScrollDownFrame.MouseButton1Down:connect(function() | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollDownFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
Class:ScrollDown() | |
wait(0.2) -- delay before auto scroll | |
while scrollEventID == current do | |
Class:ScrollDown() | |
if not Class:CanScrollDown() then break end | |
wait() | |
end | |
end) | |
ScrollDownFrame.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
end) | |
ScrollUpFrame.MouseButton1Down:connect(function() | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
Class:ScrollUp() | |
wait(0.2) | |
while scrollEventID == current do | |
Class:ScrollUp() | |
if not Class:CanScrollUp() then break end | |
wait() | |
end | |
end) | |
ScrollUpFrame.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
end) | |
if horizontal then | |
ScrollBarFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
if x > ScrollThumbFrame.AbsolutePosition.x then | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if x < ScrollThumbFrame.AbsolutePosition.x + ScrollThumbFrame.AbsoluteSize.x then break end | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait() | |
end | |
else | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if x > ScrollThumbFrame.AbsolutePosition.x then break end | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait() | |
end | |
end | |
end) | |
else | |
ScrollBarFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local current = scrollEventID | |
local up_con | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollUpFrame) | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
if y > ScrollThumbFrame.AbsolutePosition.y then | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if y < ScrollThumbFrame.AbsolutePosition.y + ScrollThumbFrame.AbsoluteSize.y then break end | |
Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace) | |
wait() | |
end | |
else | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait(0.2) | |
while scrollEventID == current do | |
if y > ScrollThumbFrame.AbsolutePosition.y then break end | |
Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace) | |
wait() | |
end | |
end | |
end) | |
end | |
if horizontal then | |
ScrollThumbFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local mouse_offset = x - ScrollThumbFrame.AbsolutePosition.x | |
local drag_con | |
local up_con | |
drag_con = MouseDrag.MouseMoved:connect(function(x,y) | |
local bar_abs_pos = ScrollBarFrame.AbsolutePosition.x | |
local bar_drag = ScrollBarFrame.AbsoluteSize.x - ScrollThumbFrame.AbsoluteSize.x | |
local bar_abs_one = bar_abs_pos + bar_drag | |
x = x - mouse_offset | |
x = x < bar_abs_pos and bar_abs_pos or x > bar_abs_one and bar_abs_one or x | |
x = x - bar_abs_pos | |
Class:SetScrollPercent(x/(bar_drag)) | |
end) | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollThumbFrame) | |
drag_con:disconnect(); drag_con = nil | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
end) | |
else | |
ScrollThumbFrame.MouseButton1Down:connect(function(x,y) | |
scrollEventID = tick() | |
local mouse_offset = y - ScrollThumbFrame.AbsolutePosition.y | |
local drag_con | |
local up_con | |
drag_con = MouseDrag.MouseMoved:connect(function(x,y) | |
local bar_abs_pos = ScrollBarFrame.AbsolutePosition.y | |
local bar_drag = ScrollBarFrame.AbsoluteSize.y - ScrollThumbFrame.AbsoluteSize.y | |
local bar_abs_one = bar_abs_pos + bar_drag | |
y = y - mouse_offset | |
y = y < bar_abs_pos and bar_abs_pos or y > bar_abs_one and bar_abs_one or y | |
y = y - bar_abs_pos | |
Class:SetScrollPercent(y/(bar_drag)) | |
end) | |
up_con = MouseDrag.MouseButton1Up:connect(function() | |
scrollEventID = tick() | |
MouseDrag.Parent = nil | |
ResetButtonColor(ScrollThumbFrame) | |
drag_con:disconnect(); drag_con = nil | |
up_con:disconnect(); drag = nil | |
end) | |
MouseDrag.Parent = GetScreen(ScrollFrame) | |
end) | |
end | |
function Class:Destroy() | |
ScrollFrame:Destroy() | |
MouseDrag:Destroy() | |
for k in pairs(Class) do | |
Class[k] = nil | |
end | |
setmetatable(Class,nil) | |
end | |
Update() | |
return Class | |
end | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- Explorer panel | |
Create(explorerPanel,{ | |
BackgroundColor3 = GuiColor.Field; | |
BorderColor3 = GuiColor.Border; | |
Active = true; | |
}) | |
local SettingsRemote = explorerPanel.Parent:WaitForChild("SettingsPanel"):WaitForChild("GetSetting") | |
local GetApiRemote = explorerPanel.Parent:WaitForChild("PropertiesFrame"):WaitForChild("GetApi") | |
local GetAwaitRemote = explorerPanel.Parent:WaitForChild("PropertiesFrame"):WaitForChild("GetAwaiting") | |
local bindSetAwaiting = explorerPanel.Parent:WaitForChild("PropertiesFrame"):WaitForChild("SetAwaiting") | |
local SaveInstanceWindow = explorerPanel.Parent:WaitForChild("SaveInstance") | |
local ConfirmationWindow = explorerPanel.Parent:WaitForChild("Confirmation") | |
local CautionWindow = explorerPanel.Parent:WaitForChild("Caution") | |
local TableCautionWindow = explorerPanel.Parent:WaitForChild("TableCaution") | |
local RemoteWindow = explorerPanel.Parent:WaitForChild("CallRemote") | |
local ScriptEditor = explorerPanel.Parent:WaitForChild("ScriptEditor") | |
local ScriptEditorEvent = ScriptEditor:WaitForChild("OpenScript") | |
local CurrentSaveInstanceWindow | |
local CurrentRemoteWindow | |
local lastSelectedNode | |
local DexStorage | |
local DexStorageMain | |
local DexStorageEnabled | |
if saveinstance then DexStorageEnabled = true end | |
local _decompile = decompile; | |
function decompile(s, ...) | |
if SettingsRemote:Invoke'UseNewDecompiler' then | |
return _decompile(s, 'new'); | |
else | |
return _decompile(s, 'legacy'); | |
end | |
end | |
if DexStorageEnabled then | |
DexStorage = Instance.new("Folder") | |
DexStorage.Name = "Dex" | |
DexStorageMain = Instance.new("Folder",DexStorage) | |
DexStorageMain.Name = "DexStorage" | |
end | |
local RunningScriptsStorage | |
local RunningScriptsStorageMain | |
local RunningScriptsStorageEnabled | |
if getscripts then RunningScriptsStorageEnabled = true end | |
if RunningScriptsStorageEnabled then | |
RunningScriptsStorage = Instance.new("Folder") | |
RunningScriptsStorage.Name = "Dex Internal Storage" | |
RunningScriptsStorageMain = Instance.new("Folder", RunningScriptsStorage) | |
RunningScriptsStorageMain.Name = "Running Scripts" | |
end | |
local LoadedModulesStorage | |
local LoadedModulesStorageMain | |
local LoadedModulesStorageEnabled | |
if getloadedmodules then LoadedModulesStorageEnabled = true end | |
if LoadedModulesStorageEnabled then | |
LoadedModulesStorage = Instance.new("Folder") | |
LoadedModulesStorage.Name = "Dex Internal Storage" | |
LoadedModulesStorageMain = Instance.new("Folder", LoadedModulesStorage) | |
LoadedModulesStorageMain.Name = "Loaded Modules" | |
end | |
local NilStorage | |
local NilStorageMain | |
local NilStorageEnabled | |
if getnilinstances then NilStorageEnabled = true end | |
if NilStorageEnabled then | |
NilStorage = Instance.new("Folder") | |
NilStorage.Name = "Dex Internal Storage" | |
NilStorageMain = Instance.new("Folder",NilStorage) | |
NilStorageMain.Name = "Nil Instances" | |
end | |
local listFrame = Create('Frame',{ | |
Name = "List"; | |
BorderSizePixel = 0; | |
BackgroundTransparency = 1; | |
ClipsDescendants = true; | |
Position = UDim2.new(0,0,0,HEADER_SIZE); | |
Size = UDim2.new(1,-GUI_SIZE,1,-HEADER_SIZE); | |
Parent = explorerPanel; | |
}) | |
local scrollBar = ScrollBar(false) | |
scrollBar.PageIncrement = 1 | |
Create(scrollBar.GUI,{ | |
Position = UDim2.new(1,-GUI_SIZE,0,HEADER_SIZE); | |
Size = UDim2.new(0,GUI_SIZE,1,-HEADER_SIZE); | |
Parent = explorerPanel; | |
}) | |
local scrollBarH = ScrollBar(true) | |
scrollBarH.PageIncrement = GUI_SIZE | |
Create(scrollBarH.GUI,{ | |
Position = UDim2.new(0,0,1,-GUI_SIZE); | |
Size = UDim2.new(1,-GUI_SIZE,0,GUI_SIZE); | |
Visible = false; | |
Parent = explorerPanel; | |
}) | |
local headerFrame = Create('Frame',{ | |
Name = "Header"; | |
BorderSizePixel = 0; | |
BackgroundColor3 = GuiColor.Background; | |
BorderColor3 = GuiColor.Border; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,0,0,HEADER_SIZE); | |
Parent = explorerPanel; | |
Create('TextLabel',{ | |
Text = "Explorer"; | |
BackgroundTransparency = 1; | |
TextColor3 = GuiColor.Text; | |
TextXAlignment = 'Left'; | |
Font = FONT; | |
FontSize = FONT_SIZE; | |
Position = UDim2.new(0,4,0,0); | |
Size = UDim2.new(1,-4,0.5,0); | |
}); | |
}) | |
local explorerFilter = Create('TextBox',{ | |
Text = "Filter Workspace"; | |
BackgroundTransparency = 0.8; | |
TextColor3 = GuiColor.Text; | |
TextXAlignment = 'Left'; | |
Font = FONT; | |
FontSize = FONT_SIZE; | |
Position = UDim2.new(0,4,0.5,0); | |
Size = UDim2.new(1,-8,0.5,-2); | |
}); | |
explorerFilter.Parent = headerFrame | |
SetZIndexOnChanged(explorerPanel) | |
local function CreateColor3(r, g, b) return Color3.new(r/255,g/255,b/255) end | |
local Styles = { | |
Font = Enum.Font.Arial; | |
Margin = 5; | |
Black = CreateColor3(0,0,0); | |
Black2 = CreateColor3(24, 24, 24); | |
White = CreateColor3(244,244,244); | |
Hover = CreateColor3(2, 128, 144); | |
Hover2 = CreateColor3(5, 102, 141); | |
} | |
local Row = { | |
Font = Styles.Font; | |
FontSize = Enum.FontSize.Size14; | |
TextXAlignment = Enum.TextXAlignment.Left; | |
TextColor = Styles.White; | |
TextColorOver = Styles.White; | |
TextLockedColor = CreateColor3(155,155,155); | |
Height = 24; | |
BorderColor = CreateColor3(216/4,216/4,216/4); | |
BackgroundColor = Styles.Black2; | |
BackgroundColorAlternate = CreateColor3(32, 32, 32); | |
BackgroundColorMouseover = CreateColor3(40, 40, 40); | |
TitleMarginLeft = 15; | |
} | |
local DropDown = { | |
Font = Styles.Font; | |
FontSize = Enum.FontSize.Size14; | |
TextColor = CreateColor3(255,255,255); | |
TextColorOver = Styles.White; | |
TextXAlignment = Enum.TextXAlignment.Left; | |
Height = 20; | |
BackColor = Styles.Black2; | |
BackColorOver = Styles.Hover2; | |
BorderColor = CreateColor3(45,45,45); | |
BorderSizePixel = 2; | |
ArrowColor = CreateColor3(160/2,160/2,160/2); | |
ArrowColorOver = Styles.Hover; | |
} | |
local BrickColors = { | |
BoxSize = 13; | |
BorderSizePixel = 1; | |
BorderColor = CreateColor3(160/3,160/3,160/3); | |
FrameColor = CreateColor3(160/3,160/3,160/3); | |
Size = 20; | |
Padding = 4; | |
ColorsPerRow = 8; | |
OuterBorder = 1; | |
OuterBorderColor = Styles.Black; | |
} | |
local currentRightClickMenu | |
local CurrentInsertObjectWindow | |
local CurrentFunctionCallerWindow | |
local RbxApi | |
function ClassCanCreate(IName) | |
local success,err = pcall(function() Instance.new(IName) end) | |
if err then | |
return false | |
else | |
return true | |
end | |
end | |
function GetClasses() | |
if RbxApi == nil then return {} end | |
local classTable = {} | |
for i,v in pairs(RbxApi.Classes) do | |
if ClassCanCreate(v.Name) then | |
table.insert(classTable,v.Name) | |
end | |
end | |
return classTable | |
end | |
local function sortAlphabetic(t, property) | |
table.sort(t, | |
function(x,y) return x[property] < y[property] | |
end) | |
end | |
local function FunctionIsHidden(functionData) | |
local tags = functionData["tags"] | |
for _,name in pairs(tags) do | |
if name == "deprecated" | |
or name == "hidden" | |
or name == "writeonly" then | |
return true | |
end | |
end | |
return false | |
end | |
local function GetAllFunctions(className) | |
local class = RbxApi.Classes[className] | |
local functions = {} | |
if not class then return functions end | |
while class do | |
if class.Name == "Instance" then break end | |
for _,nextFunction in pairs(class.Functions) do | |
if not FunctionIsHidden(nextFunction) then | |
table.insert(functions, nextFunction) | |
end | |
end | |
class = RbxApi.Classes[class.Superclass] | |
end | |
sortAlphabetic(functions, "Name") | |
return functions | |
end | |
function GetFunctions() | |
if RbxApi == nil then return {} end | |
local List = SelectionVar():Get() | |
if #List == 0 then return end | |
local MyObject = List[1] | |
local functionTable = {} | |
for i,v in pairs(GetAllFunctions(MyObject.ClassName)) do | |
table.insert(functionTable,v) | |
end | |
return functionTable | |
end | |
function CreateInsertObjectMenu(choices, currentChoice, readOnly, onClick) | |
local mouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local totalSize = explorerPanel.Parent.AbsoluteSize.y | |
if #choices == 0 then return end | |
table.sort(choices, function(a,b) return a < b end) | |
local frame = Instance.new("Frame") | |
frame.Name = "InsertObject" | |
frame.Size = UDim2.new(0, 200, 1, 0) | |
frame.BackgroundTransparency = 1 | |
frame.Active = true | |
local menu = nil | |
local arrow = nil | |
local expanded = false | |
local margin = DropDown.BorderSizePixel; | |
--[[ | |
local button = Instance.new("TextButton") | |
button.Font = Row.Font | |
button.FontSize = Row.FontSize | |
button.TextXAlignment = Row.TextXAlignment | |
button.BackgroundTransparency = 1 | |
button.TextColor3 = Row.TextColor | |
if readOnly then | |
button.TextColor3 = Row.TextLockedColor | |
end | |
button.Text = currentChoice | |
button.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0) | |
button.Position = UDim2.new(0, Styles.Margin, 0, 0) | |
button.Parent = frame | |
--]] | |
local function hideMenu() | |
expanded = false | |
--showArrow(DropDown.ArrowColor) | |
if frame then | |
--frame:Destroy() | |
CurrentInsertObjectWindow.Visible = false | |
end | |
end | |
local function showMenu() | |
expanded = true | |
menu = Instance.new("ScrollingFrame") | |
menu.Size = UDim2.new(0,200,1,0) | |
menu.CanvasSize = UDim2.new(0, 200, 0, #choices * DropDown.Height) | |
menu.Position = UDim2.new(0, margin, 0, 0) | |
menu.BackgroundTransparency = 0 | |
menu.BackgroundColor3 = DropDown.BackColor | |
menu.BorderColor3 = DropDown.BorderColor | |
menu.BorderSizePixel = DropDown.BorderSizePixel | |
menu.TopImage = "rbxasset://textures/blackBkg_square.png" | |
menu.MidImage = "rbxasset://textures/blackBkg_square.png" | |
menu.BottomImage = "rbxasset://textures/blackBkg_square.png" | |
menu.Active = true | |
menu.ZIndex = 5 | |
menu.Parent = frame | |
--local parentFrameHeight = script.Parent.List.Size.Y.Offset | |
--local rowHeight = mouse.Y | |
--if (rowHeight + menu.Size.Y.Offset) > parentFrameHeight then | |
-- menu.Position = UDim2.new(0, margin, 0, -1 * (#choices * DropDown.Height) - margin) | |
--end | |
local function choice(name) | |
onClick(name) | |
hideMenu() | |
end | |
for i,name in pairs(choices) do | |
local option = CreateRightClickMenuItem(name, function() | |
choice(name) | |
end,1) | |
option.Size = UDim2.new(1, 0, 0, 20) | |
option.Position = UDim2.new(0, 0, 0, (i - 1) * DropDown.Height) | |
option.ZIndex = menu.ZIndex | |
option.Parent = menu | |
end | |
end | |
showMenu() | |
return frame | |
end | |
function CreateFunctionCallerMenu(choices, currentChoice, readOnly, onClick) | |
local mouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local totalSize = explorerPanel.Parent.AbsoluteSize.y | |
if #choices == 0 then return end | |
table.sort(choices, function(a,b) return a.Name < b.Name end) | |
local frame = Instance.new("Frame") | |
frame.Name = "InsertObject" | |
frame.Size = UDim2.new(0, 200, 1, 0) | |
frame.BackgroundTransparency = 1 | |
frame.Active = true | |
local menu = nil | |
local arrow = nil | |
local expanded = false | |
local margin = DropDown.BorderSizePixel; | |
local function hideMenu() | |
expanded = false | |
--showArrow(DropDown.ArrowColor) | |
if frame then | |
--frame:Destroy() | |
CurrentInsertObjectWindow.Visible = false | |
end | |
end | |
local function showMenu() | |
expanded = true | |
menu = Instance.new("ScrollingFrame") | |
menu.Size = UDim2.new(0,300,1,0) | |
menu.CanvasSize = UDim2.new(0, 300, 0, #choices * DropDown.Height) | |
menu.Position = UDim2.new(0, margin, 0, 0) | |
menu.BackgroundTransparency = 0 | |
menu.BackgroundColor3 = DropDown.BackColor | |
menu.BorderColor3 = DropDown.BorderColor | |
menu.BorderSizePixel = DropDown.BorderSizePixel | |
menu.TopImage = "rbxasset://textures/blackBkg_square.png" | |
menu.MidImage = "rbxasset://textures/blackBkg_square.png" | |
menu.BottomImage = "rbxasset://textures/blackBkg_square.png" | |
menu.Active = true | |
menu.ZIndex = 5 | |
menu.Parent = frame | |
--local parentFrameHeight = script.Parent.List.Size.Y.Offset | |
--local rowHeight = mouse.Y | |
--if (rowHeight + menu.Size.Y.Offset) > parentFrameHeight then | |
-- menu.Position = UDim2.new(0, margin, 0, -1 * (#choices * DropDown.Height) - margin) | |
--end | |
local function GetParameters(functionData) | |
local paraString = "" | |
paraString = paraString.."(" | |
for i,v in pairs(functionData.Arguments) do | |
paraString = paraString..v.Type.." "..v.Name | |
if i < #functionData.Arguments then | |
paraString = paraString..", " | |
end | |
end | |
paraString = paraString..")" | |
return paraString | |
end | |
local function choice(name) | |
onClick(name) | |
hideMenu() | |
end | |
for i,name in pairs(choices) do | |
local option = CreateRightClickMenuItem(name.ReturnType.." "..name.Name..GetParameters(name), function() | |
choice(name) | |
end,2) | |
option.Size = UDim2.new(1, 0, 0, 20) | |
option.Position = UDim2.new(0, 0, 0, (i - 1) * DropDown.Height) | |
option.ZIndex = menu.ZIndex | |
option.Parent = menu | |
end | |
end | |
showMenu() | |
return frame | |
end | |
function CreateInsertObject() | |
if not CurrentInsertObjectWindow then return end | |
CurrentInsertObjectWindow.Visible = true | |
if currentRightClickMenu and CurrentInsertObjectWindow.Visible then | |
CurrentInsertObjectWindow.Position = UDim2.new(0,currentRightClickMenu.Position.X.Offset-currentRightClickMenu.Size.X.Offset-2,0,0) | |
end | |
if CurrentInsertObjectWindow.Visible then | |
CurrentInsertObjectWindow.Parent = explorerPanel.Parent | |
end | |
end | |
function CreateFunctionCaller(oh) | |
if CurrentFunctionCallerWindow then | |
CurrentFunctionCallerWindow:Destroy() | |
CurrentFunctionCallerWindow = nil | |
end | |
CurrentFunctionCallerWindow = CreateFunctionCallerMenu( | |
GetFunctions(), | |
"", | |
false, | |
function(option) | |
CurrentFunctionCallerWindow:Destroy() | |
CurrentFunctionCallerWindow = nil | |
local list = SelectionVar():Get() | |
for i,v in pairs(list) do | |
pcall(function() print("Function called.", pcall(function() v[option.Name](v) end)) end) | |
end | |
DestroyRightClick() | |
end | |
) | |
if currentRightClickMenu and CurrentFunctionCallerWindow then | |
CurrentFunctionCallerWindow.Position = UDim2.new(0,currentRightClickMenu.Position.X.Offset-currentRightClickMenu.Size.X.Offset*1.5-2,0,0) | |
end | |
if CurrentFunctionCallerWindow then | |
CurrentFunctionCallerWindow.Parent = explorerPanel.Parent | |
end | |
end | |
function CreateRightClickMenuItem(text, onClick, insObj) | |
local button = Instance.new("TextButton") | |
button.Font = DropDown.Font | |
button.FontSize = DropDown.FontSize | |
button.TextColor3 = DropDown.TextColor | |
button.TextXAlignment = DropDown.TextXAlignment | |
button.BackgroundColor3 = DropDown.BackColor | |
button.AutoButtonColor = false | |
button.BorderSizePixel = 0 | |
button.Active = true | |
button.Text = text | |
if insObj == 1 then | |
local newIcon = Icon(nil,ExplorerIndex[text] or 0) | |
newIcon.Position = UDim2.new(0,0,0,2) | |
newIcon.Size = UDim2.new(0,16,0,16) | |
newIcon.IconMap.ZIndex = 5 | |
newIcon.Parent = button | |
button.Text = " "..button.Text | |
elseif insObj == 2 then | |
button.FontSize = Enum.FontSize.Size11 | |
end | |
button.MouseEnter:connect(function() | |
button.TextColor3 = DropDown.TextColorOver | |
button.BackgroundColor3 = DropDown.BackColorOver | |
if not insObj and CurrentInsertObjectWindow then | |
if CurrentInsertObjectWindow.Visible == false and button.Text == "Insert Object" then | |
CreateInsertObject() | |
elseif CurrentInsertObjectWindow.Visible and button.Text ~= "Insert Object" then | |
CurrentInsertObjectWindow.Visible = false | |
end | |
end | |
if not insObj then | |
if CurrentFunctionCallerWindow and button.Text ~= "Call Function" then | |
CurrentFunctionCallerWindow:Destroy() | |
CurrentFunctionCallerWindow = nil | |
elseif button.Text == "Call Function" then | |
CreateFunctionCaller() | |
end | |
end | |
end) | |
button.MouseLeave:connect(function() | |
button.TextColor3 = DropDown.TextColor | |
button.BackgroundColor3 = DropDown.BackColor | |
end) | |
button.MouseButton1Click:connect(function() | |
button.TextColor3 = DropDown.TextColor | |
button.BackgroundColor3 = DropDown.BackColor | |
onClick(text) | |
end) | |
return button | |
end | |
function CreateRightClickMenu(choices, currentChoice, readOnly, onClick) | |
local mouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local frame = Instance.new("Frame") | |
frame.Name = "DropDown" | |
frame.Size = UDim2.new(0, 200, 1, 0) | |
frame.BackgroundTransparency = 1 | |
frame.Active = true | |
local menu = nil | |
local arrow = nil | |
local expanded = false | |
local margin = DropDown.BorderSizePixel; | |
--[[ | |
local button = Instance.new("TextButton") | |
button.Font = Row.Font | |
button.FontSize = Row.FontSize | |
button.TextXAlignment = Row.TextXAlignment | |
button.BackgroundTransparency = 1 | |
button.TextColor3 = Row.TextColor | |
if readOnly then | |
button.TextColor3 = Row.TextLockedColor | |
end | |
button.Text = currentChoice | |
button.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0) | |
button.Position = UDim2.new(0, Styles.Margin, 0, 0) | |
button.Parent = frame | |
--]] | |
local function hideMenu() | |
expanded = false | |
--showArrow(DropDown.ArrowColor) | |
if frame then | |
frame:Destroy() | |
DestroyRightClick() | |
end | |
end | |
local function showMenu() | |
expanded = true | |
menu = Instance.new("Frame") | |
menu.Size = UDim2.new(0, 200, 0, #choices * DropDown.Height) | |
menu.Position = UDim2.new(0, margin, 0, 5) | |
menu.BackgroundTransparency = 0 | |
menu.BackgroundColor3 = DropDown.BackColor | |
menu.BorderColor3 = DropDown.BorderColor | |
menu.BorderSizePixel = DropDown.BorderSizePixel | |
menu.Active = true | |
menu.ZIndex = 5 | |
menu.Parent = frame | |
--local parentFrameHeight = script.Parent.List.Size.Y.Offset | |
--local rowHeight = mouse.Y | |
--if (rowHeight + menu.Size.Y.Offset) > parentFrameHeight then | |
-- menu.Position = UDim2.new(0, margin, 0, -1 * (#choices * DropDown.Height) - margin) | |
--end | |
local function choice(name) | |
onClick(name) | |
hideMenu() | |
end | |
for i,name in pairs(choices) do | |
local option = CreateRightClickMenuItem(name, function() | |
choice(name) | |
end) | |
option.Size = UDim2.new(1, 0, 0, 20) | |
option.Position = UDim2.new(0, 0, 0, (i - 1) * DropDown.Height) | |
option.ZIndex = menu.ZIndex | |
option.Parent = menu | |
end | |
end | |
showMenu() | |
return frame | |
end | |
function checkMouseInGui(gui) | |
if gui == nil then return false end | |
local plrMouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local guiPosition = gui.AbsolutePosition | |
local guiSize = gui.AbsoluteSize | |
if plrMouse.X >= guiPosition.x and plrMouse.X <= guiPosition.x + guiSize.x and plrMouse.Y >= guiPosition.y and plrMouse.Y <= guiPosition.y + guiSize.y then | |
return true | |
else | |
return false | |
end | |
end | |
local clipboard = {} | |
local function delete(o) | |
o.Parent = nil | |
end | |
local getTextWidth do | |
local text = Create('TextLabel',{ | |
Name = "TextWidth"; | |
TextXAlignment = 'Left'; | |
TextYAlignment = 'Center'; | |
Font = FONT; | |
FontSize = FONT_SIZE; | |
Text = ""; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,0,1,0); | |
Visible = false; | |
Parent = explorerPanel; | |
}) | |
function getTextWidth(s) | |
text.Text = s | |
return text.TextBounds.x | |
end | |
end | |
local nameScanned = false | |
-- Holds the game tree converted to a list. | |
local TreeList = {} | |
-- Matches objects to their tree node representation. | |
local NodeLookup = {} | |
local nodeWidth = 0 | |
local QuickButtons = {} | |
function filteringWorkspace() | |
if explorerFilter.Text ~= "" and explorerFilter.Text ~= "Filter Workspace" then | |
return true | |
end | |
return false | |
end | |
function lookForAName(obj,name) | |
for i,v in pairs(obj:GetChildren()) do | |
if string.find(string.lower(v.Name),string.lower(name)) then nameScanned = true end | |
lookForAName(v,name) | |
end | |
end | |
function scanName(obj) | |
nameScanned = false | |
if string.find(string.lower(obj.Name),string.lower(explorerFilter.Text)) then | |
nameScanned = true | |
else | |
lookForAName(obj,explorerFilter.Text) | |
end | |
return nameScanned | |
end | |
function updateActions() | |
for i,v in pairs(QuickButtons) do | |
if v.Cond() then | |
v.Toggle(true) | |
else | |
v.Toggle(false) | |
end | |
end | |
end | |
local updateList,rawUpdateList,updateScroll,rawUpdateSize do | |
local function r(t) | |
for i = 1,#t do | |
if not filteringWorkspace() or scanName(t[i].Object) then | |
TreeList[#TreeList+1] = t[i] | |
local w = (t[i].Depth)*(2+ENTRY_PADDING+GUI_SIZE) + 2 + ENTRY_SIZE + 4 + getTextWidth(t[i].Object.Name) + 4 | |
if w > nodeWidth then | |
nodeWidth = w | |
end | |
if t[i].Expanded or filteringWorkspace() then | |
r(t[i]) | |
end | |
end | |
end | |
end | |
function rawUpdateSize() | |
scrollBarH.TotalSpace = nodeWidth | |
scrollBarH.VisibleSpace = listFrame.AbsoluteSize.x | |
scrollBarH:Update() | |
local visible = scrollBarH:CanScrollDown() or scrollBarH:CanScrollUp() | |
scrollBarH.GUI.Visible = visible | |
listFrame.Size = UDim2.new(1,-GUI_SIZE,1,-GUI_SIZE*(visible and 1 or 0) - HEADER_SIZE) | |
scrollBar.VisibleSpace = math.ceil(listFrame.AbsoluteSize.y/ENTRY_BOUND) | |
scrollBar.GUI.Size = UDim2.new(0,GUI_SIZE,1,-GUI_SIZE*(visible and 1 or 0) - HEADER_SIZE) | |
scrollBar.TotalSpace = #TreeList+1 | |
scrollBar:Update() | |
end | |
function rawUpdateList() | |
-- Clear then repopulate the entire list. It appears to be fast enough. | |
TreeList = {} | |
nodeWidth = 0 | |
r(NodeLookup[workspace.Parent]) | |
r(NodeLookup[DexOutput]) | |
if DexStorageEnabled then | |
r(NodeLookup[DexStorage]) | |
end | |
if NilStorageEnabled then | |
r(NodeLookup[NilStorage]) | |
end | |
if RunningScriptsStorageEnabled then | |
r(NodeLookup[RunningScriptsStorage]) | |
end | |
if LoadedModulesStorageEnabled then | |
r(NodeLookup[LoadedModulesStorage]) | |
end | |
rawUpdateSize() | |
updateActions() | |
end | |
-- Adding or removing large models will cause many updates to occur. We | |
-- can reduce the number of updates by creating a delay, then dropping any | |
-- updates that occur during the delay. | |
local updatingList = false | |
function updateList() | |
if updatingList or filteringWorkspace() then return end | |
updatingList = true | |
wait(1.5) | |
updatingList = false | |
rawUpdateList() | |
end | |
local updatingScroll = false | |
function updateScroll() | |
if updatingScroll then return end | |
updatingScroll = true | |
wait(1.5) | |
updatingScroll = false | |
scrollBar:Update() | |
end | |
end | |
local Selection do | |
local bindGetSelection = explorerPanel:FindFirstChild("GetSelection") | |
if not bindGetSelection then | |
bindGetSelection = Create('BindableFunction',{Name = "GetSelection"}) | |
bindGetSelection.Parent = explorerPanel | |
end | |
local bindSetSelection = explorerPanel:FindFirstChild("SetSelection") | |
if not bindSetSelection then | |
bindSetSelection = Create('BindableFunction',{Name = "SetSelection"}) | |
bindSetSelection.Parent = explorerPanel | |
end | |
local bindSelectionObjectChanged = explorerPanel:FindFirstChild("SelectionObjectChanged") | |
if not bindSelectionObjectChanged then | |
bindSelectionObjectChanged = Create('BindableEvent',{Name = "SelectionObjectChanged"}) | |
bindSelectionObjectChanged.Parent = explorerPanel | |
end | |
local SelectionList = {} | |
local SelectionSet = {} | |
local Updates = true | |
Selection = { | |
Selected = SelectionSet; | |
List = SelectionList; | |
} | |
local function addObject(object) | |
-- list update | |
local lupdate = false | |
-- scroll update | |
local supdate = false | |
if not SelectionSet[object] then | |
local node = NodeLookup[object] | |
if node then | |
table.insert(SelectionList,object) | |
SelectionSet[object] = true | |
node.Selected = true | |
-- expand all ancestors so that selected node becomes visible | |
node = node.Parent | |
while node do | |
if not node.Expanded then | |
node.Expanded = true | |
lupdate = true | |
end | |
node = node.Parent | |
end | |
supdate = true | |
end | |
end | |
return lupdate,supdate | |
end | |
function Selection:Set(objects) | |
local lupdate = false | |
local supdate = false | |
if #SelectionList > 0 then | |
for i = 1,#SelectionList do | |
local object = SelectionList[i] | |
local node = NodeLookup[object] | |
if node then | |
node.Selected = false | |
SelectionSet[object] = nil | |
end | |
end | |
SelectionList = {} | |
Selection.List = SelectionList | |
supdate = true | |
end | |
for i = 1,#objects do | |
local l,s = addObject(objects[i]) | |
lupdate = l or lupdate | |
supdate = s or supdate | |
end | |
if lupdate then | |
rawUpdateList() | |
supdate = true | |
elseif supdate then | |
scrollBar:Update() | |
end | |
if supdate then | |
bindSelectionObjectChanged:Fire() | |
updateActions() | |
end | |
end | |
function Selection:Add(object) | |
local l,s = addObject(object) | |
if l then | |
rawUpdateList() | |
if Updates then | |
bindSelectionObjectChanged:Fire() | |
updateActions() | |
end | |
elseif s then | |
scrollBar:Update() | |
if Updates then | |
bindSelectionObjectChanged:Fire() | |
updateActions() | |
end | |
end | |
end | |
function Selection:StopUpdates() | |
Updates = false | |
end | |
function Selection:ResumeUpdates() | |
Updates = true | |
bindSelectionObjectChanged:Fire() | |
updateActions() | |
end | |
function Selection:Remove(object,noupdate) | |
if SelectionSet[object] then | |
local node = NodeLookup[object] | |
if node then | |
node.Selected = false | |
SelectionSet[object] = nil | |
for i = 1,#SelectionList do | |
if SelectionList[i] == object then | |
table.remove(SelectionList,i) | |
break | |
end | |
end | |
if not noupdate then | |
scrollBar:Update() | |
end | |
bindSelectionObjectChanged:Fire() | |
updateActions() | |
end | |
end | |
end | |
function Selection:Get() | |
local list = {} | |
for i = 1,#SelectionList do | |
list[i] = SelectionList[i] | |
end | |
return list | |
end | |
bindSetSelection.OnInvoke = function(...) | |
Selection:Set(...) | |
end | |
bindGetSelection.OnInvoke = function() | |
return Selection:Get() | |
end | |
end | |
function CreateCaution(title,msg) | |
local newCaution = CautionWindow | |
newCaution.Visible = true | |
newCaution.Title.Text = title | |
newCaution.MainWindow.Desc.Text = msg | |
newCaution.MainWindow.Ok.MouseButton1Up:connect(function() | |
newCaution.Visible = false | |
end) | |
end | |
function CreateTableCaution(title,msg) | |
if type(msg) ~= "table" then return CreateCaution(title,tostring(msg)) end | |
local newCaution = TableCautionWindow:Clone() | |
newCaution.Title.Text = title | |
local TableList = newCaution.MainWindow.TableResults | |
local TableTemplate = newCaution.MainWindow.TableTemplate | |
for i,v in pairs(msg) do | |
local newResult = TableTemplate:Clone() | |
newResult.Type.Text = type(v) | |
newResult.Value.Text = tostring(v) | |
newResult.Position = UDim2.new(0,0,0,#TableList:GetChildren() * 20) | |
newResult.Parent = TableList | |
TableList.CanvasSize = UDim2.new(0,0,0,#TableList:GetChildren() * 20) | |
newResult.Visible = true | |
end | |
newCaution.Parent = explorerPanel.Parent | |
newCaution.Visible = true | |
newCaution.MainWindow.Ok.MouseButton1Up:connect(function() | |
newCaution:Destroy() | |
end) | |
end | |
local function Split(str, delimiter) | |
local start = 1 | |
local t = {} | |
while true do | |
local pos = string.find (str, delimiter, start, true) | |
if not pos then | |
break | |
end | |
table.insert (t, string.sub (str, start, pos - 1)) | |
start = pos + string.len (delimiter) | |
end | |
table.insert (t, string.sub (str, start)) | |
return t | |
end | |
local function ToValue(value,type) | |
if type == "Vector2" then | |
local list = Split(value,",") | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return Vector2.new(x,y) | |
elseif type == "Vector3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
local z = tonumber(list[3]) or 0 | |
return Vector3.new(x,y,z) | |
elseif type == "Color3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local r = tonumber(list[1]) or 0 | |
local g = tonumber(list[2]) or 0 | |
local b = tonumber(list[3]) or 0 | |
return Color3.new(r/255,g/255, b/255) | |
elseif type == "UDim2" then | |
local list = Split(string.gsub(string.gsub(value, "{", ""),"}",""),",") | |
if #list < 4 then return nil end | |
local xScale = tonumber(list[1]) or 0 | |
local xOffset = tonumber(list[2]) or 0 | |
local yScale = tonumber(list[3]) or 0 | |
local yOffset = tonumber(list[4]) or 0 | |
return UDim2.new(xScale, xOffset, yScale, yOffset) | |
elseif type == "Number" then | |
return tonumber(value) | |
elseif type == "String" then | |
return value | |
elseif type == "NumberRange" then | |
local list = Split(value,",") | |
if #list == 1 then | |
if tonumber(list[1]) == nil then return nil end | |
local newVal = tonumber(list[1]) or 0 | |
return NumberRange.new(newVal) | |
end | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return NumberRange.new(x,y) | |
elseif type == "Script" then | |
local success,err = ypcall(function() | |
_G.D_E_X_DONOTUSETHISPLEASE = nil | |
loadstring( | |
"_G.D_E_X_DONOTUSETHISPLEASE = "..value | |
)() | |
return _G.D_E_X_DONOTUSETHISPLEASE | |
end) | |
if err then | |
return nil | |
end | |
else | |
return nil | |
end | |
end | |
local function ToPropValue(value,type) | |
if type == "Vector2" then | |
local list = Split(value,",") | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return Vector2.new(x,y) | |
elseif type == "Vector3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
local z = tonumber(list[3]) or 0 | |
return Vector3.new(x,y,z) | |
elseif type == "Color3" then | |
local list = Split(value,",") | |
if #list < 3 then return nil end | |
local r = tonumber(list[1]) or 0 | |
local g = tonumber(list[2]) or 0 | |
local b = tonumber(list[3]) or 0 | |
return Color3.new(r/255,g/255, b/255) | |
elseif type == "UDim2" then | |
local list = Split(string.gsub(string.gsub(value, "{", ""),"}",""),",") | |
if #list < 4 then return nil end | |
local xScale = tonumber(list[1]) or 0 | |
local xOffset = tonumber(list[2]) or 0 | |
local yScale = tonumber(list[3]) or 0 | |
local yOffset = tonumber(list[4]) or 0 | |
return UDim2.new(xScale, xOffset, yScale, yOffset) | |
elseif type == "Content" then | |
return value | |
elseif type == "float" or type == "int" or type == "double" then | |
return tonumber(value) | |
elseif type == "string" then | |
return value | |
elseif type == "NumberRange" then | |
local list = Split(value,",") | |
if #list == 1 then | |
if tonumber(list[1]) == nil then return nil end | |
local newVal = tonumber(list[1]) or 0 | |
return NumberRange.new(newVal) | |
end | |
if #list < 2 then return nil end | |
local x = tonumber(list[1]) or 0 | |
local y = tonumber(list[2]) or 0 | |
return NumberRange.new(x,y) | |
elseif string.sub(value,1,4) == "Enum" then | |
local getEnum = value | |
while true do | |
local x,y = string.find(getEnum,".") | |
if y then | |
getEnum = string.sub(getEnum,y+1) | |
else | |
break | |
end | |
end | |
print(getEnum) | |
return getEnum | |
else | |
return nil | |
end | |
end | |
function PromptRemoteCaller(inst) | |
if CurrentRemoteWindow then | |
CurrentRemoteWindow:Destroy() | |
CurrentRemoteWindow = nil | |
end | |
CurrentRemoteWindow = RemoteWindow:Clone() | |
CurrentRemoteWindow.Parent = explorerPanel.Parent | |
CurrentRemoteWindow.Visible = true | |
local displayValues = false | |
local ArgumentList = CurrentRemoteWindow.MainWindow.Arguments | |
local ArgumentTemplate = CurrentRemoteWindow.MainWindow.ArgumentTemplate | |
if inst:IsA("RemoteEvent") then | |
CurrentRemoteWindow.Title.Text = "Fire Event" | |
CurrentRemoteWindow.MainWindow.Ok.Text = "Fire" | |
CurrentRemoteWindow.MainWindow.DisplayReturned.Visible = false | |
CurrentRemoteWindow.MainWindow.Desc2.Visible = false | |
end | |
local newArgument = ArgumentTemplate:Clone() | |
newArgument.Parent = ArgumentList | |
newArgument.Visible = true | |
newArgument.Type.MouseButton1Down:connect(function() | |
createDDown(newArgument.Type,function(choice) | |
newArgument.Type.Text = choice | |
end,"Script","Number","String","Color3","Vector3","Vector2","UDim2","NumberRange") | |
end) | |
CurrentRemoteWindow.MainWindow.Ok.MouseButton1Up:connect(function() | |
if CurrentRemoteWindow and inst.Parent ~= nil then | |
local MyArguments = {} | |
for i,v in pairs(ArgumentList:GetChildren()) do | |
table.insert(MyArguments,ToValue(v.Value.Text,v.Type.Text)) | |
end | |
if inst:IsA("RemoteFunction") then | |
if displayValues then | |
spawn(function() | |
local myResults = inst:InvokeServer(unpack(MyArguments)) | |
if myResults then | |
CreateTableCaution("Remote Caller",myResults) | |
else | |
CreateCaution("Remote Caller","This remote did not return anything.") | |
end | |
end) | |
else | |
spawn(function() | |
inst:InvokeServer(unpack(MyArguments)) | |
end) | |
end | |
else | |
inst:FireServer(unpack(MyArguments)) | |
end | |
CurrentRemoteWindow:Destroy() | |
CurrentRemoteWindow = nil | |
end | |
end) | |
CurrentRemoteWindow.MainWindow.Add.MouseButton1Up:connect(function() | |
if CurrentRemoteWindow then | |
local newArgument = ArgumentTemplate:Clone() | |
newArgument.Position = UDim2.new(0,0,0,#ArgumentList:GetChildren() * 20) | |
newArgument.Parent = ArgumentList | |
ArgumentList.CanvasSize = UDim2.new(0,0,0,#ArgumentList:GetChildren() * 20) | |
newArgument.Visible = true | |
newArgument.Type.MouseButton1Down:connect(function() | |
createDDown(newArgument.Type,function(choice) | |
newArgument.Type.Text = choice | |
end,"Script","Number","String","Color3","Vector3","Vector2","UDim2","NumberRange") | |
end) | |
end | |
end) | |
CurrentRemoteWindow.MainWindow.Subtract.MouseButton1Up:connect(function() | |
if CurrentRemoteWindow then | |
if #ArgumentList:GetChildren() > 1 then | |
ArgumentList:GetChildren()[#ArgumentList:GetChildren()]:Destroy() | |
ArgumentList.CanvasSize = UDim2.new(0,0,0,#ArgumentList:GetChildren() * 20) | |
end | |
end | |
end) | |
CurrentRemoteWindow.MainWindow.Cancel.MouseButton1Up:connect(function() | |
if CurrentRemoteWindow then | |
CurrentRemoteWindow:Destroy() | |
CurrentRemoteWindow = nil | |
end | |
end) | |
CurrentRemoteWindow.MainWindow.DisplayReturned.MouseButton1Up:connect(function() | |
if displayValues then | |
displayValues = false | |
CurrentRemoteWindow.MainWindow.DisplayReturned.enabled.Visible = false | |
else | |
displayValues = true | |
CurrentRemoteWindow.MainWindow.DisplayReturned.enabled.Visible = true | |
end | |
end) | |
end | |
function PromptSaveInstance(inst) | |
if not SaveInstance and not _G.SaveInstance then CreateCaution("SaveInstance Missing","You do not have the SaveInstance function installed. Please go to RaspberryPi's thread to retrieve it.") return end | |
if CurrentSaveInstanceWindow then | |
CurrentSaveInstanceWindow:Destroy() | |
CurrentSaveInstanceWindow = nil | |
if explorerPanel.Parent:FindFirstChild("SaveInstanceOverwriteCaution") then | |
explorerPanel.Parent.SaveInstanceOverwriteCaution:Destroy() | |
end | |
end | |
CurrentSaveInstanceWindow = SaveInstanceWindow:Clone() | |
CurrentSaveInstanceWindow.Parent = explorerPanel.Parent | |
CurrentSaveInstanceWindow.Visible = true | |
local filename = CurrentSaveInstanceWindow.MainWindow.FileName | |
local saveObjects = true | |
local overwriteCaution = false | |
CurrentSaveInstanceWindow.MainWindow.Save.MouseButton1Up:connect(function() | |
--[[if readfile and getelysianpath then | |
if readfile(getelysianpath()..filename.Text..".rbxmx") then | |
if not overwriteCaution then | |
overwriteCaution = true | |
local newCaution = ConfirmationWindow:Clone() | |
newCaution.Name = "SaveInstanceOverwriteCaution" | |
newCaution.MainWindow.Desc.Text = "The file, "..filename.Text..".rbxmx, already exists. Overwrite?" | |
newCaution.Parent = explorerPanel.Parent | |
newCaution.Visible = true | |
newCaution.MainWindow.Yes.MouseButton1Up:connect(function() | |
ypcall(function() | |
SaveInstance(inst,filename.Text..".rbxmx",not saveObjects) | |
end) | |
overwriteCaution = false | |
newCaution:Destroy() | |
if CurrentSaveInstanceWindow then | |
CurrentSaveInstanceWindow:Destroy() | |
CurrentSaveInstanceWindow = nil | |
end | |
end) | |
newCaution.MainWindow.No.MouseButton1Up:connect(function() | |
overwriteCaution = false | |
newCaution:Destroy() | |
end) | |
end | |
else | |
ypcall(function() | |
SaveInstance(inst,filename.Text..".rbxmx",not saveObjects) | |
end) | |
if CurrentSaveInstanceWindow then | |
CurrentSaveInstanceWindow:Destroy() | |
CurrentSaveInstanceWindow = nil | |
if explorerPanel.Parent:FindFirstChild("SaveInstanceOverwriteCaution") then | |
explorerPanel.Parent.SaveInstanceOverwriteCaution:Destroy() | |
end | |
end | |
end | |
else | |
ypcall(function() | |
if SaveInstance then | |
SaveInstance(inst,filename.Text..".rbxmx",not saveObjects) | |
else | |
_G.SaveInstance(inst,filename.Text,not saveObjects) | |
end | |
end) | |
if CurrentSaveInstanceWindow then | |
CurrentSaveInstanceWindow:Destroy() | |
CurrentSaveInstanceWindow = nil | |
if explorerPanel.Parent:FindFirstChild("SaveInstanceOverwriteCaution") then | |
explorerPanel.Parent.SaveInstanceOverwriteCaution:Destroy() | |
end | |
end | |
end]] | |
end) | |
CurrentSaveInstanceWindow.MainWindow.Cancel.MouseButton1Up:connect(function() | |
if CurrentSaveInstanceWindow then | |
CurrentSaveInstanceWindow:Destroy() | |
CurrentSaveInstanceWindow = nil | |
if explorerPanel.Parent:FindFirstChild("SaveInstanceOverwriteCaution") then | |
explorerPanel.Parent.SaveInstanceOverwriteCaution:Destroy() | |
end | |
end | |
end) | |
CurrentSaveInstanceWindow.MainWindow.SaveObjects.MouseButton1Up:connect(function() | |
if saveObjects then | |
saveObjects = false | |
CurrentSaveInstanceWindow.MainWindow.SaveObjects.enabled.Visible = false | |
else | |
saveObjects = true | |
CurrentSaveInstanceWindow.MainWindow.SaveObjects.enabled.Visible = true | |
end | |
end) | |
end | |
function DestroyRightClick() | |
if currentRightClickMenu then | |
currentRightClickMenu:Destroy() | |
currentRightClickMenu = nil | |
end | |
if CurrentInsertObjectWindow and CurrentInsertObjectWindow.Visible then | |
CurrentInsertObjectWindow.Visible = false | |
end | |
end | |
local tabChar = " " | |
local function getSmaller(a, b, notLast) | |
local aByte = a:byte() or -1 | |
local bByte = b:byte() or -1 | |
if aByte == bByte then | |
if notLast and #a == 1 and #b == 1 then | |
return -1 | |
elseif #b == 1 then | |
return false | |
elseif #a == 1 then | |
return true | |
else | |
return getSmaller(a:sub(2), b:sub(2), notLast) | |
end | |
else | |
return aByte < bByte | |
end | |
end | |
local function parseData(obj, numTabs, isKey, overflow, noTables, forceDict) | |
local objType = typeof(obj) | |
local objStr = tostring(obj) | |
if objType == "table" then | |
if noTables then | |
return objStr | |
end | |
local isCyclic = overflow[obj] | |
overflow[obj] = true | |
local out = {} | |
local nextIndex = 1 | |
local isDict = false | |
local hasTables = false | |
local data = {} | |
for key, val in next, obj do | |
if not hasTables and typeof(val) == "table" then | |
hasTables = true | |
end | |
if not isDict and key ~= nextIndex then | |
isDict = true | |
else | |
nextIndex = nextIndex + 1 | |
end | |
data[#data+1] = {key, val} | |
end | |
if isDict or hasTables or forceDict then | |
out[#out+1] = (isCyclic and "Cyclic " or "") .. "{" | |
table.sort(data, function(a, b) | |
local aType = typeof(a[2]) | |
local bType = typeof(b[2]) | |
if bType == "string" and aType ~= "string" then | |
return false | |
end | |
local res = getSmaller(aType, bType, true) | |
if res == -1 then | |
return getSmaller(tostring(a[1]), tostring(b[1])) | |
else | |
return res | |
end | |
end) | |
for i = 1, #data do | |
local arr = data[i] | |
local nowKey = arr[1] | |
local nowVal = arr[2] | |
local parseKey = parseData(nowKey, numTabs+1, true, overflow, isCyclic) | |
local parseVal = parseData(nowVal, numTabs+1, false, overflow, isCyclic) | |
if isDict then | |
local nowValType = typeof(nowVal) | |
local preStr = "" | |
local postStr = "" | |
if i > 1 and (nowValType == "table" or typeof(data[i-1][2]) ~= nowValType) then | |
preStr = "\n" | |
end | |
if i < #data and nowValType == "table" and typeof(data[i+1][2]) ~= "table" and typeof(data[i+1][2]) == nowValType then | |
postStr = "\n" | |
end | |
out[#out+1] = preStr .. string.rep(tabChar, numTabs+1) .. parseKey .. " = " .. parseVal .. ";" .. postStr | |
else | |
out[#out+1] = string.rep(tabChar, numTabs+1) .. parseVal .. ";" | |
end | |
end | |
out[#out+1] = string.rep(tabChar, numTabs) .. "}" | |
else | |
local data2 = {} | |
for i = 1, #data do | |
local arr = data[i] | |
local nowVal = arr[2] | |
local parseVal = parseData(nowVal, 0, false, overflow, isCyclic) | |
data2[#data2+1] = parseVal | |
end | |
out[#out+1] = "{" .. table.concat(data2, ", ") .. "}" | |
end | |
return table.concat(out, "\n") | |
else | |
local returnVal = nil | |
if (objType == "string" or objType == "Content") and (not isKey or tonumber(obj:sub(1, 1))) then | |
local retVal = '"' .. objStr .. '"' | |
if isKey then | |
retVal = "[" .. retVal .. "]" | |
end | |
returnVal = retVal | |
elseif objType == "EnumItem" then | |
returnVal = "Enum." .. tostring(obj.EnumType) .. "." .. obj.Name | |
elseif objType == "Enum" then | |
returnVal = "Enum." .. objStr | |
elseif objType == "Instance" then | |
returnVal = obj.Parent and obj:GetFullName() or obj.ClassName | |
elseif objType == "CFrame" then | |
returnVal = "CFrame.new(" .. objStr .. ")" | |
elseif objType == "Vector3" then | |
returnVal = "Vector3.new(" .. objStr .. ")" | |
elseif objType == "Vector2" then | |
returnVal = "Vector2.new(" .. objStr .. ")" | |
elseif objType == "UDim2" then | |
returnVal = "UDim2.new(" .. objStr:gsub("[{}]", "") .. ")" | |
elseif objType == "BrickColor" then | |
returnVal = "BrickColor.new(\"" .. objStr .. "\")" | |
elseif objType == "Color3" then | |
returnVal = "Color3.new(" .. objStr .. ")" | |
elseif objType == "NumberRange" then | |
returnVal = "NumberRange.new(" .. objStr:gsub("^%s*(.-)%s*$", "%1"):gsub(" ", ", ") .. ")" | |
elseif objType == "PhysicalProperties" then | |
returnVal = "PhysicalProperties.new(" .. objStr .. ")" | |
else | |
returnVal = objStr | |
end | |
return returnVal | |
end | |
end | |
function tableToString(t) | |
local success, result = pcall(function() | |
return parseData(t, 0, false, {}, nil, false) | |
end) | |
return success and result or 'error'; | |
end | |
local HasSpecial = function(string) | |
return (string:match("%c") or string:match("%s") or string:match("%p")) ~= nil | |
end | |
local GetPath = function(Instance) -- ripped from some random script | |
local Obj = Instance | |
local string = {} | |
local temp = {} | |
local error = false | |
while Obj ~= game do | |
if Obj == nil then | |
error = true | |
break | |
end | |
table.insert(temp, Obj.Parent == game and Obj.ClassName or tostring(Obj)) | |
Obj = Obj.Parent | |
end | |
table.insert(string, "game:GetService(\"" .. temp[#temp] .. "\")") | |
for i = #temp - 1, 1, -1 do | |
table.insert(string, HasSpecial(temp[i]) and "[\"" .. temp[i] .. "\"]" or "." .. temp[i]) | |
end | |
return (error and "nil -- Path contained an invalid instance" or table.concat(string, "")) | |
end | |
function rightClickMenu(sObj) | |
local mouse = game:GetService("Players").LocalPlayer:GetMouse() | |
local extra = ((sObj == RunningScriptsStorageMain or sObj == LoadedModulesStorageMain or sObj == NilStorageMain) and 'Refresh Instances' or nil) | |
currentRightClickMenu = CreateRightClickMenu( | |
{ | |
'Cut', | |
'Copy', | |
'Paste Into', | |
'Duplicate', | |
'Delete', | |
-- 'Group', | |
-- 'Ungroup', | |
'Select Children', | |
'Teleport To', | |
-- 'Insert Part', | |
'Insert Object', | |
'View Script', | |
'Save Script', | |
-- 'Save Instance', | |
'Copy Path', | |
'Call Function', | |
'Call Remote', | |
extra | |
}, | |
"", | |
false, | |
function(option) | |
if option == "Cut" then | |
if not Option.Modifiable then return end | |
clipboard = {} | |
local list = Selection.List | |
local cut = {} | |
for i = 1,#list do | |
local obj = list[i]:Clone() | |
if obj then | |
table.insert(clipboard,obj) | |
table.insert(cut,list[i]) | |
end | |
end | |
for i = 1,#cut do | |
pcall(delete,cut[i]) | |
end | |
updateActions() | |
elseif option == "Copy" then | |
if not Option.Modifiable then return end | |
clipboard = {} | |
local list = Selection.List | |
for i = 1,#list do | |
table.insert(clipboard,list[i]:Clone()) | |
end | |
updateActions() | |
elseif option == "Paste Into" then | |
if not Option.Modifiable then return end | |
local parent = Selection.List[1] or workspace | |
for i = 1,#clipboard do | |
clipboard[i]:Clone().Parent = parent | |
end | |
elseif option == "Duplicate" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
list[i]:Clone().Parent = Selection.List[1].Parent or workspace | |
end | |
elseif option == "Delete" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
pcall(delete,list[i]) | |
end | |
Selection:Set({}) | |
elseif option == "Group" then | |
if not Option.Modifiable then return end | |
local newModel = Instance.new("Model") | |
local list = Selection:Get() | |
newModel.Parent = Selection.List[1].Parent or workspace | |
for i = 1,#list do | |
list[i].Parent = newModel | |
end | |
Selection:Set({}) | |
elseif option == "Ungroup" then | |
if not Option.Modifiable then return end | |
local ungrouped = {} | |
local list = Selection:Get() | |
for i = 1,#list do | |
if list[i]:IsA("Model") then | |
for i2,v2 in pairs(list[i]:GetChildren()) do | |
v2.Parent = list[i].Parent or workspace | |
table.insert(ungrouped,v2) | |
end | |
pcall(delete,list[i]) | |
end | |
end | |
Selection:Set({}) | |
if SettingsRemote:Invoke("SelectUngrouped") then | |
for i,v in pairs(ungrouped) do | |
Selection:Add(v) | |
end | |
end | |
elseif option == "Select Children" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
Selection:Set({}) | |
Selection:StopUpdates() | |
for i = 1,#list do | |
for i2,v2 in pairs(list[i]:GetChildren()) do | |
Selection:Add(v2) | |
end | |
end | |
Selection:ResumeUpdates() | |
elseif option == "Teleport To" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
if list[i]:IsA("BasePart") then | |
pcall(function() | |
game:GetService("Players").LocalPlayer.Character.HumanoidRootPart.CFrame = list[i].CFrame * CFrame.new(0, 3, 0); | |
end) | |
break | |
end | |
end | |
elseif option == "Insert Part" then | |
if not Option.Modifiable then return end | |
local insertedParts = {} | |
local list = Selection:Get() | |
for i = 1,#list do | |
pcall(function() | |
local newPart = Instance.new("Part") | |
newPart.Parent = list[i] | |
newPart.CFrame = CFrame.new(game:GetService("Players").LocalPlayer.Character.Head.Position) + Vector3.new(0,3,0) | |
table.insert(insertedParts,newPart) | |
end) | |
end | |
elseif option == "Save Instance" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
if #list == 1 then | |
list[1].Archivable = true | |
ypcall(function()PromptSaveInstance(list[1]:Clone())end) | |
elseif #list > 1 then | |
local newModel = Instance.new("Model") | |
newModel.Name = "SavedInstances" | |
for i = 1,#list do | |
ypcall(function() | |
list[i].Archivable = true | |
list[i]:Clone().Parent = newModel | |
end) | |
end | |
PromptSaveInstance(newModel) | |
end | |
elseif option == 'Copy Path' then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
local paths = {}; | |
for i = 1,#list do | |
paths[#paths + 1] = GetPath(list[i]); | |
end | |
if #paths > 1 then | |
setclipboard(tableToString(paths)) | |
elseif #paths == 1 then | |
setclipboard(paths[1]) | |
end | |
elseif option == "Call Remote" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
if list[i]:IsA("RemoteFunction") or list[i]:IsA("RemoteEvent") then | |
PromptRemoteCaller(list[i]) | |
break | |
end | |
end | |
elseif option == "View Script" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
if list[i]:IsA("LocalScript") or list[i]:IsA("ModuleScript") then | |
ScriptEditorEvent:Fire(list[i]) | |
end | |
end | |
elseif option == "Save Script" then | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
if list[i]:IsA("LocalScript") or list[i]:IsA("ModuleScript") then | |
writefile(game.PlaceId .. '_' .. list[i].Name:gsub('%W', '') .. '_' .. math.random(100000, 999999) .. '.lua', decompile(list[i])); | |
end | |
end | |
elseif option == 'Refresh Instances' then | |
if sObj == NilStorageMain then | |
for i, v in pairs(getnilinstances()) do | |
if v ~= DexOutput and v ~= DexOutputMain and v ~= DexStorage and v ~= DexStorageMain and v ~= RunningScriptsStorage and v ~= RunningScriptsStorageMain and v ~= LoadedModulesStorage and v ~= LoadedModulesStorageMain and v ~= NilStorage and v ~= NilStorageMain then | |
pcall(function() | |
v:clone().Parent = NilStorageMain; | |
end) | |
end | |
end | |
elseif sObj == RunningScriptsStorageMain then | |
for i,v in pairs(getscripts()) do | |
if v ~= RunningScriptsStorage and v ~= LoadedModulesStorage and v ~= DexStorage and v ~= UpvalueStorage then | |
if (v:IsA'LocalScript' or v:IsA'ModuleScript' or v:IsA'Script') then | |
v.Archivable = true; | |
local ls = v:clone() | |
if v:IsA'LocalScript' or v:IsA'Script' then ls.Disabled = true; end | |
ls.Parent = RunningScriptsStorageMain | |
end | |
end | |
end | |
elseif sObj == LoadedModulesStorageMain then | |
for i,v in pairs(getloadedmodules()) do | |
if v ~= RunningScriptsStorage and v ~= LoadedModulesStorage and v ~= DexStorage and v ~= UpvalueStorage then | |
if (v:IsA'LocalScript' or v:IsA'ModuleScript' or v:IsA'Script') then | |
v.Archivable = true; | |
local ls = v:clone() | |
if v:IsA'LocalScript' or v:IsA'Script' then ls.Disabled = true; end | |
ls.Parent = LoadedModulesStorageMain | |
end | |
end | |
end | |
end | |
end | |
end) | |
currentRightClickMenu.Parent = explorerPanel.Parent | |
currentRightClickMenu.Position = UDim2.new(0,mouse.X,0,mouse.Y) | |
if currentRightClickMenu.AbsolutePosition.X + currentRightClickMenu.AbsoluteSize.X > explorerPanel.AbsolutePosition.X + explorerPanel.AbsoluteSize.X then | |
currentRightClickMenu.Position = UDim2.new(0, explorerPanel.AbsolutePosition.X + explorerPanel.AbsoluteSize.X - currentRightClickMenu.AbsoluteSize.X, 0, mouse.Y) | |
end | |
end | |
local function cancelReparentDrag()end | |
local function cancelSelectDrag()end | |
do | |
local listEntries = {} | |
local nameConnLookup = {} | |
local mouseDrag = Create('ImageButton',{ | |
Name = "MouseDrag"; | |
Position = UDim2.new(-0.25,0,-0.25,0); | |
Size = UDim2.new(1.5,0,1.5,0); | |
Transparency = 1; | |
AutoButtonColor = false; | |
Active = true; | |
ZIndex = 10; | |
}) | |
local function dragSelect(last,add,button) | |
local connDrag | |
local conUp | |
conDrag = mouseDrag.MouseMoved:connect(function(x,y) | |
local pos = Vector2.new(x,y) - listFrame.AbsolutePosition | |
local size = listFrame.AbsoluteSize | |
if pos.x < 0 or pos.x > size.x or pos.y < 0 or pos.y > size.y then return end | |
local i = math.ceil(pos.y/ENTRY_BOUND) + scrollBar.ScrollIndex | |
-- Mouse may have made a large step, so interpolate between the | |
-- last index and the current. | |
for n = i<last and i or last, i>last and i or last do | |
local node = TreeList[n] | |
if node then | |
if add then | |
Selection:Add(node.Object) | |
else | |
Selection:Remove(node.Object) | |
end | |
end | |
end | |
last = i | |
end) | |
function cancelSelectDrag() | |
mouseDrag.Parent = nil | |
conDrag:disconnect() | |
conUp:disconnect() | |
function cancelSelectDrag()end | |
end | |
conUp = mouseDrag[button]:connect(cancelSelectDrag) | |
mouseDrag.Parent = GetScreen(listFrame) | |
end | |
local function dragReparent(object,dragGhost,clickPos,ghostOffset) | |
local connDrag | |
local conUp | |
local conUp2 | |
local parentIndex = nil | |
local dragged = false | |
local parentHighlight = Create('Frame',{ | |
Transparency = 1; | |
Visible = false; | |
Create('Frame',{ | |
BorderSizePixel = 0; | |
BackgroundColor3 = Color3.new(0,0,0); | |
BackgroundTransparency = 0.1; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,0,0,1); | |
}); | |
Create('Frame',{ | |
BorderSizePixel = 0; | |
BackgroundColor3 = Color3.new(0,0,0); | |
BackgroundTransparency = 0.1; | |
Position = UDim2.new(1,0,0,0); | |
Size = UDim2.new(0,1,1,0); | |
}); | |
Create('Frame',{ | |
BorderSizePixel = 0; | |
BackgroundColor3 = Color3.new(0,0,0); | |
BackgroundTransparency = 0.1; | |
Position = UDim2.new(0,0,1,0); | |
Size = UDim2.new(1,0,0,1); | |
}); | |
Create('Frame',{ | |
BorderSizePixel = 0; | |
BackgroundColor3 = Color3.new(0,0,0); | |
BackgroundTransparency = 0.1; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(0,1,1,0); | |
}); | |
}) | |
SetZIndex(parentHighlight,9) | |
conDrag = mouseDrag.MouseMoved:connect(function(x,y) | |
local dragPos = Vector2.new(x,y) | |
if dragged then | |
local pos = dragPos - listFrame.AbsolutePosition | |
local size = listFrame.AbsoluteSize | |
parentIndex = nil | |
parentHighlight.Visible = false | |
if pos.x >= 0 and pos.x <= size.x and pos.y >= 0 and pos.y <= size.y + ENTRY_SIZE*2 then | |
local i = math.ceil(pos.y/ENTRY_BOUND-2) | |
local node = TreeList[i + scrollBar.ScrollIndex] | |
if node and node.Object ~= object and not object:IsAncestorOf(node.Object) then | |
parentIndex = i | |
local entry = listEntries[i] | |
if entry then | |
parentHighlight.Visible = true | |
parentHighlight.Position = UDim2.new(0,1,0,entry.AbsolutePosition.y-listFrame.AbsolutePosition.y) | |
parentHighlight.Size = UDim2.new(0,size.x-4,0,entry.AbsoluteSize.y) | |
end | |
end | |
end | |
dragGhost.Position = UDim2.new(0,dragPos.x+ghostOffset.x,0,dragPos.y+ghostOffset.y) | |
elseif (clickPos-dragPos).magnitude > 8 then | |
dragged = true | |
SetZIndex(dragGhost,9) | |
dragGhost.IndentFrame.Transparency = 0.25 | |
dragGhost.IndentFrame.EntryText.TextColor3 = GuiColor.TextSelected | |
dragGhost.Position = UDim2.new(0,dragPos.x+ghostOffset.x,0,dragPos.y+ghostOffset.y) | |
dragGhost.Parent = GetScreen(listFrame) | |
parentHighlight.Parent = listFrame | |
end | |
end) | |
function cancelReparentDrag() | |
mouseDrag.Parent = nil | |
conDrag:disconnect() | |
conUp:disconnect() | |
conUp2:disconnect() | |
dragGhost:Destroy() | |
parentHighlight:Destroy() | |
function cancelReparentDrag()end | |
end | |
local wasSelected = Selection.Selected[object] | |
if not wasSelected and Option.Selectable then | |
Selection:Set({object}) | |
end | |
conUp = mouseDrag.MouseButton1Up:connect(function() | |
cancelReparentDrag() | |
if dragged then | |
if parentIndex then | |
local parentNode = TreeList[parentIndex + scrollBar.ScrollIndex] | |
if parentNode then | |
parentNode.Expanded = true | |
local parentObj = parentNode.Object | |
local function parent(a,b) | |
a.Parent = b | |
end | |
if Option.Selectable then | |
local list = Selection.List | |
for i = 1,#list do | |
pcall(parent,list[i],parentObj) | |
end | |
else | |
pcall(parent,object,parentObj) | |
end | |
end | |
end | |
else | |
-- do selection click | |
if wasSelected and Option.Selectable then | |
Selection:Set({}) | |
end | |
end | |
end) | |
conUp2 = mouseDrag.MouseButton2Down:connect(function() | |
cancelReparentDrag() | |
end) | |
mouseDrag.Parent = GetScreen(listFrame) | |
end | |
local entryTemplate = Create('ImageButton',{ | |
Name = "Entry"; | |
Transparency = 1; | |
AutoButtonColor = false; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,0,0,ENTRY_SIZE); | |
Create('Frame',{ | |
Name = "IndentFrame"; | |
BackgroundTransparency = 1; | |
BackgroundColor3 = GuiColor.Selected; | |
BorderColor3 = GuiColor.BorderSelected; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,0,1,0); | |
Create(Icon('ImageButton',0),{ | |
Name = "Expand"; | |
AutoButtonColor = false; | |
Position = UDim2.new(0,-GUI_SIZE,0.5,-GUI_SIZE/2); | |
Size = UDim2.new(0,GUI_SIZE,0,GUI_SIZE); | |
}); | |
Create(Icon(nil,0),{ | |
Name = "ExplorerIcon"; | |
Position = UDim2.new(0,2+ENTRY_PADDING,0.5,-GUI_SIZE/2); | |
Size = UDim2.new(0,GUI_SIZE,0,GUI_SIZE); | |
}); | |
Create('TextLabel',{ | |
Name = "EntryText"; | |
BackgroundTransparency = 1; | |
TextColor3 = GuiColor.Text; | |
TextXAlignment = 'Left'; | |
TextYAlignment = 'Center'; | |
Font = FONT; | |
FontSize = FONT_SIZE; | |
Text = ""; | |
Position = UDim2.new(0,2+ENTRY_SIZE+4,0,0); | |
Size = UDim2.new(1,-2,1,0); | |
}); | |
}); | |
}) | |
function scrollBar.UpdateCallback(self) | |
for i = 1,self.VisibleSpace do | |
local node = TreeList[i + self.ScrollIndex] | |
if node then | |
local entry = listEntries[i] | |
if not entry then | |
entry = Create(entryTemplate:Clone(),{ | |
Position = UDim2.new(0,2,0,ENTRY_BOUND*(i-1)+2); | |
Size = UDim2.new(0,nodeWidth,0,ENTRY_SIZE); | |
ZIndex = listFrame.ZIndex; | |
}) | |
listEntries[i] = entry | |
local expand = entry.IndentFrame.Expand | |
expand.MouseEnter:connect(function() | |
local node = TreeList[i + self.ScrollIndex] | |
if #node > 0 then | |
if node.Expanded then | |
Icon(expand,NODE_EXPANDED_OVER) | |
else | |
Icon(expand,NODE_COLLAPSED_OVER) | |
end | |
end | |
end) | |
expand.MouseLeave:connect(function() | |
local node = TreeList[i + self.ScrollIndex] | |
if #node > 0 then | |
if node.Expanded then | |
Icon(expand,NODE_EXPANDED) | |
else | |
Icon(expand,NODE_COLLAPSED) | |
end | |
end | |
end) | |
expand.MouseButton1Down:connect(function() | |
local node = TreeList[i + self.ScrollIndex] | |
if #node > 0 then | |
node.Expanded = not node.Expanded | |
if node.Object == explorerPanel.Parent and node.Expanded then | |
CreateCaution("Warning","Please be careful when editing instances inside here, this is like the System32 of Dex and modifying objects here can break Dex.") | |
end | |
-- use raw update so the list updates instantly | |
rawUpdateList() | |
end | |
end) | |
entry.MouseButton1Down:connect(function(x,y) | |
local node = TreeList[i + self.ScrollIndex] | |
DestroyRightClick() | |
if GetAwaitRemote:Invoke() then | |
bindSetAwaiting:Fire(node.Object) | |
return | |
end | |
if not HoldingShift then | |
lastSelectedNode = i + self.ScrollIndex | |
end | |
if HoldingShift and not filteringWorkspace() then | |
if lastSelectedNode then | |
if i + self.ScrollIndex - lastSelectedNode > 0 then | |
Selection:StopUpdates() | |
for i2 = 1, i + self.ScrollIndex - lastSelectedNode do | |
local newNode = TreeList[lastSelectedNode + i2] | |
if newNode then | |
Selection:Add(newNode.Object) | |
end | |
end | |
Selection:ResumeUpdates() | |
else | |
Selection:StopUpdates() | |
for i2 = i + self.ScrollIndex - lastSelectedNode, 1 do | |
local newNode = TreeList[lastSelectedNode + i2] | |
if newNode then | |
Selection:Add(newNode.Object) | |
end | |
end | |
Selection:ResumeUpdates() | |
end | |
end | |
return | |
end | |
if HoldingCtrl then | |
if Selection.Selected[node.Object] then | |
Selection:Remove(node.Object) | |
else | |
Selection:Add(node.Object) | |
end | |
return | |
end | |
if Option.Modifiable then | |
local pos = Vector2.new(x,y) | |
dragReparent(node.Object,entry:Clone(),pos,entry.AbsolutePosition-pos) | |
elseif Option.Selectable then | |
if Selection.Selected[node.Object] then | |
Selection:Set({}) | |
else | |
Selection:Set({node.Object}) | |
end | |
dragSelect(i+self.ScrollIndex,true,'MouseButton1Up') | |
end | |
end) | |
entry.MouseButton2Down:connect(function() | |
if not Option.Selectable then return end | |
DestroyRightClick() | |
curSelect = entry | |
local node = TreeList[i + self.ScrollIndex] | |
if GetAwaitRemote:Invoke() then | |
bindSetAwaiting:Fire(node.Object) | |
return | |
end | |
if not Selection.Selected[node.Object] then | |
Selection:Set({node.Object}) | |
end | |
end) | |
entry.MouseButton2Up:connect(function() | |
if not Option.Selectable then return end | |
local node = TreeList[i + self.ScrollIndex] | |
if checkMouseInGui(curSelect) then | |
rightClickMenu(node.Object) | |
end | |
end) | |
entry.Parent = listFrame | |
end | |
entry.Visible = true | |
local object = node.Object | |
-- update expand icon | |
if #node == 0 then | |
entry.IndentFrame.Expand.Visible = false | |
elseif node.Expanded then | |
Icon(entry.IndentFrame.Expand,NODE_EXPANDED) | |
entry.IndentFrame.Expand.Visible = true | |
else | |
Icon(entry.IndentFrame.Expand,NODE_COLLAPSED) | |
entry.IndentFrame.Expand.Visible = true | |
end | |
-- update explorer icon | |
Icon(entry.IndentFrame.ExplorerIcon,ExplorerIndex[object.ClassName] or 0) | |
-- update indentation | |
local w = (node.Depth)*(2+ENTRY_PADDING+GUI_SIZE) | |
entry.IndentFrame.Position = UDim2.new(0,w,0,0) | |
entry.IndentFrame.Size = UDim2.new(1,-w,1,0) | |
-- update name change detection | |
if nameConnLookup[entry] then | |
nameConnLookup[entry]:disconnect() | |
end | |
local text = entry.IndentFrame.EntryText | |
text.Text = object.Name | |
nameConnLookup[entry] = node.Object.Changed:connect(function(p) | |
if p == 'Name' then | |
text.Text = object.Name | |
end | |
end) | |
-- update selection | |
entry.IndentFrame.Transparency = node.Selected and 0 or 1 | |
text.TextColor3 = GuiColor[node.Selected and 'TextSelected' or 'Text'] | |
entry.Size = UDim2.new(0,nodeWidth,0,ENTRY_SIZE) | |
elseif listEntries[i] then | |
listEntries[i].Visible = false | |
end | |
end | |
for i = self.VisibleSpace+1,self.TotalSpace do | |
local entry = listEntries[i] | |
if entry then | |
listEntries[i] = nil | |
entry:Destroy() | |
end | |
end | |
end | |
function scrollBarH.UpdateCallback(self) | |
for i = 1,scrollBar.VisibleSpace do | |
local node = TreeList[i + scrollBar.ScrollIndex] | |
if node then | |
local entry = listEntries[i] | |
if entry then | |
entry.Position = UDim2.new(0,2 - scrollBarH.ScrollIndex,0,ENTRY_BOUND*(i-1)+2) | |
end | |
end | |
end | |
end | |
Connect(listFrame.Changed,function(p) | |
if p == 'AbsoluteSize' then | |
rawUpdateSize() | |
end | |
end) | |
local wheelAmount = 6 | |
explorerPanel.MouseWheelForward:connect(function() | |
if scrollBar.VisibleSpace - 1 > wheelAmount then | |
scrollBar:ScrollTo(scrollBar.ScrollIndex - wheelAmount) | |
else | |
scrollBar:ScrollTo(scrollBar.ScrollIndex - scrollBar.VisibleSpace) | |
end | |
end) | |
explorerPanel.MouseWheelBackward:connect(function() | |
if scrollBar.VisibleSpace - 1 > wheelAmount then | |
scrollBar:ScrollTo(scrollBar.ScrollIndex + wheelAmount) | |
else | |
scrollBar:ScrollTo(scrollBar.ScrollIndex + scrollBar.VisibleSpace) | |
end | |
end) | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- Object detection | |
-- Inserts `v` into `t` at `i`. Also sets `Index` field in `v`. | |
local function insert(t,i,v) | |
for n = #t,i,-1 do | |
local v = t[n] | |
v.Index = n+1 | |
t[n+1] = v | |
end | |
v.Index = i | |
t[i] = v | |
end | |
-- Removes `i` from `t`. Also sets `Index` field in removed value. | |
local function remove(t,i) | |
local v = t[i] | |
for n = i+1,#t do | |
local v = t[n] | |
v.Index = n-1 | |
t[n-1] = v | |
end | |
t[#t] = nil | |
v.Index = 0 | |
return v | |
end | |
-- Returns how deep `o` is in the tree. | |
local function depth(o) | |
local d = -1 | |
while o do | |
o = o.Parent | |
d = d + 1 | |
end | |
return d | |
end | |
local connLookup = {} | |
-- Returns whether a node would be present in the tree list | |
local function nodeIsVisible(node) | |
local visible = true | |
node = node.Parent | |
while node and visible do | |
visible = visible and node.Expanded | |
node = node.Parent | |
end | |
return visible | |
end | |
-- Removes an object's tree node. Called when the object stops existing in the | |
-- game tree. | |
local function removeObject(object) | |
local objectNode = NodeLookup[object] | |
if not objectNode then | |
return | |
end | |
local visible = nodeIsVisible(objectNode) | |
Selection:Remove(object,true) | |
local parent = objectNode.Parent | |
remove(parent,objectNode.Index) | |
NodeLookup[object] = nil | |
connLookup[object]:disconnect() | |
connLookup[object] = nil | |
if visible then | |
updateList() | |
elseif nodeIsVisible(parent) then | |
updateScroll() | |
end | |
end | |
-- Moves a tree node to a new parent. Called when an existing object's parent | |
-- changes. | |
local function moveObject(object,parent) | |
local objectNode = NodeLookup[object] | |
if not objectNode then | |
return | |
end | |
local parentNode = NodeLookup[parent] | |
if not parentNode then | |
return | |
end | |
local visible = nodeIsVisible(objectNode) | |
remove(objectNode.Parent,objectNode.Index) | |
objectNode.Parent = parentNode | |
objectNode.Depth = depth(object) | |
local function r(node,d) | |
for i = 1,#node do | |
node[i].Depth = d | |
r(node[i],d+1) | |
end | |
end | |
r(objectNode,objectNode.Depth+1) | |
insert(parentNode,#parentNode+1,objectNode) | |
if visible or nodeIsVisible(objectNode) then | |
updateList() | |
elseif nodeIsVisible(objectNode.Parent) then | |
updateScroll() | |
end | |
end | |
local InstanceBlacklist = { | |
'Instance'; | |
'VRService'; | |
'ContextActionService'; | |
'AssetService'; | |
'TouchInputService'; | |
'ScriptContext'; | |
'FilteredSelection'; | |
'MeshContentProvider'; | |
'SolidModelContentProvider'; | |
'AnalyticsService'; | |
'RobloxReplicatedStorage'; | |
'GamepadService'; | |
'HapticService'; | |
'ChangeHistoryService'; | |
'Visit'; | |
'SocialService'; | |
'SpawnerService'; | |
'FriendService'; | |
'Geometry'; | |
'BadgeService'; | |
'PhysicsService'; | |
'CollectionService'; | |
'TeleportService'; | |
'HttpRbxApiService'; | |
'TweenService'; | |
'TextService'; | |
'NotificationService'; | |
'AdService'; | |
'CSGDictionaryService'; | |
'ControllerService'; | |
'RuntimeScriptService'; | |
'ScriptService'; | |
'MouseService'; | |
'KeyboardService'; | |
'CookiesService'; | |
'TimerService'; | |
'GamePassService'; | |
'KeyframeSequenceProvider'; | |
'NonReplicatedCSGDictionaryService'; | |
'GuidRegistryService'; | |
'PathfindingService'; | |
'GroupService'; | |
} | |
for i, v in ipairs(InstanceBlacklist) do | |
InstanceBlacklist[v] = true; | |
InstanceBlacklist[i] = nil; | |
end | |
-- ScriptContext['/Libraries/LibraryRegistration/LibraryRegistration'] | |
-- This RobloxLocked object lets me index its properties for some reason | |
local function check(object) | |
return object.AncestryChanged | |
end | |
-- Creates a new tree node from an object. Called when an object starts | |
-- existing in the game tree. | |
local function addObject(object,noupdate) | |
if object.Parent == game and InstanceBlacklist[object.ClassName] or object.ClassName == '' then | |
return; | |
end | |
if script then | |
-- protect against naughty RobloxLocked objects | |
local s = pcall(check,object) | |
if not s then | |
return | |
end | |
end | |
local parentNode = NodeLookup[object.Parent] | |
if not parentNode then | |
return | |
end | |
local objectNode = { | |
Object = object; | |
Parent = parentNode; | |
Index = 0; | |
Expanded = false; | |
Selected = false; | |
Depth = depth(object); | |
} | |
connLookup[object] = Connect(object.AncestryChanged,function(c,p) | |
if c == object then | |
if p == nil then | |
removeObject(c) | |
else | |
moveObject(c,p) | |
end | |
end | |
end) | |
NodeLookup[object] = objectNode | |
insert(parentNode,#parentNode+1,objectNode) | |
if not noupdate then | |
if nodeIsVisible(objectNode) then | |
updateList() | |
elseif nodeIsVisible(objectNode.Parent) then | |
updateScroll() | |
end | |
end | |
end | |
local function makeObject(obj,par) | |
local newObject = Instance.new(obj.ClassName) | |
for i,v in pairs(obj.Properties) do | |
ypcall(function() | |
local newProp | |
newProp = ToPropValue(v.Value,v.Type) | |
newObject[v.Name] = newProp | |
end) | |
end | |
newObject.Parent = par | |
end | |
local function writeObject(obj) | |
local newObject = {ClassName = obj.ClassName, Properties = {}} | |
for i,v in pairs(RbxApi.GetProperties(obj.className)) do | |
if v["Name"] ~= "Parent" then | |
print("thispassed") | |
table.insert(newObject.Properties,{Name = v["Name"], Type = v["ValueType"], Value = tostring(obj[v["Name"]])}) | |
end | |
end | |
return newObject | |
end | |
local function buildDexStorage() | |
local localDexStorage | |
local success,err = ypcall(function() | |
localDexStorage = game:GetObjects("rbxasset://DexStorage.rbxm")[1] | |
end) | |
if success and localDexStorage then | |
for i,v in pairs(localDexStorage:GetChildren()) do | |
ypcall(function() | |
v.Parent = DexStorageMain | |
end) | |
end | |
end | |
updateDexStorageListeners() | |
--[[ | |
local localDexStorage = readfile(getelysianpath().."DexStorage.txt")--game:GetService("CookiesService"):GetCookieValue("DexStorage") | |
--local success,err = pcall(function() | |
if localDexStorage then | |
local objTable = game:GetService("HttpService"):JSONDecode(localDexStorage) | |
for i,v in pairs(objTable) do | |
makeObject(v,DexStorageMain) | |
end | |
end | |
--end) | |
--]] | |
end | |
local dexStorageDebounce = false | |
local dexStorageListeners = {} | |
local function updateDexStorage() | |
if dexStorageDebounce then return end | |
dexStorageDebounce = true | |
wait() | |
pcall(function() | |
-- saveinstance("content//DexStorage.rbxm",DexStorageMain) | |
end) | |
updateDexStorageListeners() | |
dexStorageDebounce = false | |
--[[ | |
local success,err = ypcall(function() | |
local objs = {} | |
for i,v in pairs(DexStorageMain:GetChildren()) do | |
table.insert(objs,writeObject(v)) | |
end | |
writefile(getelysianpath().."DexStorage.txt",game:GetService("HttpService"):JSONEncode(objs)) | |
--game:GetService("CookiesService"):SetCookieValue("DexStorage",game:GetService("HttpService"):JSONEncode(objs)) | |
end) | |
if err then | |
CreateCaution("DexStorage Save Fail!","DexStorage broke! If you see this message, report to Raspberry Pi!") | |
end | |
print("hi") | |
--]] | |
end | |
function updateDexStorageListeners() | |
for i,v in pairs(dexStorageListeners) do | |
v:Disconnect() | |
end | |
dexStorageListeners = {} | |
for i,v in pairs(DexStorageMain:GetChildren()) do | |
pcall(function() | |
local ev = v.Changed:connect(updateDexStorage) | |
table.insert(dexStorageListeners,ev) | |
end) | |
end | |
end | |
do | |
NodeLookup[workspace.Parent] = { | |
Object = workspace.Parent; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
NodeLookup[DexOutput] = { | |
Object = DexOutput; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
if DexStorageEnabled then | |
NodeLookup[DexStorage] = { | |
Object = DexStorage; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
end | |
if NilStorageEnabled then | |
NodeLookup[NilStorage] = { | |
Object = NilStorage; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
end | |
if RunningScriptsStorageEnabled then | |
NodeLookup[RunningScriptsStorage] = { | |
Object = RunningScriptsStorage; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
end | |
if LoadedModulesStorageEnabled then | |
NodeLookup[LoadedModulesStorage] = { | |
Object = LoadedModulesStorage; | |
Parent = nil; | |
Index = 0; | |
Expanded = true; | |
} | |
end | |
Connect(game.DescendantAdded,addObject) | |
Connect(game.DescendantRemoving,removeObject) | |
Connect(DexOutput.DescendantAdded,addObject) | |
Connect(DexOutput.DescendantRemoving,removeObject) | |
if DexStorageEnabled then | |
--[[ | |
if readfile(getelysianpath().."DexStorage.txt") == nil then | |
writefile(getelysianpath().."DexStorage.txt","") | |
end | |
--]] | |
buildDexStorage() | |
Connect(DexStorage.DescendantAdded,addObject) | |
Connect(DexStorage.DescendantRemoving,removeObject) | |
Connect(DexStorage.DescendantAdded,updateDexStorage) | |
Connect(DexStorage.DescendantRemoving,updateDexStorage) | |
end | |
if NilStorageEnabled then | |
Connect(NilStorage.DescendantAdded,addObject) | |
Connect(NilStorage.DescendantRemoving,removeObject) | |
--[[local currentTable = get_nil_instances() | |
spawn(function() | |
while wait() do | |
if #currentTable ~= #get_nil_instances() then | |
currentTable = get_nil_instances() | |
--NilStorageMain:ClearAllChildren() | |
for i,v in pairs(get_nil_instances()) do | |
if v ~= NilStorage and v ~= DexStorage then | |
pcall(function() | |
v.Parent = NilStorageMain | |
end) | |
--[ [ | |
local newNil = v | |
newNil.Archivable = true | |
newNil:Clone().Parent = NilStorageMain | |
-- ] ] | |
end | |
end | |
end | |
end | |
end)]] | |
end | |
if RunningScriptsStorageEnabled then | |
Connect(RunningScriptsStorage.DescendantAdded,addObject) | |
Connect(RunningScriptsStorage.DescendantRemoving,removeObject) | |
end | |
if LoadedModulesStorageEnabled then | |
Connect(LoadedModulesStorage.DescendantAdded,addObject) | |
Connect(LoadedModulesStorage.DescendantRemoving,removeObject) | |
end | |
local function get(o) | |
return o:GetDescendants() | |
end | |
local function r(o) | |
local s,children = pcall(get, o) | |
if s then | |
for i = 1,#children do | |
addObject(children[i],true); | |
end | |
end | |
end | |
r(workspace.Parent) | |
r(DexOutput) | |
if DexStorageEnabled then | |
r(DexStorage) | |
end | |
if NilStorageEnabled then | |
r(NilStorage) | |
end | |
if RunningScriptsStorageEnabled then | |
r(RunningScriptsStorage) | |
end | |
if LoadedModulesStorageEnabled then | |
r(LoadedModulesStorage) | |
end | |
scrollBar.VisibleSpace = math.ceil(listFrame.AbsoluteSize.y/ENTRY_BOUND) | |
updateList() | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- Actions | |
local actionButtons do | |
actionButtons = {} | |
local totalActions = 1 | |
local currentActions = totalActions | |
local function makeButton(icon,over,name,vis,cond) | |
local buttonEnabled = false | |
local button = Create(Icon('ImageButton',icon),{ | |
Name = name .. "Button"; | |
Visible = Option.Modifiable and Option.Selectable; | |
Position = UDim2.new(1,-(GUI_SIZE+2)*currentActions+2,0.25,-GUI_SIZE/2); | |
Size = UDim2.new(0,GUI_SIZE,0,GUI_SIZE); | |
Parent = headerFrame; | |
}) | |
local tipText = Create('TextLabel',{ | |
Name = name .. "Text"; | |
Text = name; | |
Visible = false; | |
BackgroundTransparency = 1; | |
TextXAlignment = 'Right'; | |
Font = FONT; | |
FontSize = FONT_SIZE; | |
Position = UDim2.new(0,0,0,0); | |
Size = UDim2.new(1,-(GUI_SIZE+2)*totalActions,1,0); | |
Parent = headerFrame; | |
}) | |
button.MouseEnter:connect(function() | |
if buttonEnabled then | |
button.BackgroundTransparency = 0.9 | |
end | |
--Icon(button,over) | |
--tipText.Visible = true | |
end) | |
button.MouseLeave:connect(function() | |
button.BackgroundTransparency = 1 | |
--Icon(button,icon) | |
--tipText.Visible = false | |
end) | |
currentActions = currentActions + 1 | |
actionButtons[#actionButtons+1] = {Obj = button,Cond = cond} | |
QuickButtons[#actionButtons+1] = {Obj = button,Cond = cond, Toggle = function(on) | |
if on then | |
buttonEnabled = true | |
Icon(button,over) | |
else | |
buttonEnabled = false | |
Icon(button,icon) | |
end | |
end} | |
return button | |
end | |
--local clipboard = {} | |
local function delete(o) | |
o.Parent = nil | |
end | |
makeButton(ACTION_EDITQUICKACCESS,ACTION_EDITQUICKACCESS,"Options",true,function()return true end).MouseButton1Click:connect(function() | |
end) | |
-- DELETE | |
makeButton(ACTION_DELETE,ACTION_DELETE_OVER,"Delete",true,function() return #Selection:Get() > 0 end).MouseButton1Click:connect(function() | |
if not Option.Modifiable then return end | |
local list = Selection:Get() | |
for i = 1,#list do | |
pcall(delete,list[i]) | |
end | |
Selection:Set({}) | |
end) | |
-- PASTE | |
makeButton(ACTION_PASTE,ACTION_PASTE_OVER,"Paste",true,function() return #Selection:Get() > 0 and #clipboard > 0 end).MouseButton1Click:connect(function() | |
if not Option.Modifiable then return end | |
local parent = Selection.List[1] or workspace | |
for i = 1,#clipboard do | |
clipboard[i]:Clone().Parent = parent | |
end | |
end) | |
-- COPY | |
makeButton(ACTION_COPY,ACTION_COPY_OVER,"Copy",true,function() return #Selection:Get() > 0 end).MouseButton1Click:connect(function() | |
if not Option.Modifiable then return end | |
clipboard = {} | |
local list = Selection.List | |
for i = 1,#list do | |
table.insert(clipboard,list[i]:Clone()) | |
end | |
updateActions() | |
end) | |
-- CUT | |
makeButton(ACTION_CUT,ACTION_CUT_OVER,"Cut",true,function() return #Selection:Get() > 0 end).MouseButton1Click:connect(function() | |
if not Option.Modifiable then return end | |
clipboard = {} | |
local list = Selection.List | |
local cut = {} | |
for i = 1,#list do | |
local obj = list[i]:Clone() | |
if obj then | |
table.insert(clipboard,obj) | |
table.insert(cut,list[i]) | |
end | |
end | |
for i = 1,#cut do | |
pcall(delete,cut[i]) | |
end | |
updateActions() | |
end) | |
-- FREEZE | |
makeButton(ACTION_FREEZE,ACTION_FREEZE,"Freeze",true,function() return true end) | |
-- ADD/REMOVE STARRED | |
makeButton(ACTION_ADDSTAR,ACTION_ADDSTAR_OVER,"Star",true,function() return #Selection:Get() > 0 end) | |
-- STARRED | |
makeButton(ACTION_STARRED,ACTION_STARRED,"Starred",true,function() return true end) | |
-- SORT | |
-- local actionSort = makeButton(ACTION_SORT,ACTION_SORT_OVER,"Sort") | |
end | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---------------------------------------------------------------- | |
---- Option Bindables | |
do | |
local optionCallback = { | |
Modifiable = function(value) | |
for i = 1,#actionButtons do | |
actionButtons[i].Obj.Visible = value and Option.Selectable | |
end | |
cancelReparentDrag() | |
end; | |
Selectable = function(value) | |
for i = 1,#actionButtons do | |
actionButtons[i].Obj.Visible = value and Option.Modifiable | |
end | |
cancelSelectDrag() | |
Selection:Set({}) | |
end; | |
} | |
local bindSetOption = explorerPanel:FindFirstChild("SetOption") | |
if not bindSetOption then | |
bindSetOption = Create('BindableFunction',{Name = "SetOption"}) | |
bindSetOption.Parent = explorerPanel | |
end | |
bindSetOption.OnInvoke = function(optionName,value) | |
if optionCallback[optionName] then | |
Option[optionName] = value | |
optionCallback[optionName](value) | |
end | |
end | |
local bindGetOption = explorerPanel:FindFirstChild("GetOption") | |
if not bindGetOption then | |
bindGetOption = Create('BindableFunction',{Name = "GetOption"}) | |
bindGetOption.Parent = explorerPanel | |
end | |
bindGetOption.OnInvoke = function(optionName) | |
if optionName then | |
return Option[optionName] | |
else | |
local options = {} | |
for k,v in pairs(Option) do | |
options[k] = v | |
end | |
return options | |
end | |
end | |
end | |
function SelectionVar() | |
return Selection | |
end | |
Input.InputBegan:connect(function(key) | |
if key.KeyCode == Enum.KeyCode.LeftControl then | |
HoldingCtrl = true | |
end | |
if key.KeyCode == Enum.KeyCode.LeftShift then | |
HoldingShift = true | |
end | |
end) | |
Input.InputEnded:connect(function(key) | |
if key.KeyCode == Enum.KeyCode.LeftControl then | |
HoldingCtrl = false | |
end | |
if key.KeyCode == Enum.KeyCode.LeftShift then | |
HoldingShift = false | |
end | |
end) | |
while RbxApi == nil do | |
RbxApi = GetApiRemote:Invoke() | |
wait() | |
end | |
--[[ | |
explorerFilter.Changed:connect(function(prop) | |
if prop == "Text" then | |
rawUpdateList() | |
end | |
end) | |
]] -- literally just free lag | |
explorerFilter.FocusLost:Connect(function(EnterPressed) | |
if EnterPressed then | |
rawUpdateList() | |
end | |
end) | |
CurrentInsertObjectWindow = CreateInsertObjectMenu( | |
GetClasses(), | |
"", | |
false, | |
function(option) | |
CurrentInsertObjectWindow.Visible = false | |
local list = SelectionVar():Get() | |
for i = 1,#list do | |
pcall(function() Instance.new(option,list[i]) end) | |
end | |
DestroyRightClick() | |
end | |
) end,Properties={Disabled=true},Reference=17,ClassName="LocalScript"},{Properties={Name="SetSelection"},Reference=14,ClassName="BindableFunction"},{Properties={Name="GetSelection"},Reference=16,ClassName="BindableFunction"},{Properties={Name="SelectionChanged"},Reference=12,ClassName="BindableEvent"},{Properties={Name="GetOption"},Reference=15,ClassName="BindableFunction"},{Properties={Name="GetPrint"},Reference=18,ClassName="BindableFunction"},{Properties={Name="SetOption"},Reference=13,ClassName="BindableFunction"}},Properties={Name="ExplorerPanel",BackgroundTransparency=0.1000000014901161,Position=UDim2.new(1,0,0,0),BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,300,0.5,0),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=11,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",TextStrokeTransparency=0.75,Name="FileName",BackgroundTransparency=0.2000000029802322,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0.8500000238418579,0,0,30),Position=UDim2.new(0.07500000298023224,0,0.4000000059604645,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=55,ClassName="TextBox"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="This will save an instance to your PC. Type in the name for your instance. (.rbxmx will be added automatically.)",Text="This will save an instance to your PC. Type in the name for your instance. (.rbxmx will be added automatically.)",TextStrokeTransparency=0.75,Name="Desc",BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,40),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=53,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save",Text="Save",TextStrokeTransparency=0.75,Name="Save",BackgroundTransparency=0.5,Position=UDim2.new(0.07500000298023224,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=52,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save \"Object\" type values",Text="Save \"Object\" type values",TextStrokeTransparency=0.75,Name="Desc2",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0.925000011920929,-30,0,20),Position=UDim2.new(0.07500000298023224,30,0.625,0),TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=58,ClassName="TextLabel"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",TextStrokeTransparency=0.75,Name="enabled",BackgroundTransparency=0.4000000059604645,Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,14,0,14),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0.3803921937942505,0.3803921937942505,0.3803921937942505)},Reference=57,ClassName="TextLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",TextStrokeTransparency=0.75,Name="SaveObjects",BackgroundTransparency=0.6000000238418579,Position=UDim2.new(0.07500000298023224,0,0.625,0),Size=UDim2.new(0,20,0,20),ZIndex=2,TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=56,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Cancel",Text="Cancel",TextStrokeTransparency=0.75,Name="Cancel",BackgroundTransparency=0.5,Position=UDim2.new(0.5249999761581421,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=54,ClassName="TextButton"}},Properties={BackgroundTransparency=0.1000000014901161,BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Name="MainWindow",Size=UDim2.new(1,0,0,200),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=51,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Save Instance",Text="Save Instance",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Title",ZIndex=2,TextSize=14,Size=UDim2.new(1,0,1,0)},Reference=50,ClassName="TextLabel"}},Properties={Visible=false,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,350,0,20),Name="SaveInstance",Position=UDim2.new(0.300000011920929,0,0.300000011920929,0),Draggable=true,ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=49,ClassName="Frame"},{Children={{Children={{Properties={ImageTransparency=1,Name="Icon",Image="rbxassetid://475456048",BackgroundTransparency=1,Position=UDim2.new(0,5,0,5),Size=UDim2.new(0,20,0,20),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(1,1,1)},Reference=37,ClassName="ImageLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Active=false,Text="",AutoButtonColor=false,Name="OpenScriptEditor",Position=UDim2.new(0,0,0,30),Size=UDim2.new(0,30,0,30),BorderSizePixel=0,TextSize=24,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=36,ClassName="TextButton"},{Properties={ImageColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574),Image="rbxassetid://1513966937",BackgroundTransparency=1,Position=UDim2.new(0,0,0,90),Name="Slant",Size=UDim2.new(0,30,0,30),Rotation=180,BackgroundColor3=Color3.new(1,1,1)},Reference=24,ClassName="ImageLabel"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="v3",Text="v3",TextStrokeTransparency=0.75,Name="Version",FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),BackgroundTransparency=1,Position=UDim2.new(0,0,0,15),Size=UDim2.new(0,30,0,20),ZIndex=2,TextSize=12,BackgroundColor3=Color3.new(1,1,1)},Reference=23,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextTransparency=1,TextColor3=Color3.new(1,1,1),LocalizedText=">",Text=">",Size=UDim2.new(0,30,0,30),TextStrokeTransparency=0.800000011920929,Active=false,BorderSizePixel=0,Name="Toggle",Position=UDim2.new(0,0,0,60),AutoButtonColor=false,TextWrapped=true,TextSize=24,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=21,ClassName="TextButton"},{Children={{Children={{Children={{Properties={Image="rbxassetid://472636337",BackgroundTransparency=1,Position=UDim2.new(0,5,0,5),Name="Icon",ZIndex=2,Size=UDim2.new(0,20,0,20),BackgroundColor3=Color3.new(1,1,1)},Reference=31,ClassName="ImageLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Text="",AutoButtonColor=false,Name="SaveMap",BackgroundTransparency=1,Position=UDim2.new(0,0,0,60),Size=UDim2.new(0,30,0,30),BorderSizePixel=0,TextSize=24,BackgroundColor3=Color3.new(0.1568627506494522,0.1568627506494522,0.1568627506494522)},Reference=30,ClassName="TextButton"},{Children={{Properties={Image="rbxassetid://476354004",BackgroundTransparency=1,Position=UDim2.new(0,5,0,5),Name="Icon",ZIndex=2,Size=UDim2.new(0,20,0,20),BackgroundColor3=Color3.new(1,1,1)},Reference=35,ClassName="ImageLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Text="",AutoButtonColor=false,BackgroundTransparency=1,Name="About",Size=UDim2.new(0,30,0,30),BorderSizePixel=0,TextSize=24,BackgroundColor3=Color3.new(0.1568627506494522,0.1568627506494522,0.1568627506494522)},Reference=34,ClassName="TextButton"},{Children={{Properties={Image="rbxassetid://472635937",BackgroundTransparency=1,Position=UDim2.new(0,5,0,5),Name="Icon",ZIndex=2,Size=UDim2.new(0,20,0,20),BackgroundColor3=Color3.new(1,1,1)},Reference=29,ClassName="ImageLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Text="",AutoButtonColor=false,Name="Explorer",BackgroundTransparency=1,Position=UDim2.new(0,0,0,90),Size=UDim2.new(0,30,0,30),BorderSizePixel=0,TextSize=24,BackgroundColor3=Color3.new(0.1568627506494522,0.1568627506494522,0.1568627506494522)},Reference=28,ClassName="TextButton"},{Children={{Properties={Image="rbxassetid://472635774",BackgroundTransparency=1,Position=UDim2.new(0,5,0,5),Name="Icon",ZIndex=2,Size=UDim2.new(0,20,0,20),BackgroundColor3=Color3.new(1,1,1)},Reference=33,ClassName="ImageLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Text="",AutoButtonColor=false,Name="Settings",BackgroundTransparency=1,Position=UDim2.new(0,0,0,30),Size=UDim2.new(0,30,0,30),BorderSizePixel=0,TextSize=24,BackgroundColor3=Color3.new(0.1568627506494522,0.1568627506494522,0.1568627506494522)},Reference=32,ClassName="TextButton"}},Properties={Name="SlideFrame",Position=UDim2.new(0,0,0,-120),Size=UDim2.new(0,30,0,120),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=27,ClassName="Frame"}},Properties={Name="SlideOut",BackgroundTransparency=1,ClipsDescendants=true,Size=UDim2.new(0,30,0,150),Position=UDim2.new(0,0,0,30),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=26,ClassName="Frame"},{Properties={Name="Main",Size=UDim2.new(0,30,0,30),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=25,ClassName="Frame"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="DEX",Text="DEX",TextStrokeTransparency=0.75,Name="Title",BackgroundTransparency=1,FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),Size=UDim2.new(0,30,0,20),ZIndex=2,TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=22,ClassName="TextLabel"}},Properties={Visible=false,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Name="SideMenu",BackgroundTransparency=1,Position=UDim2.new(1,-330,0,0),Size=UDim2.new(0,30,0,180),ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=20,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Settings",Text="Settings",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,BorderSizePixel=0,Position=UDim2.new(0,4,0,0),TextSize=14,Size=UDim2.new(1,-4,1,0)},Reference=40,ClassName="TextLabel"}},Properties={Name="Header",BorderColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261),Size=UDim2.new(1,0,0,17),BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=39,ClassName="Frame"},{Properties={BackgroundTransparency=1,Position=UDim2.new(0,0,0,17),BorderColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261),Name="SettingList",Size=UDim2.new(1,0,1,-17),BackgroundColor3=Color3.new(1,1,1)},Reference=48,ClassName="Frame"},{Properties={Name="GetSetting"},Reference=41,ClassName="BindableFunction"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="SettingName",Text="SettingName",TextStrokeTransparency=0.75,Name="SName",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,-20,0,30),Position=UDim2.new(0,10,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=43,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Off",Text="Off",TextStrokeTransparency=0.75,Name="Status",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0,50,0,15),Position=UDim2.new(0,60,0,30),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=44,ClassName="TextLabel"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),ClipsDescendants=true,Text="",Name="Bar",Position=UDim2.new(0,-2,0,-2),Size=UDim2.new(0,10,0,19),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0,0,0)},Reference=47,ClassName="TextLabel"},{Properties={Size=UDim2.new(0,0,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="OnBar",BorderSizePixel=0,TextWrapped=true,Text="",TextSize=14,BackgroundColor3=Color3.new(0,0.5764706134796143,0.8627451658248901)},Reference=46,ClassName="TextLabel"}},Properties={Size=UDim2.new(0,40,0,15),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),Name="Change",Position=UDim2.new(0,10,0,30),BorderSizePixel=0,Text="",TextSize=14,BackgroundColor3=Color3.new(0.8627451658248901,0.8627451658248901,0.8627451658248901)},Reference=45,ClassName="TextButton"}},Properties={Visible=false,BackgroundTransparency=1,Position=UDim2.new(0,0,0,18),Name="SettingTemplate",Size=UDim2.new(1,0,0,60),BackgroundColor3=Color3.new(1,1,1)},Reference=42,ClassName="Frame"}},Properties={Name="SettingsPanel",BackgroundTransparency=0.1000000014901161,Position=UDim2.new(1,0,0,0),BorderColor3=Color3.new(0.0784313753247261,0,0.0784313753247261),Size=UDim2.new(0,300,1,0),BorderSizePixel=0,BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=38,ClassName="Frame"},{Children={{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Call",Text="Call",TextStrokeTransparency=0.75,Name="Ok",BackgroundTransparency=0.5,Position=UDim2.new(0.07500000298023224,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=84,ClassName="TextButton"},{Properties={TextWrapped=true,TextColor3=Color3.new(1,1,1),LocalizedText="Arguments",Text="Arguments",TextStrokeTransparency=0.75,Name="Desc",BackgroundTransparency=1,Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,20),FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=73,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Display values returned",Text="Display values returned",TextStrokeTransparency=0.75,Name="Desc2",BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(0.925000011920929,-30,0,20),Position=UDim2.new(0.07500000298023224,30,0.625,0),TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=77,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="-",Text="-",TextStrokeTransparency=0.75,Name="Subtract",BackgroundTransparency=0.5,Position=UDim2.new(0.8999999761581421,0,0.625,0),Size=UDim2.new(0,20,0,20),BorderColor3=Color3.new(0,0,0),TextSize=24,BackgroundColor3=Color3.new(1,1,1)},Reference=79,ClassName="TextButton"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Cancel",Text="Cancel",TextStrokeTransparency=0.75,Name="Cancel",BackgroundTransparency=0.5,Position=UDim2.new(0.5249999761581421,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=83,ClassName="TextButton"},{Children={{Properties={Visible=false,FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(0.4941176772117615,0.4941176772117615,0.4941176772117615),Text="",TextStrokeTransparency=0.75,Name="enabled",BackgroundTransparency=0.4000000059604645,Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,14,0,14),BorderSizePixel=0,TextSize=14,BackgroundColor3=Color3.new(0.3803921937942505,0.3803921937942505,0.3803921937942505)},Reference=76,ClassName="TextLabel"}},Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",TextStrokeTransparency=0.75,Name="DisplayReturned",BackgroundTransparency=0.6000000238418579,Position=UDim2.new(0.07500000298023224,0,0.625,0),Size=UDim2.new(0,20,0,20),ZIndex=2,TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=75,ClassName="TextButton"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),Text="",TextStrokeTransparency=0.75,Name="Value",Size=UDim2.new(0.6000000238418579,-12,0,20),BackgroundTransparency=0.8999999761581421,PlaceholderColor3=Color3.new(0.6980392336845398,0.6980392336845398,0.6980392336845398),Position=UDim2.new(0.4000000059604645,0,0,0),TextXAlignment=Enum.TextXAlignment.Left,TextSize=14,BackgroundColor3=Color3.new(1,1,1)},Reference=82,ClassName="TextBox"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Script",Text="Script",TextStrokeTransparency=0.75,BackgroundTransparency=0.8999999761581421,Name="Type",Size=UDim2.new(0.4000000059604645,0,0,20),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(1,1,1)},Reference=81,ClassName="TextButton"}},Properties={Visible=false,BackgroundTransparency=0.5,BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Name="ArgumentTemplate",Size=UDim2.new(1,0,0,20),BackgroundColor3=Color3.new(0.2235294282436371,0.2235294282436371,0.2235294282436371)},Reference=80,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Bold,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="+",Text="+",TextStrokeTransparency=0.75,Name="Add",BackgroundTransparency=0.5,Position=UDim2.new(0.800000011920929,0,0.625,0),Size=UDim2.new(0,20,0,20),BorderColor3=Color3.new(0,0,0),TextSize=24,BackgroundColor3=Color3.new(1,1,1)},Reference=78,ClassName="TextButton"},{Properties={MidImage="rbxasset://textures/blackBkg_square.png",AbsoluteWindowSize=Vector2.new(350,80),Name="Arguments",Size=UDim2.new(1,0,0,80),Position=UDim2.new(0,0,0,40),BackgroundTransparency=1,TopImage="rbxasset://textures/blackBkg_square.png",ScrollingDirection=Enum.ScrollingDirection.Y,BackgroundColor3=Color3.new(1,1,1),AbsoluteCanvasSize=Vector2.new(350,80),BottomImage="rbxasset://textures/blackBkg_square.png",CanvasSize=UDim2.new(0,0,0,0)},Reference=74,ClassName="ScrollingFrame"}},Properties={BackgroundTransparency=0.1000000014901161,BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Name="MainWindow",Size=UDim2.new(1,0,0,200),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=72,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Call Remote",Text="Call Remote",TextStrokeTransparency=0.75,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Title",ZIndex=2,TextSize=14,Size=UDim2.new(1,0,1,0)},Reference=71,ClassName="TextLabel"}},Properties={Visible=false,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,350,0,20),Name="CallRemote",Position=UDim2.new(0.5,-175,0.5,-100),Draggable=true,ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=70,ClassName="Frame"},{Children={{Children={{Properties={MidImage="rbxasset://textures/blackBkg_square.png",AbsoluteWindowSize=Vector2.new(349.9999694824219,80),Name="TableResults",Size=UDim2.new(1,0,0,80),Position=UDim2.new(0,0,0,20),BackgroundTransparency=1,TopImage="rbxasset://textures/blackBkg_square.png",ScrollingDirection=Enum.ScrollingDirection.Y,BackgroundColor3=Color3.new(1,1,1),AbsoluteCanvasSize=Vector2.new(349.9999694824219,80),BottomImage="rbxasset://textures/blackBkg_square.png",CanvasSize=UDim2.new(0,0,0,0)},Reference=88,ClassName="ScrollingFrame"},{Children={{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Script",Text="Script",TextStrokeTransparency=0.800000011920929,BackgroundTransparency=0.8999999761581421,Position=UDim2.new(0.4000000059604645,0,0,0),Name="Value",Size=UDim2.new(0.6000000238418579,-12,0,20),TextSize=14,BackgroundColor3=Color3.new(0.4000000357627869,0.4000000357627869,0.4000000357627869)},Reference=91,ClassName="TextLabel"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Script",Text="Script",TextStrokeTransparency=0.800000011920929,BackgroundTransparency=0.8999999761581421,Name="Type",Size=UDim2.new(0.4000000059604645,0,0,20),TextSize=18,BackgroundColor3=Color3.new(0.4000000357627869,0.4000000357627869,0.4000000357627869)},Reference=90,ClassName="TextLabel"}},Properties={Visible=false,BackgroundTransparency=0.5,BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Name="TableTemplate",Size=UDim2.new(1,0,0,20),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=89,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),LocalizedText="Ok",Text="Ok",Name="Ok",BackgroundTransparency=0.5,Position=UDim2.new(0.300000011920929,0,1,-40),Size=UDim2.new(0.4000000059604645,0,0,30),BorderColor3=Color3.new(0,0,0),TextSize=18,BackgroundColor3=Color3.new(0.4235294461250305,0.4235294461250305,0.4235294461250305)},Reference=87,ClassName="TextButton"}},Properties={BackgroundTransparency=0.1000000014901161,BorderColor3=Color3.new(0.7490196228027344,0.7490196228027344,0.7490196228027344),Name="MainWindow",Size=UDim2.new(1,0,0,150),BackgroundColor3=Color3.new(0.168627455830574,0.168627455830574,0.168627455830574)},Reference=86,ClassName="Frame"},{Properties={FontFace=Font.new("rbxasset://fonts/families/SourceSansPro.json",Enum.FontWeight.Regular,Enum.FontStyle.Normal),TextColor3=Color3.new(1,1,1),LocalizedText="Caution",Text="Caution",TextStrokeTransparency=0.800000011920929,BackgroundTransparency=1,TextXAlignment=Enum.TextXAlignment.Left,Name="Title",ZIndex=2,TextSize=14,Size=UDim2.new(1,0,1,0)},Reference=92,ClassName="TextLabel"}},Properties={Visible=false,Active=true,BorderColor3=Color3.new(0.5843137502670288,0.5843137502670288,0.5843137502670288),Size=UDim2.new(0,350,0,20),Name="TableCaution",Position=UDim2.new(0.300000011920929,0,0.300000011920929,0),Draggable=true,ZIndex=2,BorderSizePixel=0,BackgroundColor3=Color3.new(0.0784313753247261,0.0784313753247261,0.0784313753247261)},Reference=85,ClassName="Frame"}},Properties={Name="Dex"},Reference=2,ClassName="ScreenGui"}}}}local Flags={ContextualExecution=false,ReturnMainModule=true}do local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p='0.4.1',Flags or{},script,next,unpack,table,require,type,pcall,getfenv,setfenv,setmetatable,rawget,coroutine,task,Instance local q,r,s,t,u,v,w,x,y=f.insert,f.freeze,n.wrap,o.defer,o.cancel,p.new,(b.ContextualExecution==nil and true)or b.ContextualExecution do if w then local z=game:GetService'RunService'x=z:IsServer()y=z:IsClient()end end local z,A,B,C,D,E={},{},{},{},{},{}local function F(G)local H,I=i(v,G.ClassName)if not H then return end z[G.Reference]=I if G.Closure then B[I]=G.Closure if I:IsA'BaseScript'then q(D,I)end end if G.Properties then for J,K in d,G.Properties do i(function()I[J]=K end)end end if G.RefProperties then for J,K in d,G.RefProperties do q(A,{InstanceObject=I,Property=J,ReferenceId=K})end end if G.Attributes then for J,K in d,G.Attributes do i(I.SetAttribute,I,J,K)end end if G.Children then for J,K in d,G.Children do local L=F(K)if L then L.Parent=I end end end return I end local G={}do for H,I in d,ModuleRoot do q(G,F(I))end end local H=j(0)local function I(J)local K=C[J]if J.ClassName=='ModuleScript'and K then return e(K)end local L=B[J]if not L then return end do local M local N={['maui']=r{Version=a,Script=c,Shared=E,GetScript=function()return c end,GetShared=function()return E end},['script']=J,['require']=function(N,...)if N and N.ClassName=='ModuleScript'and B[N]then return I(N)end return g(N,...)end,['getfenv']=function(N,...)if h(N)=='number'and N>=0 then if N==0 then return M else N=N+1 local O,P=i(j,N)if O and P==H then return M end end end return j(N,...)end,['setfenv']=function(N,O,...)if h(N)=='number'and N>=0 then if N==0 then return k(M,O)else N=N+1 local P,Q=i(j,N)if P and Q==H then return k(M,O)end end end return k(N,O,...)end}M=l({},{__index=function(O,P)local Q=m(M,P)if Q~=nil then return Q end local R=N[P]if R~=nil then return R end return H[P]end})k(L,M)end local M=s(L)if J:IsA'BaseScript'then local N=(not w or not J.Disabled)and t(M)if w then local O O=J:GetPropertyChangedSignal'Disabled':Connect(function(P)O:Disconnect()if P==false then I(J)else i(u,N)end end)end return else local N={M()}C[J]=N return e(N)end end for J,K in d,A do i(function()K.InstanceObject[K.Property]=z[K.ReferenceId]end)end for L,M in d,D do if not w or((x and M.ClassName=='Script')or(y and M.ClassName=='LocalScript'))then I(M)end end if b.ReturnMainModule==nil or b.ReturnMainModule then local N do for O,P in d,G do if P.ClassName=='ModuleScript'and P.Name=='MainModule'then N=P break end end end if N then return I(N)end end end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment