Run it
Copy the script and paste it into your executor.
selection
nodes = {}
oldgame =
= .Parent
cloneref = cloneref (ref)
getreg ref
InstanceList
a = .()
_, c (())
(c) == #c
(c, ) ==
d, e (c)
e == a
InstanceList = c
f = {}
f.(g)
InstanceList
b, c (InstanceList)
c == g
InstanceList[b] =
g
f.invalidate
EmbeddedModules = {
[] = ()
Main,Lib,Apps,Settings
Explorer, Properties, ScriptViewer, Notebook
API,RMD,env,service,plr,create,createSimple
(data)
Main = data.Main
Lib = data.Lib
Apps = data.Apps
Settings = data.Settings
API = data.API
RMD = data.RMD
env = data.env
service = data.service
plr = data.plr
create = data.create
createSimple = data.createSimple
()
Explorer = Apps.Explorer
Properties = Apps.Properties
ScriptViewer = Apps.ScriptViewer
Notebook = Apps.Notebook
()
Console = {}
window,ConsoleFrame
OutputLimit =
G2L = {};
window = Lib.Window.()
window:()
window:(,)
Console.Window = window
ConsoleFrame = .(, window.GuiElems.Content);
ConsoleFrame[] = ;
ConsoleFrame[] = ;
ConsoleFrame[] = ;
ConsoleFrame[] = .(, , );
ConsoleFrame[] = ;
ConsoleFrame[] = .(,,,);
ConsoleFrame[] = .(, , );
ConsoleFrame[] = ;
ConsoleFrame[] = .(,,,);
G2L[] = Lib.Frame.().Gui
G2L[].Parent = ConsoleFrame
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, );
G2L[][] = ;
G2L[][] = .(, -, , );
G2L[][] = .(, , , -);
G2L[][] = .(, , );
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = .ScrollingDirection.X;
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .ElasticBehavior.Never;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .ScrollBarInset.Always;
G2L[][] = ;
G2L[][] = .AutomaticSize.X;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = -;
G2L[][] = .TextXAlignment.Left;
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .AutomaticSize.X;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .TextXAlignment.Left;
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[][] = .AutomaticSize.X;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, );
G2L[][] = .(, -, , -);
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
scrollbar = Lib.ScrollBar.()
scrollbar.Gui.Parent = ConsoleFrame
scrollbar.Gui.Size = .(, , , -);
scrollbar.Gui.Position = .(, -,, );
scrollbar.Gui.Up.ZIndex =
scrollbar.Gui.Down.ZIndex =
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = ;
G2L[][] = .(, , );
G2L[].BackgroundTransparency =
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, );
G2L[][] = .AutomaticSize.Y;
G2L[][] = .(, -, , -);
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[].ScrollBarImageColor3 = .(, , )
G2L[][] = ;
G2L[][] = ;
G2L[]:():(()
G2L[].AbsoluteCanvasSize ~= G2L[].AbsoluteWindowSize
scrollbar.Gui.Visible =
scrollbar.Gui.Visible =
)
G2L[] = .(, G2L[]);
G2L[][] = .SortOrder.LayoutOrder;
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = OutputLimit;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[][] = .(, );
G2L[][] = .(, );
G2L[][] = .(, );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, -, , );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[][] = .(, );
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .TextXAlignment.Left;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .AutomaticSize.Y;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[][] = .(, );
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[][] = .(, );
G2L[] = .(, ConsoleFrame);
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = ;
G2L[][] = .(, , );
G2L[][] = Font.(, .FontWeight.Regular, .FontStyle.Normal);
G2L[][] = .(, , );
G2L[][] = ;
G2L[][] = .(, , , );
G2L[][] = .(, , );
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = .(, );
G2L[][] = .(, );
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L[] = .(, G2L[]);
G2L[][] = ;
G2L_REQUIRE = ;
G2L_MODULES = {};
(Module)
ModuleState = G2L_MODULES[Module];
ModuleState
ModuleState.Required
ModuleState.Required = ;
ModuleState.Value = ModuleState.();
ModuleState.Value;
;
(Module);
G2L_MODULES[G2L[]] = {
Closure = ()
= G2L[]; highlighter = {}
keywords = {
lua = {
, , , , , , , , , , , , , ,
, , ,
},
rbx = {
, , , , , , , , , , ,
, , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , ,
, , , , , , , , , ,
},
exploit = {
, , , , , , , , , ,
, , , , , , ,
, , , , , , , , , , ,
, , , , , , , ,
},
operators = {
, , , , , , , , , , , , , , , , , , , , ,
}
}
colors = {
numbers = .(, , ),
boolean = .(, , ),
operator = .(, , ),
lua = .(, , ),
exploit = .(, , ),
rbx = .(, , ),
str = .(, , ),
comment = .(, , ),
null = .(, , ),
call = .(, , ),
self_call = .(, , ),
local_color = .(, , ),
function_color = .(, , ),
self_color = .(, , ),
local_property = .(, , ),
}
(keywords)
keywordSet = {}
_, keyword (keywords)
keywordSet[keyword] =
keywordSet
luaSet = (keywords.lua)
exploitSet = (keywords.exploit)
rbxSet = (keywords.rbx)
operatorsSet = (keywords.operators)
(tokens, index)
token = tokens[index]
colors[token .. ]
colors[token .. ]
(token)
colors.numbers
token ==
colors.null
token:(, ) ==
colors.comment
operatorsSet[token]
colors.operator
luaSet[token]
colors.rbx
rbxSet[token]
colors.lua
exploitSet[token]
colors.exploit
token:(, ) == token:(, ) ==
colors.str
token == token ==
colors.boolean
tokens[index + ] ==
tokens[index - ] ==
colors.self_call
colors.call
tokens[index - ] ==
tokens[index - ] ==
colors.rbx
colors.local_property
highlighter.(source)
tokens = {}
currentToken =
inString =
inComment =
commentPersist =
i = , #source
character = source:(i, i)
inComment
character == commentPersist
.(tokens, currentToken)
.(tokens, character)
currentToken =
inComment =
source:(i - , i) == commentPersist
currentToken ..=
.(tokens, currentToken)
currentToken =
inComment =
commentPersist =
currentToken = currentToken .. character
inString
character == inString source:(i-, i-) ~= character ==
currentToken = currentToken .. character
inString =
currentToken = currentToken .. character
source:(i, i + ) ==
.(tokens, currentToken)
currentToken =
inComment =
commentPersist = source:(i + , i + ) ==
character == character ==
.(tokens, currentToken)
currentToken = character
inString = character
operatorsSet[character]
.(tokens, currentToken)
.(tokens, character)
currentToken =
character:()
currentToken = currentToken .. character
.(tokens, currentToken)
.(tokens, character)
currentToken =
.(tokens, currentToken)
highlighted = {}
i, token (tokens)
highlight = (tokens, i)
highlight
syntax = .(, highlight:(), token:(, ):(, ))
.(highlighted, syntax)
.(highlighted, token)
.(highlighted)
highlighter
;
};
Console.Init = ()
CtrlScroll =
AutoScroll =
LogService = :()
Players = :()
LocalPlayer = Players.LocalPlayer
Mouse = LocalPlayer:()
UserInputService = :()
RunService = :()
Console = ConsoleFrame
SyntaxHighlightingModule = (G2L[].SyntaxHighlighter)
OutputTextSize = Console.Output.OutputTextSize
(obj, info, prop)
tween = :():(obj, info, prop)
tween:()
tween
CtrlScroll ==
Console.CtrlScroll.BackgroundColor3 = .(, , )
CtrlScroll ==
Console.CtrlScroll.BackgroundColor3 = .(, , )
Console.CtrlScroll.MouseButton1Click:(()
CtrlScroll = CtrlScroll
CtrlScroll ==
Console.CtrlScroll.BackgroundColor3 = .(, , )
CtrlScroll ==
Console.CtrlScroll.BackgroundColor3 = .(, , )
)
IsHoldingCTRL =
UserInputService.InputBegan:((input, gameproc)
gameproc
input.KeyCode == .KeyCode.LeftControl input.KeyCode == .KeyCode.RightControl
IsHoldingCTRL =
)
UserInputService.InputEnded:((input, gameproc)
gameproc
input.KeyCode == .KeyCode.LeftControl input.KeyCode == .KeyCode.RightControl
IsHoldingCTRL =
)
AutoScroll ==
Console.AutoScroll.BackgroundColor3 = .(, , )
AutoScroll ==
Console.AutoScroll.BackgroundColor3 = .(, , )
Console.AutoScroll.MouseButton1Click:(()
AutoScroll = AutoScroll
AutoScroll ==
Console.AutoScroll.BackgroundColor3 = .(, , )
Console.Output.CanvasPosition = .(, )
AutoScroll ==
Console.AutoScroll.BackgroundColor3 = .(, , )
)
displayedOutput = {}
OutputLimit = Console.Output.OutputLimit
Console.TextSizeBox.TextBox.Text = (OutputTextSize.Value)
Console.TextSizeBox.TextBox:():(()
tonum = (Console.TextSizeBox.TextBox.Text)
tonum
OutputTextSize.Value = tonum
)
OutputTextSize:():(()
Console.TextSizeBox.TextBox.Text = (OutputTextSize.Value)
)
scrollConsoleInput
Console.Output.MouseEnter:(()
scrollConsoleInput = UserInputService.InputChanged:((input)
CtrlScroll input.UserInputType == .UserInputType.MouseWheel IsHoldingCTRL ==
Console.Output.ScrollingEnabled =
newTextSize = OutputTextSize.Value + input.Position.Z
newTextSize >=
OutputTextSize.Value = newTextSize
Console.Output.ScrollingEnabled =
)
)
Console.Output.MouseLeave:(()
scrollConsoleInput
scrollConsoleInput:()
scrollConsoleInput =
)
Console.Clear.MouseButton1Click:(()
_, log (Console.Output:())
log:()
log:()
)
focussedOutput
LogService.MessageOut:((msg, msgtype)
formattedText =
unformattedText =
newOutputText = Console.OutputTemplate:()
.(displayedOutput, newOutputText)
#displayedOutput > OutputLimit.Value
oldest = .(displayedOutput, )
oldest (oldest) ==
oldest:()
unformattedText = .()....msg
msgtype == .MessageType.MessageOutput
formattedText = .()....msg..
newOutputText.Text = formattedText
msgtype == .MessageType.MessageWarning
formattedText = .()....msg..
newOutputText.Text = formattedText
msgtype == .MessageType.MessageError
formattedText = .()....msg..
newOutputText.Text = formattedText
msgtype == .MessageType.MessageInfo
formattedText = .()....msg..
newOutputText.Text = formattedText
newOutputText.TextSize = OutputTextSize.Value
OutputTextSize:():(()
newOutputText.TextSize = OutputTextSize.Value
)
newOutputText.Focused:(()
focussedOutput = newOutputText
newOutputText.Text = unformattedText
)
newOutputText.FocusLost:(()
focussedOutput =
newOutputText.Text = formattedText
)
newOutputText.Parent = Console.Output
newOutputText.Visible =
AutoScroll
Console.Output.CanvasPosition = .(, )
)
Console.Output.MouseLeave:(()
focussedOutput
focussedOutput:()
)
Console.CommandLine.ScrollingFrame.TextBox:():(()
oneliner = .(Console.CommandLine.ScrollingFrame.TextBox.Text, , )
Console.CommandLine.ScrollingFrame.TextBox.Text = oneliner
Console.CommandLine.ScrollingFrame.Highlight.Text = SyntaxHighlightingModule.(Console.CommandLine.ScrollingFrame.TextBox.Text)
)
Console.CommandLine.ScrollingFrame.TextBox.FocusLost:((enterPressed)
enterPressed Console.CommandLine.ScrollingFrame.TextBox.Text ~=
(..Console.CommandLine.ScrollingFrame.TextBox.Text)
(Console.CommandLine.ScrollingFrame.TextBox.Text)()
)
Console
{InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
,
[] = ()
Main,Lib,Apps,Settings
Explorer, Properties, ScriptViewer, ModelViewer, Notebook
API,RMD,env,service,plr,create,createSimple
(data)
Main = data.Main
Lib = data.Lib
Apps = data.Apps
Settings = data.Settings
API = data.API
RMD = data.RMD
env = data.env
service = data.service
plr = data.plr
create = data.create
createSimple = data.createSimple
()
Explorer = Apps.Explorer
Properties = Apps.Properties
ScriptViewer = Apps.ScriptViewer
ModelViewer = Apps.ModelViewer
Notebook = Apps.Notebook
()
Explorer = {}
tree,listEntries,explorerOrders,searchResults,specResults = {},{},{},{},{}
expanded
entryTemplate,treeFrame,toolBar,descendantAddedCon,descendantRemovingCon,itemChangedCon
ffa = .FindFirstAncestorWhichIsA
getDescendants = .GetDescendants
getTextSize = service.TextService.GetTextSize
updateDebounce,refreshDebounce = ,
nilNode = {Obj = .()}
idCounter =
scrollV,scrollH,clipboard
renameBox,renamingNode,searchFunc
sortingEnabled,autoUpdateSearch
, = ,
nilMap,nilCons = {},{}
connectSignal = .DescendantAdded.Connect
addObject,removeObject,moveObject = ,,
iconData
remote_blocklist = {}
nodes = nodes {}
addObject = (root)
nodes[root]
isNil =
rootParObj = (root,)
par = nodes[rootParObj]
par
nilMap[root]
nilCons[root] = nilCons[root] {
(root.ChildAdded,addObject),
(root.AncestryChanged,moveObject),
}
par = nilNode
isNil =
nilMap[rootParObj] par == nilNode
nilMap[root] =
nilCons[root] = nilCons[root] {
(root.ChildAdded,addObject),
(root.AncestryChanged,moveObject),
}
isNil =
newNode = {Obj = root, Parent = par}
nodes[root] = newNode
sortingEnabled expanded[par] par.Sorted
left,right = ,#par
floor = .floor
sorter = Explorer.NodeSorter
pos = (right == )
pos
left >= right
(newNode,par[left])
pos = left
pos = left+
mid = ((left+right)/)
(newNode,par[mid])
right = mid-
left = mid+
.(par,pos,newNode)
par[#par+] = newNode
par.Sorted =
insts = (root)
i = ,#insts
obj = insts[i]
nodes[obj]
par = nodes[(obj,)]
par
newNode = {Obj = obj, Parent = par}
nodes[obj] = newNode
par[#par+] = newNode
isNil
nilMap[obj] =
nilCons[obj] = nilCons[obj] {
(obj.ChildAdded,addObject),
(obj.AncestryChanged,moveObject),
}
searchFunc autoUpdateSearch
({newNode})
updateDebounce Explorer.(par)
expanded[par]
Explorer.()
refreshDebounce
Explorer.()
removeObject = (root)
node = nodes[root]
node
nilMap[node.Obj]
(node.Obj)
par = node.Parent
par
par.HasDel =
(root)
i = ,#root
node = root[i]
node.Del
nodes[node.Obj] =
#node > (node)
(node)
node.Del =
nodes[root] =
par updateDebounce Explorer.(par)
expanded[par]
Explorer.()
refreshDebounce
Explorer.()
moveObject = (obj)
node = nodes[obj]
node
oldPar = node.Parent
newPar = nodes[(obj,)]
oldPar == newPar
newPar
nilMap[obj]
newPar = nilNode
nilMap[newPar.Obj] newPar == nilNode
nilMap[obj] =
nilCons[obj] = nilCons[obj] {
(obj.ChildAdded,addObject),
(obj.AncestryChanged,moveObject),
}
oldPar
parPos = .(oldPar,node)
parPos .(oldPar,parPos)
node.Id =
node.Parent = newPar
sortingEnabled expanded[newPar] newPar.Sorted
left,right = ,#newPar
floor = .floor
sorter = Explorer.NodeSorter
pos = (right == )
pos
left >= right
(node,newPar[left])
pos = left
pos = left+
mid = ((left+right)/)
(node,newPar[mid])
right = mid-
left = mid+
.(newPar,pos,node)
newPar[#newPar+] = node
newPar.Sorted =
searchFunc searchResults[node]
currentNode = node.Parent
currentNode ( searchResults[currentNode] expanded[currentNode] == )
expanded[currentNode] =
searchResults[currentNode] =
currentNode = currentNode.Parent
updateDebounce (Explorer.(newPar) Explorer.(oldPar))
expanded[newPar] expanded[oldPar]
Explorer.()
refreshDebounce
Explorer.()
Explorer.ViewWidth =
Explorer.Index =
Explorer.EntryIndent =
Explorer.FreeWidth =
Explorer.GuiElems = {}
Explorer.InitRenameBox = ()
renameBox = ({{,,{BackgroundColor3=.(,,),BorderColor3=.(,,),BorderMode=,ClearTextOnFocus=,Font=,Name=,PlaceholderColor3=.(,,),Position=.(,,,),Size=.(,,,),Text=,TextColor3=.(,,),TextSize=,TextXAlignment=,Visible=,ZIndex=}}})
renameBox.Parent = Explorer.Window.GuiElems.Content.List
renameBox.FocusLost:(()
renamingNode
(() renamingNode.Obj.Name = renameBox.Text )
renamingNode =
Explorer.()
)
renameBox.Focused:(()
renameBox.SelectionStart =
renameBox.CursorPosition = #renameBox.Text +
)
Explorer.SetRenamingNode = (node)
renamingNode = node
renameBox.Text = (node.Obj)
renameBox:()
Explorer.()
Explorer.SetSortingEnabled = (val)
sortingEnabled = val
Settings.Explorer.Sorting = val
Explorer.UpdateView = ()
maxNodes = .(treeFrame.AbsoluteSize.Y / )
maxX = treeFrame.AbsoluteSize.X
totalWidth = Explorer.ViewWidth + Explorer.FreeWidth
scrollV.VisibleSpace = maxNodes
scrollV.TotalSpace = #tree +
scrollH.VisibleSpace = maxX
scrollH.TotalSpace = totalWidth
scrollV.Gui.Visible = #tree + > maxNodes
scrollH.Gui.Visible = totalWidth > maxX
oldSize = treeFrame.Size
treeFrame.Size = .(,(scrollV.Gui.Visible - ),,(scrollH.Gui.Visible - -))
oldSize ~= treeFrame.Size
Explorer.()
scrollV:()
scrollH:()
renameBox.Size = .(,maxX-,,)
scrollV.Gui.Visible scrollH.Gui.Visible
scrollV.Gui.Size = .(,,,-)
scrollH.Gui.Size = .(,-,,)
Explorer.Window.GuiElems.Content.ScrollCorner.Visible =
scrollV.Gui.Size = .(,,,-)
scrollH.Gui.Size = .(,,,)
Explorer.Window.GuiElems.Content.ScrollCorner.Visible =
Explorer.Index = scrollV.Index
Explorer.NodeSorter = (a,b)
a.Del b.Del
aClass = a.Class
bClass = b.Class
aClass aClass = a.Obj.ClassName a.Class = aClass
bClass bClass = b.Obj.ClassName b.Class = bClass
aOrder = explorerOrders[aClass]
bOrder = explorerOrders[bClass]
aOrder aOrder = RMD.Classes[aClass] (RMD.Classes[aClass].ExplorerOrder) explorerOrders[aClass] = aOrder
bOrder bOrder = RMD.Classes[bClass] (RMD.Classes[bClass].ExplorerOrder) explorerOrders[bClass] = bOrder
aOrder ~= bOrder
aOrder < bOrder
aName,bName = (a.Obj),(b.Obj)
aName ~= bName
aName < bName
aClass ~= bClass
aClass < bClass
aId = a.Id aId aId = idCounter idCounter = (idCounter+)% a.Id = aId
bId = b.Id bId bId = idCounter idCounter = (idCounter+)% b.Id = bId
aId < bId
Explorer.Update = ()
.(tree)
maxNameWidth,maxDepth,count = ,,
nameCache = {}
font = .Font.SourceSans
size = .(.huge,)
useNameWidth = Settings.Explorer.UseNameWidth
tSort = .sort
sortFunc = Explorer.NodeSorter
isSearching = (expanded == Explorer.SearchExpanded)
textServ = service.TextService
(root,depth)
depth > maxDepth maxDepth = depth
depth = depth +
sortingEnabled root.Sorted
(root,sortFunc)
root.Sorted =
i = ,#root
n = root[i]
(isSearching searchResults[n]) n.Del
useNameWidth
nameWidth = n.NameWidth
nameWidth
objName = (n.Obj)
nameWidth = nameCache[objName]
nameWidth
nameWidth = (textServ,objName,,font,size).X
nameCache[objName] = nameWidth
n.NameWidth = nameWidth
nameWidth > maxNameWidth
maxNameWidth = nameWidth
tree[count] = n
count = count +
expanded[n] #n >
(n,depth)
(nodes[],)
env.getnilinstances
(isSearching searchResults[nilNode])
tree[count] = nilNode
count = count +
expanded[nilNode]
(nilNode,)
Explorer.MaxNameWidth = maxNameWidth
Explorer.MaxDepth = maxDepth
Explorer.ViewWidth = useNameWidth Explorer.EntryIndent*maxDepth + maxNameWidth + Explorer.EntryIndent*maxDepth +
Explorer.()
Explorer.StartDrag = (offX,offY)
Explorer.Dragging
i,v , selection.List
Obj = v.Obj
Obj.Parent == Obj:()
Explorer.Dragging =
dragTree = treeFrame:()
dragTree:()
i,v (listEntries)
node = tree[i + Explorer.Index]
node selection.Map[node]
clone = v:()
clone.Active =
clone.Indent.Expand.Visible =
clone.Parent = dragTree
newGui = .()
newGui.DisplayOrder = Main.DisplayOrders.Menu
dragTree.Parent = newGui
Lib.(newGui)
dragOutline = ({
{,,{BackgroundColor3=.(,,),BackgroundTransparency=,Name=,Size=.(,,,),}},
{,,{BackgroundColor3=.(,,),BorderSizePixel=,Name=,Parent={},Size=.(,,,),ZIndex=,}},
{,,{BackgroundColor3=.(,,),BorderSizePixel=,Name=,Parent={},Position=.(,,,-),Size=.(,,,),ZIndex=,}},
{,,{BackgroundColor3=.(,,),BorderSizePixel=,Name=,Parent={},Size=.(,,,),ZIndex=,}},
{,,{BackgroundColor3=.(,,),BorderSizePixel=,Name=,Parent={},Position=.(,-,,),Size=.(,,,),ZIndex=,}},
})
dragOutline.Parent = treeFrame
mouse = Main.Mouse service.Players.LocalPlayer:()
()
posX = mouse.X - offX
posY = mouse.Y - offY
dragTree.Position = .(,posX,,posY)
i = ,#listEntries
entry = listEntries[i]
Lib.(entry)
dragOutline.Position = .(,entry.Indent.Position.X.Offset-scrollH.Index,,entry.Position.Y.Offset)
dragOutline.Size = .(,entry.Size.X.Offset-entry.Indent.Position.X.Offset,,)
dragOutline.Visible =
dragOutline.Visible =
()
input = service.UserInputService
mouseEvent,releaseEvent
mouseEvent = input.InputChanged:((input)
input.UserInputType == .UserInputType.MouseMovement input.UserInputType == .UserInputType.Touch
()
)
releaseEvent = input.InputEnded:((input)
input.UserInputType == .UserInputType.MouseButton1 input.UserInputType == .UserInputType.Touch
releaseEvent:()
mouseEvent:()
newGui:()
dragOutline:()
Explorer.Dragging =
i = ,#listEntries
Lib.(listEntries[i])
node = tree[i + Explorer.Index]
node
selection.Map[node]
newPar = node.Obj
sList = selection.List
i = ,#sList
n = sList[i]
(() n.Obj.Parent = newPar )
Explorer.(sList[])
)
Explorer.NewListEntry = (index)
newEntry = entryTemplate:()
newEntry.Position = .(,,,*(index-))
isRenaming =
newEntry.InputBegan:((input)
node = tree[index + Explorer.Index]
node selection.Map[node] (input.UserInputType ~= .UserInputType.MouseMovement input.UserInputType ~= .UserInputType.Touch)
newEntry.Indent.BackgroundColor3 = Settings.Theme.Button
newEntry.Indent.BorderSizePixel =
newEntry.Indent.BackgroundTransparency =
)
newEntry.InputEnded:((input)
node = tree[index + Explorer.Index]
node selection.Map[node] (input.UserInputType ~= .UserInputType.MouseMovement input.UserInputType ~= .UserInputType.Touch)
newEntry.Indent.BackgroundTransparency =
)
newEntry.MouseButton1Down:(()
)
newEntry.MouseButton1Up:(()
)
newEntry.InputBegan:((input)
input.UserInputType == .UserInputType.MouseButton1 input.UserInputType == .UserInputType.Touch
releaseEvent, mouseEvent
mouse = Main.Mouse plr:()
startX, startY
input.UserInputType == .UserInputType.Touch
startX = input.Position.X
startY = input.Position.Y
startX = mouse.X
startY = mouse.Y
listOffsetX = startX - treeFrame.AbsolutePosition.X
listOffsetY = startY - treeFrame.AbsolutePosition.Y
releaseEvent = service.UserInputService.InputEnded:((input)
input.UserInputType == .UserInputType.MouseButton1 input.UserInputType == .UserInputType.Touch
releaseEvent:()
mouseEvent:()
)
mouseEvent = service.UserInputService.InputChanged:((input)
input.UserInputType == .UserInputType.MouseMovement input.UserInputType == .UserInputType.Touch
currentX, currentY
input.UserInputType == .UserInputType.Touch
currentX = input.Position.X
currentY = input.Position.Y
currentX = mouse.X
currentY = mouse.Y
deltaX = currentX - startX
deltaY = currentY - startY
dist = .(deltaX^ + deltaY^)
dist >
releaseEvent:()
mouseEvent:()
isRenaming =
Explorer.(listOffsetX, listOffsetY)
)
)
newEntry.MouseButton2Down:(()
)
newEntry.Indent.Expand.InputBegan:((input)
node = tree[index + Explorer.Index]
node (input.UserInputType ~= .UserInputType.MouseMovement input.UserInputType ~= .UserInputType.Touch)
input.UserInputType == .UserInputType.Touch
Explorer.MiscIcons:(newEntry.Indent.Expand.Icon, expanded[node] )
input.UserInputType == .UserInputType.MouseMovement
Explorer.MiscIcons:(newEntry.Indent.Expand.Icon, expanded[node] )
)
newEntry.Indent.Expand.InputEnded:((input)
node = tree[index + Explorer.Index]
node (input.UserInputType ~= .UserInputType.MouseMovement input.UserInputType ~= .UserInputType.Touch)
input.UserInputType == .UserInputType.Touch
Explorer.MiscIcons:(newEntry.Indent.Expand.Icon, expanded[node] )
input.UserInputType == .UserInputType.MouseMovement
Explorer.MiscIcons:(newEntry.Indent.Expand.Icon, expanded[node] )
)
newEntry.Indent.Expand.MouseButton1Down:(()
node = tree[index + Explorer.Index]
node #node ==
expanded[node] = expanded[node]
Explorer.()
Explorer.()
)
newEntry.Parent = treeFrame
newEntry
Explorer.Refresh = ()
maxNodes = .(.((treeFrame.AbsoluteSize.Y) / ), )
renameNodeVisible =
isa = .IsA
i = ,maxNodes
entry = listEntries[i]
listEntries[i] entry = Explorer.(i) listEntries[i] = entry Explorer.ClickSystem:(entry)
node = tree[i + Explorer.Index]
node
obj = node.Obj
depth = Explorer.EntryIndent*Explorer.(node)
entry.Visible =
entry.Position = .(,-scrollH.Index,,entry.Position.Y.Offset)
entry.Size = .(,Explorer.ViewWidth,,)
entry.Indent.EntryName.Text = (node.Obj)
entry.Indent.Position = .(,depth,,)
entry.Indent.Size = .(,-depth,,)
entry.Indent.EntryName.TextTruncate = (Settings.Explorer.UseNameWidth .TextTruncate.None .TextTruncate.AtEnd)
Explorer.MiscIcons:(entry.Indent.Icon, obj.ClassName)
selection.Map[node]
entry.Indent.BackgroundColor3 = Settings.Theme.ListSelection
entry.Indent.BorderSizePixel =
entry.Indent.BackgroundTransparency =
Lib.(entry)
entry.Indent.BackgroundColor3 = Settings.Theme.Button
entry.Indent.BackgroundTransparency =
node == renamingNode
renameNodeVisible =
renameBox.Position = .(,depth+-scrollH.Index,,entry.Position.Y.Offset+)
renameBox.Visible =
#node > expanded[node] ~=
Lib.(entry.Indent.Expand)
Explorer.MiscIcons:(entry.Indent.Expand.Icon, expanded[node] )
Explorer.MiscIcons:(entry.Indent.Expand.Icon, expanded[node] )
entry.Indent.Expand.Visible =
entry.Indent.Expand.Visible =
entry.Visible =
renameNodeVisible
renameBox.Visible =
i = maxNodes+, #listEntries
Explorer.ClickSystem:(listEntries[i])
listEntries[i]:()
listEntries[i] =
Explorer.PerformUpdate = (instant)
updateDebounce =
Lib.( instant )
updateDebounce
updateDebounce =
Explorer.Window:()
Explorer.()
Explorer.()
Explorer.ForceUpdate = (norefresh)
updateDebounce =
Explorer.()
norefresh Explorer.()
Explorer.PerformRefresh = ()
refreshDebounce =
Lib.()
refreshDebounce =
updateDebounce Explorer.Window:()
Explorer.()
Explorer.IsNodeVisible = (node)
node
curNode = node.Parent
curNode
expanded[curNode]
curNode = curNode.Parent
Explorer.NodeDepth = (node)
depth =
node == nilNode
curNode = node.Parent
curNode
curNode == nilNode depth = depth +
curNode = curNode.Parent
depth = depth +
depth
Explorer.SetupConnections = ()
descendantAddedCon descendantAddedCon:()
descendantRemovingCon descendantRemovingCon:()
itemChangedCon itemChangedCon:()
Main.Elevated
descendantAddedCon = .DescendantAdded:(addObject)
descendantRemovingCon = .DescendantRemoving:(removeObject)
descendantAddedCon = .DescendantAdded:((obj) (addObject,obj) )
descendantRemovingCon = .DescendantRemoving:((obj) (removeObject,obj) )
Settings.Explorer.UseNameWidth
itemChangedCon = .ItemChanged:((obj,prop)
prop == nodes[obj]
(obj)
prop == nodes[obj]
nodes[obj].NameWidth =
)
itemChangedCon = .ItemChanged:((obj,prop)
prop == nodes[obj]
(obj)
)
Explorer.ViewNode = (node)
node
Explorer.(node)
Explorer.()
visibleSpace = scrollV.VisibleSpace
i,v ,tree
v == node
relative = i -
Explorer.Index > relative
scrollV.Index = relative
Explorer.Index + visibleSpace - <= relative
scrollV.Index = relative - visibleSpace +
scrollV:() Explorer.Index = scrollV.Index
Explorer.()
Explorer.ViewObj = (obj)
Explorer.(nodes[obj])
Explorer.MakeNodeVisible = (node,expandRoot)
node
hasExpanded =
expandRoot expanded[node]
expanded[node] =
hasExpanded =
currentNode = node.Parent
currentNode
hasExpanded =
expanded[currentNode] =
currentNode = currentNode.Parent
hasExpanded updateDebounce
.(Explorer.PerformUpdate)()
Explorer.ShowRightClick = (MousePos)
Mouse = MousePos Main.Mouse
context = Explorer.RightClickContext
absoluteSize = context.Gui.AbsoluteSize
context.MaxHeight = (absoluteSize.Y <= (absoluteSize.Y - ))
context:()
sList = selection.List
sMap = selection.Map
emptyClipboard = #clipboard ==
presentClasses = {}
apiClasses = API.Classes
i = , #sList
node = sList[i]
class = node.Class
obj = node.Obj
presentClasses.isViableDecompileScript
presentClasses.isViableDecompileScript = env.(obj)
class
class = obj.ClassName
node.Class = class
curClass = apiClasses[class]
curClass presentClasses[curClass.Name]
presentClasses[curClass.Name] =
curClass = curClass.Superclass
context:()
context:()
context:(, emptyClipboard)
context:()
context:()
context:(, #sList ~= )
context:(, #sList ~= )
context:()
context:()
context:()
context:()
context:()
context:()
context:()
context:()
expanded == Explorer.SearchExpanded context:()
env.setclipboard context:()
context:()
context:()
context:()
context:()
presentClasses[] presentClasses[]
context:()
context:()
context:()
presentClasses[] context:()
presentClasses[]
context:()
context:()
presentClasses[] context:(, == )
presentClasses[] context:(, == )
presentClasses[] context:(, == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:(, env.hookfunction == )
presentClasses[] context:()context:()
presentClasses[]
context:()
context:()
presentClasses[]
context:(, presentClasses.isViableDecompileScript env.isdecompile)
context:(, presentClasses.isViableDecompileScript env.getupvalues == env.getconstants == )
context:(, presentClasses.isViableDecompileScript env.isdecompile env.writefile == )
context:(, presentClasses.isViableDecompileScript env.getscriptbytecode == env.writefile == )
sMap[nilNode]
context:()
context:()
Explorer.LastRightClickX, Explorer.LastRightClickY = Mouse.X, Mouse.Y
context:(Mouse.X, Mouse.Y)
Explorer.InitRightClick = ()
context = Lib.ContextMenu.()
context:(,{Name = , IconMap = Explorer.MiscIcons, Icon = , DisabledIcon = , Shortcut = , OnClick = ()
destroy,clone = .Destroy,.Clone
sList,newClipboard = selection.List,{}
count =
i = ,#sList
inst = sList[i].Obj
s,cloned = (clone,inst)
s cloned
newClipboard[count] = cloned
count = count +
(destroy,inst)
clipboard = newClipboard
selection:()
})
context:(,{Name = , IconMap = Explorer.MiscIcons, Icon = , DisabledIcon = , Shortcut = , OnClick = ()
clone = .Clone
sList,newClipboard = selection.List,{}
count =
i = ,#sList
inst = sList[i].Obj
s,cloned = (clone,inst)
s cloned
newClipboard[count] = cloned
count = count +
clipboard = newClipboard
})
context:(,{Name = , IconMap = Explorer.MiscIcons, Icon = , DisabledIcon = , Shortcut = , OnClick = ()
sList = selection.List
newSelection = {}
count =
i = ,#sList
node = sList[i]
inst = node.Obj
Explorer.(node,)
c = ,#clipboard
cloned = clipboard[c]:()
cloned
cloned.Parent = inst
clonedNode = nodes[cloned]
clonedNode newSelection[count] = clonedNode count = count +
selection:(newSelection)
#newSelection >
Explorer.(newSelection[])
})
context:(,{Name = plicate", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+D", OnClick = function()
local clone = game.Clone
local sList = selection.List
local newSelection = {}
local count = 1
for i = 1,#sList do
local node = sList[i]
local inst = node.Obj
local instPar = node.Parent and node.Parent.Obj
Explorer.MakeNodeVisible(node)
local s,cloned = pcall(clone,inst)
if s and cloned then
cloned.Parent = instPar
local clonedNode = nodes[cloned]
if clonedNode then newSelection[count] = clonedNode count = count + 1 end
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
end
end})
context:Register("DELETE",{Name = "Delete", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Delete_Disabled", Shortcut = "Del", OnClick = function()
local destroy = game.Destroy
local sList = selection.List
for i = 1,#sList do
pcall(destroy,sList[i].Obj)
end
selection:Clear()
end})
context:Register("DELETE_CHILDREN",{Name = "Delete Children", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Delete_Disabled", Shortcut = "Shift+Del", OnClick = function()
local sList = selection.List
for i = 1,#sList do
pcall(sList[i].Obj.ClearAllChildren,sList[i].Obj)
end
selection:Clear()
end})
context:Register("RENAME",{Name = "Rename", IconMap = Explorer.MiscIcons, Icon = "Rename", DisabledIcon = "Rename_Disabled", Shortcut = "F2", OnClick = function()
local sList = selection.List
if sList[1] then
Explorer.SetRenamingNode(sList[1])
end
end})
context:Register("GROUP",{Name = "Group", IconMap = Explorer.MiscIcons, Icon = "Group", DisabledIcon = "Group_Disabled", Shortcut = "Ctrl+G", OnClick = function()
local sList = selection.List
if #sList == 0 then return end
local model = Instance.new("Model",sList[#sList].Obj.Parent)
for i = 1,#sList do
pcall(function() sList[i].Obj.Parent = model end)
end
if nodes[model] then
selection:Set(nodes[model])
Explorer.ViewNode(nodes[model])
end
end})
context:Register("UNGROUP",{Name = "Ungroup", IconMap = Explorer.MiscIcons, Icon = "Ungroup", DisabledIcon = "Ungroup_Disabled", Shortcut = "Ctrl+U", OnClick = function()
local newSelection = {}
local count = 1
local isa = game.IsA
local function ungroup(node)
local par = node.Parent.Obj
local ch = {}
local chCount = 1
for i = 1,#node do
local n = node[i]
newSelection[count] = n
ch[chCount] = n
count = count + 1
chCount = chCount + 1
end
for i = 1,#ch do
pcall(function() ch[i].Obj.Parent = par end)
end
node.Obj:Destroy()
end
for i,v in next,selection.List do
if isa(v.Obj,"Model") then
ungroup(v)
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
end
end})
context:Register("SELECT_CHILDREN",{Name = "Select Children", IconMap = Explorer.MiscIcons, Icon = "SelectChildren", DisabledIcon = "SelectChildren_Disabled", OnClick = function()
local newSelection = {}
local count = 1
local sList = selection.List
for i = 1,#sList do
local node = sList[i]
for ind = 1,#node do
local cNode = node[ind]
if ind == 1 then Explorer.MakeNodeVisible(cNode) end
newSelection[count] = cNode
count = count + 1
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
else
Explorer.Refresh()
end
end})
context:Register("JUMP_TO_PARENT",{Name = "Jump to Parent", IconMap = Explorer.MiscIcons, Icon = "JumpToParent", OnClick = function()
local newSelection = {}
local count = 1
local sList = selection.List
for i = 1,#sList do
local node = sList[i]
if node.Parent then
newSelection[count] = node.Parent
count = count + 1
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
else
Explorer.Refresh()
end
end})
context:Register("TELEPORT_TO",{Name = "Teleport To", IconMap = Explorer.MiscIcons, Icon = "TeleportTo", OnClick = function()
local sList = selection.List
local plrRP = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
if not plrRP then return end
for _,node in next, sList do
local Obj = node.Obj
if Obj:IsA("BasePart") then
if Obj.CanCollide then
plr.Character:MoveTo(Obj.Position)
else
plrRP.CFrame = CFrame.new(Obj.Position + Settings.Explorer.TeleportToOffset)
end
break
elseif Obj:IsA("Model") then
if Obj.PrimaryPart then
if Obj.PrimaryPart.CanCollide then
plr.Character:MoveTo(Obj.PrimaryPart.Position)
else
plrRP.CFrame = CFrame.new(Obj.PrimaryPart.Position + Settings.Explorer.TeleportToOffset)
end
break
else
local part = Obj:FindFirstChildWhichIsA("BasePart", true)
if part and nodes[part] then
if part.CanCollide then
plr.Character:MoveTo(part.Position)
else
plrRP.CFrame = CFrame.new(part.Position + Settings.Explorer.TeleportToOffset)
end
break
elseif Obj.WorldPivot then
plrRP.CFrame = Obj.WorldPivot
end
end
end
end
end})
local OldAnimation
context:Register("PLAY_TWEEN",{Name = "Play Tween", IconMap = Explorer.MiscIcons, Icon = "Play", OnClick = function()
local sList = selection.List
for i = 1, #sList do
local node = sList[i]
local Obj = node.Obj
if Obj:IsA("Tween") then Obj:Play() end
end
end})
local OldAnimation
context:Register("LOAD_ANIMATION",{Name = "Load Animation", IconMap = Explorer.MiscIcons, Icon = "Play", OnClick = function()
local sList = selection.List
local Humanoid = plr.Character and plr.Character:FindFirstChild("Humanoid")
if not Humanoid then return end
for i = 1, #sList do
local node = sList[i]
local Obj = node.Obj
if Obj:IsA("Animation") then
if OldAnimation then OldAnimation:Stop() end
OldAnimation = Humanoid:LoadAnimation(Obj)
OldAnimation:Play()
break
end
end
end})
context:Register("STOP_ANIMATION",{Name = "Stop Animation", IconMap = Explorer.MiscIcons, Icon = "Pause", OnClick = function()
local sList = selection.List
local Humanoid = plr.Character and plr.Character:FindFirstChild("Humanoid")
if not Humanoid then return end
for i = 1, #sList do
local node = sList[i]
local Obj = node.Obj
if Obj:IsA("Animation") then
if OldAnimation then OldAnimation:Stop() end
Humanoid:LoadAnimation(Obj):Stop()
break
end
end
end})
context:Register("EXPAND_ALL",{Name = "Expand All", OnClick = function()
local sList = selection.List
local function expand(node)
expanded[node] = true
for i = 1,#node do
if #node[i] > 0 then
expand(node[i])
end
end
end
for i = 1,#sList do
expand(sList[i])
end
Explorer.ForceUpdate()
end})
context:Register("COLLAPSE_ALL",{Name = "Collapse All", OnClick = function()
local sList = selection.List
local function expand(node)
expanded[node] = nil
for i = 1,#node do
if #node[i] > 0 then
expand(node[i])
end
end
end
for i = 1,#sList do
expand(sList[i])
end
Explorer.ForceUpdate()
end})
context:Register("CLEAR_SEARCH_AND_JUMP_TO",{Name = "Clear Search and Jump to", OnClick = function()
local newSelection = {}
local count = 1
local sList = selection.List
for i = 1,#sList do
newSelection[count] = sList[i]
count = count + 1
end
selection:SetTable(newSelection)
Explorer.ClearSearch()
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
end
end})
-- this code is very bad but im lazy and it works so cope
local clth = function(str)
if str:sub(1, 28) == "game:GetService(\"Workspace\")" then str = str:gsub("game:GetService%(\"Workspace\"%)", "workspace", 1) end
if str:sub(1, 27 + #plr.Name) == "game:GetService(\"Players\")." .. plr.Name then str = str:gsub("game:GetService%(\"Players\"%)." .. plr.Name, "game:GetService(\"Players\").LocalPlayer", 1) end
return str
end
context:Register("COPY_PATH",{Name = "Copy Path", IconMap = Explorer.LegacyClassIcons, Icon = 50, OnClick = function()
local sList = selection.List
if #sList == 1 then
env.setclipboard(clth(Explorer.GetInstancePath(sList[1].Obj)))
elseif #sList > 1 then
local resList = {"{"}
local count = 2
for i = 1,#sList do
local path = "\t"..clth(Explorer.GetInstancePath(sList[i].Obj))..","
if #path > 0 then
resList[count] = path
count = count+1
end
end
resList[count] = "}"
env.setclipboard(table.concat(resList,"\n"))
end
end})
context:Register("INSERT_OBJECT",{Name = "Insert Object", IconMap = Explorer.MiscIcons, Icon = "InsertObject", OnClick = function()
local mouse = Main.Mouse
local x,y = Explorer.LastRightClickX or mouse.X, Explorer.LastRightClickY or mouse.Y
Explorer.InsertObjectContext:Show(x,y)
end})
--[[context:Register("CALL_FUNCTION",{Name = "Call Function", IconMap = Explorer.ClassIcons, Icon = 66, OnClick = function()
end})
context:Register("GET_REFERENCES",{Name = "Get Lua References", IconMap = Explorer.ClassIcons, Icon = 34, OnClick = function()
end})]]
context:Register("SAVE_INST",{Name = "Save to File", IconMap = Explorer.MiscIcons, Icon = "Save", OnClick = function()
local sList = selection.List
if #sList == 1 then
Lib.SaveAsPrompt("Place_"..game.PlaceId.."_"..sList[1].Obj.ClassName.."_"..sList[1].Obj.Name.."_"..os.time(), function(filename)
env.saveinstance(sList[1].Obj, filename, {
Decompile = true,
RemovePlayerCharacters = false
})
end)
elseif #sList > 1 then
for i = 1,#sList do
-- sList[i].Obj.Name.." ("..sList[1].Obj.ClassName..")"
-- "Place_"..game.PlaceId.."_"..sList[1].Obj.ClassName.."_"..sList[i].Obj.Name.."_"..os.time()
Lib.SaveAsPrompt("Place_"..game.PlaceId.."_"..sList[i].Obj.ClassName.."_"..sList[i].Obj.Name.."_"..os.time(), function(filename)
env.saveinstance(sList[i].Obj, filename, {
Decompile = true,
RemovePlayerCharacters = false
})
end)
task.wait(0.1)
end
end
end})
--[[context:Register("VIEW_CONNECTIONS",{Name = "View Connections", OnClick = function()
end})]]
local ClassFire = {
RemoteEvent = "FireServer",
RemoteFunction = "InvokeServer",
UnreliableRemoteEvent = "FireServer",
BindableRemote = "Fire",
BindableFunction = "Invoke",
}
context:Register("BLOCK_REMOTE",{Name = "Block From Firing", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Empty", OnClick = function()
local sList = selection.List
for i, list in sList do
local obj = list.Obj
if not remote_blocklist[obj] then
local functionToHook = ClassFire[obj.ClassName]
remote_blocklist[obj] = true
local old; old = env.hookmetamethod((oldgame or game), "__namecall", function(self, ...)
if remote_blocklist[obj] and self == obj and getnamecallmethod() == functionToHook then
return nil
end
return old(self,...)
end)
if Settings.RemoteBlockWriteAttribute then
obj:SetAttribute("IsBlocked", true)
end
--print("blocking ",functionToHook)
end
end
end})
context:Register("UNBLOCK_REMOTE",{Name = "Unblock", IconMap = Explorer.MiscIcons, Icon = "Play", DisabledIcon = "Empty", OnClick = function()
local sList = selection.List
for i, list in sList do
local obj = list.Obj
if remote_blocklist[obj] then
remote_blocklist[obj] = nil
if Settings.RemoteBlockWriteAttribute then
list.Obj:SetAttribute("IsBlocked", false)
end
--print("unblocking ",functionToHook)
end
end
end})
context:Register("COPY_API_PAGE",{Name = "Copy Roblox API Page URL", IconMap = Explorer.MiscIcons, Icon = "Reference", OnClick = function()
local sList = selection.List
if #sList == 1 then
env.setclipboard(
"https://create.roblox.com/docs/reference/engine/classes/"..sList[1].Obj.ClassName
)
end
end})
context:Register("3DVIEW_MODEL",{Name = "3D Preview Object", IconMap = Explorer.LegacyClassIcons, Icon = 54, OnClick = function()
local sList = selection.List
local isa = game.IsA
if #sList == 1 then
if isa(sList[1].Obj,"BasePart") or isa(sList[1].Obj,"Model") then
ModelViewer.ViewModel(sList[1].Obj)
return
end
end
end})
context:Register("VIEW_OBJECT",{Name = "View Object (Right click to reset)", IconMap = Explorer.LegacyClassIcons, Icon = 5, OnClick = function()
local sList = selection.List
local isa = game.IsA
for i = 1,#sList do
local node = sList[i]
if isa(node.Obj,"BasePart") or isa(node.Obj,"Model") then
workspace.CurrentCamera.CameraSubject = node.Obj
break
end
end
end, OnRightClick = function()
workspace.CurrentCamera.CameraSubject = plr.Character
end})
context:Register("VIEW_SCRIPT",{Name = "View Script", IconMap = Explorer.MiscIcons, Icon = "ViewScript", DisabledIcon = "Empty", OnClick = function()
local scr = selection.List[1] and selection.List[1].Obj
if scr then ScriptViewer.ViewScript(scr) end
end})
context:Register("DUMP_FUNCTIONS",{Name = "Dump Functions", IconMap = Explorer.MiscIcons, Icon = "SelectChildren", DisabledIcon = "Empty", OnClick = function()
local scr = selection.List[1] and selection.List[1].Obj
if scr then ScriptViewer.DumpFunctions(scr) end
end})
context:Register("FIRE_TOUCHTRANSMITTER",{Name = "Fire TouchTransmitter", OnClick = function()
local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("TouchTransmitter") then firetouchinterest(hrp, v.Obj.Parent, 0) end end
end})
context:Register("FIRE_CLICKDETECTOR",{Name = "Fire ClickDetector", OnClick = function()
local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ClickDetector") then fireclickdetector(v.Obj) end end
end})
context:Register("FIRE_PROXIMITYPROMPT",{Name = "Fire ProximityPrompt", OnClick = function()
local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ProximityPrompt") then fireproximityprompt(v.Obj) end end
end})
context:Register("VIEW_SCRIPT",{Name = "View Script", IconMap = Explorer.MiscIcons, Icon = "ViewScript", DisabledIcon = "Empty", OnClick = function()
local scr = selection.List[1] and selection.List[1].Obj
if scr then ScriptViewer.ViewScript(scr) end
end})
context:Register("SAVE_SCRIPT",{Name = "Save Script", IconMap = Explorer.MiscIcons, Icon = "Save", DisabledIcon = "Empty", OnClick = function()
for _, v in next, selection.List do
if v.Obj:IsA("LuaSourceContainer") and env.isViableDecompileScript(v.Obj) then
local success, source = pcall(env.decompile, v.Obj)
if not success or not source then source = ("-- DEX - %s failed to decompile %s"):format(env.executor, v.Obj.ClassName) end
local fileName = ("%s_%s_%i_Source.txt"):format(env.parsefile(v.Obj.Name), v.Obj.ClassName, game.PlaceId)
--env.writefile(fileName, source)
Lib.SaveAsPrompt(fileName, source)
task.wait(0.2)
end
end
end})
context:Register("SAVE_BYTECODE",{Name = "Save Script Bytecode", IconMap = Explorer.MiscIcons, Icon = "Save", DisabledIcon = "Empty", OnClick = function()
for _, v in next, selection.List do
if v.Obj:IsA("LuaSourceContainer") and env.isViableDecompileScript(v.Obj) then
local success, bytecode = pcall(env.getscriptbytecode, v.Obj)
if success and type(bytecode) == "string" then
local fileName = ("%s_%s_%i_Bytecode.txt"):format(env.parsefile(v.Obj.Name), v.Obj.ClassName, game.PlaceId)
--env.writefile(fileName, bytecode)
Lib.SaveAsPrompt(fileName, bytecode)
task.wait(0.2)
end
end
end
end})
context:Register("SELECT_CHARACTER",{Name = "Select Character", IconMap = Explorer.LegacyClassIcons, Icon = 9, OnClick = function()
local newSelection = {}
local count = 1
local sList = selection.List
local isa = game.IsA
for i = 1,#sList do
local node = sList[i]
if isa(node.Obj,"Player") and nodes[node.Obj.Character] then
newSelection[count] = nodes[node.Obj.Character]
count = count + 1
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
else
Explorer.Refresh()
end
end})
context:Register("VIEW_PLAYER",{Name = "View Player", IconMap = Explorer.LegacyClassIcons, Icon = 5, OnClick = function()
local newSelection = {}
local count = 1
local sList = selection.List
local isa = game.IsA
for i = 1,#sList do
local node = sList[i]
local Obj = node.Obj
if Obj:IsA("Player") and Obj.Character then
workspace.CurrentCamera.CameraSubject = Obj.Character
break
end
end
end})
context:Register("SELECT_LOCAL_PLAYER",{Name = "Select Local Player", IconMap = Explorer.LegacyClassIcons, Icon = 9, OnClick = function()
pcall(function() if nodes[plr] then selection:Set(nodes[plr]) Explorer.ViewNode(nodes[plr]) end end)
end})
context:Register("SELECT_ALL_CHARACTERS",{Name = "Select All Characters", IconMap = Explorer.LegacyClassIcons, Icon = 2, OnClick = function()
local newSelection = {}
local sList = selection.List
for i,v in next, service.Players:GetPlayers() do
if v.Character and nodes[v.Character] then
if i == 1 then Explorer.MakeNodeVisible(v.Character) end
table.insert(newSelection, nodes[v.Character])
end
end
selection:SetTable(newSelection)
if #newSelection > 0 then
Explorer.ViewNode(newSelection[1])
else
Explorer.Refresh()
end
end})
context:Register("REFRESH_NIL",{Name = "Refresh Nil Instances", OnClick = function()
Explorer.RefreshNilInstances()
end})
context:Register("HIDE_NIL",{Name = "Hide Nil Instances", OnClick = function()
Explorer.HideNilInstances()
end})
Explorer.RightClickContext = context
end
Explorer.HideNilInstances = function()
table.clear(nilMap)
local disconnectCon = Instance.new("Folder").ChildAdded:Connect(function() end).Disconnect
for i,v in next,nilCons do
disconnectCon(v[1])
disconnectCon(v[2])
end
table.clear(nilCons)
for i = 1,#nilNode do
coroutine.wrap(removeObject)(nilNode[i].Obj)
end
Explorer.Update()
Explorer.Refresh()
end
Explorer.RefreshNilInstances = function()
if not env.getnilinstances then return end
local nilInsts = env.getnilinstances()
local game = game
local getDescs = game.GetDescendants
--local newNilMap = {}
--local newNilRoots = {}
--local nilRoots = Explorer.NilRoots
--local connect = game.DescendantAdded.Connect
--local disconnect
--if not nilRoots then nilRoots = {} Explorer.NilRoots = nilRoots end
for i = 1,#nilInsts do
local obj = nilInsts[i]
if obj ~= game then
nilMap[obj] = true
--newNilRoots[obj] = true
local descs = getDescs(obj)
for j = 1,#descs do
nilMap[descs[j]] = true
end
end
end
-- Remove unmapped nil nodes
--[[for i = 1,#nilNode do
local node = nilNode[i]
if not newNilMap[node.Obj] then
nilMap[node.Obj] = nil
coroutine.wrap(removeObject)(node)
end
end]]
--nilMap = newNilMap
for i = 1,#nilInsts do
local obj = nilInsts[i]
local node = nodes[obj]
if not node then coroutine.wrap(addObject)(obj) end
end
--[[
-- Remove old root connections
for obj in next,nilRoots do
if not newNilRoots[obj] then
if not disconnect then disconnect = obj[1].Disconnect end
disconnect(obj[1])
disconnect(obj[2])
end
end
for obj in next,newNilRoots do
if not nilRoots[obj] then
nilRoots[obj] = {
connect(obj.DescendantAdded,addObject),
connect(obj.DescendantRemoving,removeObject)
}
end
end]]
--nilMap = newNilMap
--Explorer.NilRoots = newNilRoots
Explorer.Update()
Explorer.Refresh()
end
Explorer.GetInstancePath = function(obj)
local ffc = game.FindFirstChild
local getCh = game.GetChildren
local path = ""
local curObj = obj
local ts = tostring
local match = string.match
local gsub = string.gsub
local tableFind = table.find
local useGetCh = Settings.Explorer.CopyPathUseGetChildren
local formatLuaString = Lib.FormatLuaString
while curObj do
if curObj == game then
path = "game"..path
break
end
local className = curObj.ClassName
local curName = ts(curObj)
local indexName
if match(curName,"^[%a_][%w_]*$") then
indexName = "."..curName
else
local cleanName = formatLuaString(curName)
indexName = '["'..cleanName..'"]'
end
local parObj = curObj.Parent
if parObj then
local fc = ffc(parObj,curName)
if useGetCh and fc and fc ~= curObj then
local parCh = getCh(parObj)
local fcInd = tableFind(parCh,curObj)
indexName = ":GetChildren()["..fcInd.."]"
elseif parObj == game and API.Classes[className] and API.Classes[className].Tags.Service then
indexName = ':GetService("'..className..'")'
end
elseif parObj == nil then
local getnil = "local getNil = function(name, class) for _, v in next, getnilinstances() do if v.ClassName == class and v.Name == name then return v end end end"
local gotnil = "\n\ngetNil(\"%s\", \"%s\")"
indexName = getnil .. gotnil:format(curObj.Name, className)
end
path = indexName..path
curObj = parObj
end
return path
end
Explorer.DefaultProps = {
["BasePart"] = {
Position = function(Obj)
local Player = service.Players.LocalPlayer
if Player.Character and Player.Character:FindFirstChild("HumanoidRootPart") then
Obj.Position = (Player.Character.HumanoidRootPart.CFrame * CFrame.new(0, 0, -10)).p
end
return Obj.Position
end,
Anchored = true
},
["GuiObject"] = {
Position = function(Obj) return (Obj.Parent:IsA("ScreenGui") and UDim2.new(0.5, 0, 0.5, 0)) or Obj.Position end,
Active = true
}
}
Explorer.InitInsertObject = function()
local context = Lib.ContextMenu.new()
context.SearchEnabled = true
context.MaxHeight = 400
context:ApplyTheme({
ContentColor = Settings.Theme.Main2,
OutlineColor = Settings.Theme.Outline1,
DividerColor = Settings.Theme.Outline1,
TextColor = Settings.Theme.Text,
HighlightColor = Settings.Theme.ButtonHover
})
local classes = {}
for i,class in next,API.Classes do
local tags = class.Tags
if not tags.NotCreatable and not tags.Service then
local rmdEntry = RMD.Classes[class.Name]
classes[#classes+1] = {class,rmdEntry and rmdEntry.ClassCategory or "Uncategorized"}
end
end
table.sort(classes,function(a,b)
if a[2] ~= b[2] then
return a[2] < b[2]
else
return a[1].Name < b[1].Name
end
end)
local function defaultProps(obj)
for class, props in pairs(Explorer.DefaultProps) do
if obj:IsA(class) then
for prop, value in pairs(props) do
obj[prop] = (type(value) == "function" and value(obj)) or value
end
end
end
end
local function onClick(className)
local sList = selection.List
local instNew = Instance.new
for i = 1,#sList do
local node = sList[i]
local obj = node.Obj
Explorer.MakeNodeVisible(node, true)
local success, obj = pcall(instNew, className, obj)
if success and obj then defaultProps(obj) end
end
end
local lastCategory = ""
for i = 1,#classes do
local class = classes[i][1]
local rmdEntry = RMD.Classes[class.Name]
local iconInd = rmdEntry and tonumber(rmdEntry.ExplorerImageIndex) or 0
local category = classes[i][2]
if lastCategory ~= category then
context:AddDivider(category)
lastCategory = category
end
local icon
if iconData then
icon = iconData.Icons[class.Name] or iconData.Icons.Placeholder
else
icon = iconInd
end
context:Add({Name = class.Name, IconMap = Explorer.ClassIcons, Icon = icon, OnClick = onClick})
end
Explorer.InsertObjectContext = context
end
--[[
Headers, Setups, Predicate, ObjectDefs
]]
Explorer.SearchFilters = { -- TODO: Use data table (so we can disable some if funcs don't exist)
Comparison = {
["isa"] = function(argString)
local lower = string.lower
local find = string.find
local classQuery = string.split(argString)[1]
if not classQuery then return end
classQuery = lower(classQuery)
local className
for class,_ in pairs(API.Classes) do
local cName = lower(class)
if cName == classQuery then
className = class
break
elseif find(cName,classQuery,1,true) then
className = class
end
end
if not className then return end
return {
Headers = {"local isa = game.IsA"},
Predicate = "isa(obj,'"..className.."')"
}
end,
["remotes"] = function(argString)
return {
Headers = {"local isa = game.IsA"},
Predicate = "isa(obj,'RemoteEvent') or isa(obj,'RemoteFunction') or isa(obj,'UnreliableRemoteEvent')"
}
end,
["bindables"] = function(argString)
return {
Headers = {"local isa = game.IsA"},
Predicate = "isa(obj,'BindableEvent') or isa(obj,'BindableFunction')"
}
end,
["rad"] = function(argString)
local num = tonumber(argString)
if not num then return end
if not service.Players.LocalPlayer.Character or not service.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") or not service.Players.LocalPlayer.Character.HumanoidRootPart:IsA("BasePart") then return end
return {
Headers = {"local isa = game.IsA", "local hrp = service.Players.LocalPlayer.Character.HumanoidRootPart"},
Setups = {"local hrpPos = hrp.Position"},
ObjectDefs = {"local isBasePart = isa(obj,'BasePart')"},
Predicate = "(isBasePart and (obj.Position-hrpPos).Magnitude <= "..num..")"
}
end,
},
Specific = {
["players"] = function()
return function() return service.Players:GetPlayers() end
end,
["loadedmodules"] = function()
return env.getloadedmodules
end,
},
Default = function(argString,caseSensitive)
local cleanString = argString:gsub("\"","\\\""):gsub("\n","\\n")
if caseSensitive then
return {
Headers = {"local find = string.find"},
ObjectDefs = {"local objName = tostring(obj)"},
Predicate = "find(objName,\"" .. cleanString .. "\",1,true)"
}
else
return {
Headers = {"local lower = string.lower","local find = string.find","local tostring = tostring"},
ObjectDefs = {"local lowerName = lower(tostring(obj))"},
Predicate = "find(lowerName,\"" .. cleanString:lower() .. "\",1,true)"
}
end
end,
SpecificDefault = function(n)
return {
Headers = {},
ObjectDefs = {"local isSpec"..n.." = specResults["..n.."][node]"},
Predicate = "isSpec"..n
}
end,
}
Explorer.BuildSearchFunc = function(query)
local specFilterList,specMap = {},{}
local finalPredicate = ""
local rep = string.rep
local formatQuery = query:gsub("\\."," "):gsub('".-"',function(str) return rep(" ",#str) end)
local headers = {}
local objectDefs = {}
local setups = {}
local find = string.find
local sub = string.sub
local lower = string.lower
local match = string.match
local ops = {
["("] = "(",
[")"] = ")",
["||"] = " or ",
["&&"] = " and "
}
local filterCount = 0
local compFilters = Explorer.SearchFilters.Comparison
local specFilters = Explorer.SearchFilters.Specific
local init = 1
local lastOp = nil
local function processFilter(dat)
if dat.Headers then
local t = dat.Headers
for i = 1,#t do
headers[t[i]] = true
end
end
if dat.ObjectDefs then
local t = dat.ObjectDefs
for i = 1,#t do
objectDefs[t[i]] = true
end
end
if dat.Setups then
local t = dat.Setups
for i = 1,#t do
setups[t[i]] = true
end
end
finalPredicate = finalPredicate..dat.Predicate
end
local found = {}
local foundData = {}
local find = string.find
local sub = string.sub
local function findAll(str,pattern)
local count = #found+1
local init = 1
local sz = #pattern
local x,y,extra = find(str,pattern,init,true)
while x do
found[count] = x
foundData[x] = {sz,pattern}
count = count+1
init = y+1
x,y,extra = find(str,pattern,init,true)
end
end
local start = tick()
findAll(formatQuery,'&&')
findAll(formatQuery,"||")
findAll(formatQuery,"(")
findAll(formatQuery,")")
table.sort(found)
table.insert(found,#formatQuery+1)
local function inQuotes(str)
local len = #str
if sub(str,1,1) == '"' and sub(str,len,len) == '"' then
return sub(str,2,len-1)
end
end
for i = 1,#found do
local nextInd = found[i]
local nextData = foundData[nextInd] or {1}
local op = ops[nextData[2]]
local term = sub(query,init,nextInd-1)
term = match(term,"^%s*(.-)%s*$") or "" -- Trim
if #term > 0 then
if sub(term,1,1) == "!" then
term = sub(term,2)
finalPredicate = finalPredicate.."not "
end
local qTerm = inQuotes(term)
if qTerm then
processFilter(Explorer.SearchFilters.Default(qTerm,true))
else
local x,y = find(term,"%S+")
if x then
local first = sub(term,x,y)
local specifier = sub(first,1,1) == "/" and lower(sub(first,2))
local compFunc = specifier and compFilters[specifier]
local specFunc = specifier and specFilters[specifier]
if compFunc then
local argStr = sub(term,y+2)
local ret = compFunc(inQuotes(argStr) or argStr)
if ret then
processFilter(ret)
else
finalPredicate = finalPredicate.."false"
end
elseif specFunc then
local argStr = sub(term,y+2)
local ret = specFunc(inQuotes(argStr) or argStr)
if ret then
if not specMap[term] then
specFilterList[#specFilterList + 1] = ret
specMap[term] = #specFilterList
end
processFilter(Explorer.SearchFilters.SpecificDefault(specMap[term]))
else
finalPredicate = finalPredicate.."false"
end
else
processFilter(Explorer.SearchFilters.Default(term))
end
end
end
end
if op then
finalPredicate = finalPredicate..op
if op == "(" and (#term > 0 or lastOp == ")") then -- Handle bracket glitch
return
else
lastOp = op
end
end
init = nextInd+nextData[1]
end
local finalSetups = ""
local finalHeaders = ""
local finalObjectDefs = ""
for setup,_ in next,setups do finalSetups = finalSetups..setup.."\n" end
for header,_ in next,headers do finalHeaders = finalHeaders..header.."\n" end
for oDef,_ in next,objectDefs do finalObjectDefs = finalObjectDefs..oDef.."\n" end
local template = [==[
local searchResults = searchResults
local nodes = nodes
local expandTable = Explorer.SearchExpanded
local specResults = specResults
local service = service
%s
local function search(root)
%s
local expandedpar = false
for i = 1,#root do
local node = root[i]
local obj = node.Obj
%s
if %s then
expandTable[node] = 0
searchResults[node] = true
if not expandedpar then
local parnode = node.Parent
while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
expandTable[parnode] = true
searchResults[parnode] = true
parnode = parnode.Parent
end
expandedpar = true
end
end
if #node > 0 then search(node) end
end
end
return search]==]
local funcStr = template:format(finalHeaders,finalSetups,finalObjectDefs,finalPredicate)
local s,func = pcall(loadstring,funcStr)
if not s or not func then return nil,specFilterList end
local env = setmetatable({["searchResults"] = searchResults, ["nodes"] = nodes, ["Explorer"] = Explorer, ["specResults"] = specResults,
["service"] = service},{__index = getfenv()})
setfenv(func,env)
return func(),specFilterList
end
Explorer.DoSearch = function(query)
table.clear(Explorer.SearchExpanded)
table.clear(searchResults)
expanded = (#query == 0 and Explorer.Expanded or Explorer.SearchExpanded)
searchFunc = nil
if #query > 0 then
local expandTable = Explorer.SearchExpanded
local specFilters
local lower = string.lower
local find = string.find
local tostring = tostring
local lowerQuery = lower(query)
local function defaultSearch(root)
local expandedpar = false
for i = 1,#root do
local node = root[i]
local obj = node.Obj
if find(lower(tostring(obj)),lowerQuery,1,true) then
expandTable[node] = 0
searchResults[node] = true
if not expandedpar then
local parnode = node.Parent
while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
expanded[parnode] = true
searchResults[parnode] = true
parnode = parnode.Parent
end
expandedpar = true
end
end
if #node > 0 then defaultSearch(node) end
end
end
if Main.Elevated then
local start = tick()
searchFunc,specFilters = Explorer.BuildSearchFunc(query)
--print("BUILD SEARCH",tick()-start)
else
searchFunc = defaultSearch
end
if specFilters then
table.clear(specResults)
for i = 1,#specFilters do -- Specific search filers that returns list of matches
local resMap = {}
specResults[i] = resMap
local objs = specFilters[i]()
for c = 1,#objs do
local node = nodes[objs[c]]
if node then
resMap[node] = true
end
end
end
end
if searchFunc then
local start = tick()
searchFunc(nodes[game])
searchFunc(nilNode)
--warn(tick()-start)
end
end
Explorer.ForceUpdate()
end
Explorer.ClearSearch = function()
Explorer.GuiElems.SearchBar.Text = ""
expanded = Explorer.Expanded
searchFunc = nil
end
Explorer.InitSearch = function()
local searchBox = Explorer.GuiElems.ToolBar.SearchFrame.SearchBox
Explorer.GuiElems.SearchBar = searchBox
Lib.ViewportTextBox.convert(searchBox)
searchBox.FocusLost:Connect(function()
Explorer.DoSearch(searchBox.Text)
end)
end
Explorer.InitEntryTemplate = function()
entryTemplate = create({
{1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0,0,0),BackgroundTransparency=1,BorderColor3=Color3.new(0,0,0),Font=3,Name="Entry",Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,250,0,20),Text="",TextSize=14,}},
{2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="Indent",Parent={1},Position=UDim2.new(0,20,0,0),Size=UDim2.new(1,-20,1,0),}},
{3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="EntryName",Parent={2},Position=UDim2.new(0,26,0,0),Size=UDim2.new(1,-26,1,0),Text="Workspace",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
{4,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Font=3,Name="Expand",Parent={2},Position=UDim2.new(0,-20,0,0),Size=UDim2.new(0,20,0,20),Text="",TextSize=14,}},
{5,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={4},Position=UDim2.new(0,2,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
{6,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ImageRectOffset=Vector2.new(304,0),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={2},Position=UDim2.new(0,4,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
})
local sys = Lib.ClickSystem.new()
sys.AllowedButtons = {1,2}
sys.OnDown:Connect(function(item,combo,button)
local ind = table.find(listEntries,item)
if not ind then return end
local node = tree[ind + Explorer.Index]
if not node then return end
local entry = listEntries[ind]
if button == 1 then
if combo == 2 then
if node.Obj:IsA("LuaSourceContainer") then
ScriptViewer.ViewScript(node.Obj)
elseif #node > 0 and expanded[node] ~= 0 then
expanded[node] = not expanded[node]
Explorer.Update()
end
end
if Properties.SelectObject(node.Obj) then
sys.IsRenaming = false
return
end
sys.IsRenaming = selection.Map[node]
if Lib.IsShiftDown() then
if not selection.Piviot then return end
local fromIndex = table.find(tree,selection.Piviot)
local toIndex = table.find(tree,node)
if not fromIndex or not toIndex then return end
fromIndex,toIndex = math.min(fromIndex,toIndex),math.max(fromIndex,toIndex)
local sList = selection.List
for i = #sList,1,-1 do
local elem = sList[i]
if selection.ShiftSet[elem] then
selection.Map[elem] = nil
table.remove(sList,i)
end
end
selection.ShiftSet = {}
for i = fromIndex,toIndex do
local elem = tree[i]
if not selection.Map[elem] then
selection.ShiftSet[elem] = true
selection.Map[elem] = true
sList[#sList+1] = elem
end
end
selection.Changed:Fire()
elseif Lib.IsCtrlDown() then
selection.ShiftSet = {}
if selection.Map[node] then selection:Remove(node) else selection:Add(node) end
selection.Piviot = node
sys.IsRenaming = false
elseif not selection.Map[node] then
selection.ShiftSet = {}
selection:Set(node)
selection.Piviot = node
end
elseif button == 2 then
if Properties.SelectObject(node.Obj) then
return
end
if not Lib.IsCtrlDown() and not selection.Map[node] then
selection.ShiftSet = {}
selection:Set(node)
selection.Piviot = node
Explorer.Refresh()
end
end
Explorer.Refresh()
end)
sys.OnRelease:Connect(function(item,combo,button,position)
local ind = table.find(listEntries,item)
if not ind then return end
local node = tree[ind + Explorer.Index]
if not node then return end
if button == 1 then
if selection.Map[node] and not Lib.IsShiftDown() and not Lib.IsCtrlDown() then
selection.ShiftSet = {}
selection:Set(node)
selection.Piviot = node
Explorer.Refresh()
end
local id = sys.ClickId
Lib.FastWait(sys.ComboTime)
if combo == 1 and id == sys.ClickId and sys.IsRenaming and selection.Map[node] then
Explorer.SetRenamingNode(node)
end
elseif button == 2 then
Explorer.ShowRightClick(position)
end
end)
Explorer.ClickSystem = sys
end
Explorer.InitDelCleaner = function()
coroutine.wrap(function()
local fw = Lib.FastWait
while true do
local processed = false
local c = 0
for _,node in next,nodes do
if node.HasDel then
local delInd
for i = 1,#node do
if node[i].Del then
delInd = i
break
end
end
if delInd then
for i = delInd+1,#node do
local cn = node[i]
if not cn.Del then
node[delInd] = cn
delInd = delInd+1
end
end
for i = delInd,#node do
node[i] = nil
end
end
node.HasDel = false
processed = true
fw()
end
c = c + 1
if c > 10000 then
c = 0
fw()
end
end
if processed and not refreshDebounce then Explorer.PerformRefresh() end
fw(0.5)
end
end)()
end
Explorer.UpdateSelectionVisuals = function()
local holder = Explorer.SelectionVisualsHolder
local isa = game.IsA
local clone = game.Clone
if not holder then
holder = Instance.new("ScreenGui")
holder.Name = "ExplorerSelections"
holder.DisplayOrder = Main.DisplayOrders.Core
Lib.ShowGui(holder)
Explorer.SelectionVisualsHolder = holder
Explorer.SelectionVisualCons = {}
local guiTemplate = create({
{1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Size=UDim2.new(0,100,0,100),}},
{2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,-1),Size=UDim2.new(1,2,0,1),}},
{3,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,1,0),Size=UDim2.new(1,2,0,1),}},
{4,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,0),Size=UDim2.new(0,1,1,0),}},
{5,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(1,0,0,0),Size=UDim2.new(0,1,1,0),}},
})
Explorer.SelectionVisualGui = guiTemplate
local boxTemplate = Instance.new("SelectionBox")
boxTemplate.LineThickness = 0.03
boxTemplate.Color3 = Color3.fromRGB(0, 170, 255)
Explorer.SelectionVisualBox = boxTemplate
end
holder:ClearAllChildren()
-- Updates theme
for i,v in pairs(Explorer.SelectionVisualGui:GetChildren()) do
v.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
end
local attachCons = Explorer.SelectionVisualCons
for i = 1,#attachCons do
attachCons[i].Destroy()
end
table.clear(attachCons)
local partEnabled = Settings.Explorer.PartSelectionBox
local guiEnabled = Settings.Explorer.GuiSelectionBox
if not partEnabled and not guiEnabled then return end
local svg = Explorer.SelectionVisualGui
local svb = Explorer.SelectionVisualBox
local attachTo = Lib.AttachTo
local sList = selection.List
local count = 1
local boxCount = 0
local workspaceNode = nodes[workspace]
for i = 1,#sList do
if boxCount > 1000 then break end
local node = sList[i]
local obj = node.Obj
if node ~= workspaceNode then
if isa(obj,"GuiObject") and guiEnabled then
local newVisual = clone(svg)
attachCons[count] = attachTo(newVisual,{Target = obj, Resize = true})
count = count + 1
newVisual.Parent = holder
boxCount = boxCount + 1
elseif isa(obj,"PVInstance") and partEnabled then
local newBox = clone(svb)
newBox.Adornee = obj
newBox.Parent = holder
boxCount = boxCount + 1
end
end
end
end
Explorer.Init = function()
Explorer.LegacyClassIcons = Lib.IconMap.newLinear("rbxasset://textures/ClassImages.PNG", 16,16)
if Settings.ClassIcon ~= nil and Settings.ClassIcon ~= "Old" then
iconData = Lib.IconMap.getIconDataFromName(Settings.ClassIcon)
Explorer.ClassIcons = Lib.IconMap.new("rbxassetid://"..tostring(iconData.MapId), iconData.IconSize * iconData.Witdh, iconData.IconSize * iconData.Height,iconData.IconSize,iconData.IconSize)
-- move every value dict 1 behind because SetDict starts at 0 not 1 lol
local fixed = {}
for i,v in pairs(iconData.Icons) do
fixed[i] = v - 1
end
iconData.Icons = fixed
Explorer.ClassIcons:SetDict(fixed)
else
Explorer.ClassIcons = Lib.IconMap.newLinear("rbxasset://textures/ClassImages.PNG", 16,16)
end
Explorer.MiscIcons = Main.MiscIcons
clipboard = {}
selection = Lib.Set.new()
selection.ShiftSet = {}
selection.Changed:Connect(Properties.ShowExplorerProps)
Explorer.Selection = selection
Explorer.InitRightClick()
Explorer.InitInsertObject()
Explorer.SetSortingEnabled(Settings.Explorer.Sorting)
Explorer.Expanded = setmetatable({},{__mode = "k"})
Explorer.SearchExpanded = setmetatable({},{__mode = "k"})
expanded = Explorer.Expanded
nilNode.Obj.Name = "Nil Instances"
nilNode.Locked = true
local explorerItems = create({
{1,"Folder",{Name="ExplorerItems",}},
{2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
{3,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchFrame",Parent={2},Position=UDim2.new(0,3,0,1),Size=UDim2.new(1,-6,0,18),}},
{4,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClearTextOnFocus=false,Font=3,Name="SearchBox",Parent={3},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search workspace",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-24,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
{5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
{6,"UIStroke",{Thickness=1.4,Parent={3},Color=Color3.fromRGB(42,42,42)}},
{7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Reset",Parent={3},Position=UDim2.new(1,-17,0,1),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
{8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={7},Size=UDim2.new(0,16,0,16),}},
{9,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Refresh",Parent={2},Position=UDim2.new(1,-20,0,1),Size=UDim2.new(0,18,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
{10,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={9},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
{11,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Parent={1},Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}},
{12,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Name="List",Parent={1},Position=UDim2.new(0,0,0,23),Size=UDim2.new(1,0,1,-23),}}
})
toolBar = explorerItems.ToolBar
treeFrame = explorerItems.List
Explorer.GuiElems.ToolBar = toolBar
Explorer.GuiElems.TreeFrame = treeFrame
scrollV = Lib.ScrollBar.new()
scrollV.WheelIncrement = 3
scrollV.Gui.Position = UDim2.new(1,-16,0,23)
scrollV:SetScrollFrame(treeFrame)
scrollV.Scrolled:Connect(function()
Explorer.Index = scrollV.Index
Explorer.Refresh()
end)
scrollH = Lib.ScrollBar.new(true)
scrollH.Increment = 5
scrollH.WheelIncrement = Explorer.EntryIndent
scrollH.Gui.Position = UDim2.new(0,0,1,-16)
scrollH.Scrolled:Connect(function()
Explorer.Refresh()
end)
local window = Lib.Window.new()
Explorer.Window = window
window:SetTitle("Explorer")
window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
Explorer.InitEntryTemplate()
toolBar.Parent = window.GuiElems.Content
treeFrame.Parent = window.GuiElems.Content
explorerItems.ScrollCorner.Parent = window.GuiElems.Content
scrollV.Gui.Parent = window.GuiElems.Content
scrollH.Gui.Parent = window.GuiElems.Content
-- Init stuff that requires the window
Explorer.InitRenameBox()
Explorer.InitSearch()
Explorer.InitDelCleaner()
selection.Changed:Connect(Explorer.UpdateSelectionVisuals)
-- Window events
window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
if Explorer.Active then
Explorer.UpdateView()
Explorer.Refresh()
end
end)
window.OnActivate:Connect(function()
Explorer.Active = true
Explorer.UpdateView()
Explorer.Update()
Explorer.Refresh()
end)
window.OnRestore:Connect(function()
Explorer.Active = true
Explorer.UpdateView()
Explorer.Update()
Explorer.Refresh()
end)
window.OnDeactivate:Connect(function() Explorer.Active = false end)
window.OnMinimize:Connect(function() Explorer.Active = false end)
-- Settings
autoUpdateSearch = Settings.Explorer.AutoUpdateSearch
-- Fill in nodes
nodes[game] = {Obj = game}
expanded[nodes[game]] = true
-- Nil Instances
if env.getnilinstances then
nodes[nilNode.Obj] = nilNode
end
Explorer.SetupConnections()
local insts = getDescendants(game)
if Main.Elevated then
for i = 1,#insts do
local obj = insts[i]
local par = nodes[ffa(obj,"Instance")]
if not par then continue end
local newNode = {
Obj = obj,
Parent = par,
}
nodes[obj] = newNode
par[#par+1] = newNode
end
else
for i = 1,#insts do
local obj = insts[i]
local s,parObj = pcall(ffa,obj,"Instance")
local par = nodes[parObj]
if not par then continue end
local newNode = {
Obj = obj,
Parent = par,
}
nodes[obj] = newNode
par[#par+1] = newNode
end
end
end
return Explorer
end
return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
end,
["Lib"] = function()
--[[
Lib Module
Container for functions and classes
]]
-- Common Locals
local Main,Lib,Apps,Settings -- Main Containers
local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
local API,RMD,env,service,plr,create,createSimple -- Main Locals
local function initDeps(data)
Main = data.Main
Lib = data.Lib
Apps = data.Apps
Settings = data.Settings
API = data.API
RMD = data.RMD
env = data.env
service = data.service
plr = data.plr
create = data.create
createSimple = data.createSimple
end
local function initAfterMain()
Explorer = Apps.Explorer
Properties = Apps.Properties
ScriptViewer = Apps.ScriptViewer
Notebook = Apps.Notebook
end
local function main()
local Lib = {}
local renderStepped = service.RunService.RenderStepped
local signalWait = renderStepped.wait
local PH = newproxy() -- Placeholder, must be replaced in constructor
local SIGNAL = newproxy()
-- Usually for classes that work with a Roblox Object
local function initObj(props,mt)
local type = type
local function copy(t)
local res = {}
for i,v in pairs(t) do
if v == SIGNAL then
res[i] = Lib.Signal.new()
elseif type(v) == "table" then
res[i] = copy(v)
else
res[i] = v
end
end
return res
end
local newObj = copy(props)
return setmetatable(newObj,mt)
end
local function getGuiMT(props,funcs)
return {__index = function(self,ind) if not props[ind] then return funcs[ind] or self.Gui[ind] end end,
__newindex = function(self,ind,val) if not props[ind] then self.Gui[ind] = val else rawset(self,ind,val) end end}
end
-- Functions
Lib.FormatLuaString = (function()
local string = string
local gsub = string.gsub
local format = string.format
local char = string.char
local cleanTable = {['"'] = '\\"', ['\\'] = '\\\\'}
for i = 0,31 do
cleanTable[char(i)] = "\\"..format("%03d",i)
end
for i = 127,255 do
cleanTable[char(i)] = "\\"..format("%03d",i)
end
return function(str)
return gsub(str,"[\"\\\0-\31\127-\255]",cleanTable)
end
end)()
Lib.CheckMouseInGui = function(gui)
if gui == nil then return false end
local mouse = Main.Mouse
local guiPosition = gui.AbsolutePosition
local guiSize = gui.AbsoluteSize
return mouse.X >= guiPosition.X and mouse.X < guiPosition.X + guiSize.X and mouse.Y >= guiPosition.Y and mouse.Y < guiPosition.Y + guiSize.Y
end
Lib.IsShiftDown = function()
return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
end
Lib.IsCtrlDown = function()
return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
end
Lib.CreateArrow = function(size,num,dir)
local max = num
local arrowFrame = createSimple("Frame",{
BackgroundTransparency = 1,
Name = "Arrow",
Size = UDim2.new(0,size,0,size)
})
if dir == "up" then
for i = 1,num do
local newLine = createSimple("Frame",{
BackgroundColor3 = Color3.new(220/255,220/255,220/255),
BorderSizePixel = 0,
Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)+i-math.floor(max/2)-1),
Size = UDim2.new(0,i+(i-1),0,1),
Parent = arrowFrame
})
end
return arrowFrame
elseif dir == "down" then
for i = 1,num do
local newLine = createSimple("Frame",{
BackgroundColor3 = Color3.new(220/255,220/255,220/255),
BorderSizePixel = 0,
Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)-i+math.floor(max/2)+1),
Size = UDim2.new(0,i+(i-1),0,1),
Parent = arrowFrame
})
end
return arrowFrame
elseif dir == "left" then
for i = 1,num do
local newLine = createSimple("Frame",{
BackgroundColor3 = Color3.new(220/255,220/255,220/255),
BorderSizePixel = 0,
Position = UDim2.new(0,math.floor(size/2)+i-math.floor(max/2)-1,0,math.floor(size/2)-(i-1)),
Size = UDim2.new(0,1,0,i+(i-1)),
Parent = arrowFrame
})
end
return arrowFrame
elseif dir == "right" then
for i = 1,num do
local newLine = createSimple("Frame",{
BackgroundColor3 = Color3.new(220/255,220/255,220/255),
BorderSizePixel = 0,
Position = UDim2.new(0,math.floor(size/2)-i+math.floor(max/2)+1,0,math.floor(size/2)-(i-1)),
Size = UDim2.new(0,1,0,i+(i-1)),
Parent = arrowFrame
})
end
return arrowFrame
end
error("r u ok")
end
Lib.ParseXML = (function()
local func = function()
-- Only exists to parse RMD
-- from https://github.com/jonathanpoelen/xmlparser
local string, print, pairs = string, print, pairs
-- http://lua-users.org/wiki/StringTrim
local trim = function(s)
local from = s:match"^%s*()"
return from > #s and "" or s:match(".*%S", from)
end
local gtchar = string.byte('>', 1)
local slashchar = string.byte('/', 1)
local D = string.byte('D', 1)
local E = string.byte('E', 1)
function parse(s, evalEntities)
-- remove comments
s = s:gsub('<!%-%-(.-)%-%->', '')
local entities, tentities = {}
if evalEntities then
local pos = s:find('<[_%w]')
if pos then
s:sub(1, pos):gsub('<!ENTITY%s+([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
entities[#entities+1] = {name=name, value=entity}
end)
tentities = createEntityTable(entities)
s = replaceEntities(s:sub(pos), tentities)
end
end
local t, l = {}, {}
local addtext = function(txt)
txt = txt:match'^%s*(.*%S)' or ''
if #txt ~= 0 then
t[#t+1] = {text=txt}
end
end
s:gsub('<([?!/]?)([-:_%w]+)%s*(/?>?)([^<]*)', function(type, name, closed, txt)
-- open
if #type == 0 then
local a = {}
if #closed == 0 then
local len = 0
for all,aname,_,value,starttxt in string.gmatch(txt, "(.-([-_%w]+)%s*=%s*(.)(.-)%3%s*(/?>?))") do
len = len + #all
a[aname] = value
if #starttxt ~= 0 then
txt = txt:sub(len+1)
closed = starttxt
break
end
end
end
t[#t+1] = {tag=name, attrs=a, children={}}
if closed:byte(1) ~= slashchar then
l[#l+1] = t
t = t[#t].children
end
addtext(txt)
-- close
elseif '/' == type then
t = l[#l]
l[#l] = nil
addtext(txt)
-- ENTITY
elseif '!' == type then
if E == name:byte(1) then
txt:gsub('([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
entities[#entities+1] = {name=name, value=entity}
end, 1)
end
-- elseif '?' == type then
-- print('? ' .. name .. ' // ' .. attrs .. '$$')
-- elseif '-' == type then
-- print('comment ' .. name .. ' // ' .. attrs .. '$$')
-- else
-- print('o ' .. #p .. ' // ' .. name .. ' // ' .. attrs .. '$$')
end
end)
return {children=t, entities=entities, tentities=tentities}
end
function parseText(txt)
return parse(txt)
end
function defaultEntityTable()
return { quot='"', apos='\'', lt='<', gt='>', amp='&', tab='\t', nbsp=' ', }
end
function replaceEntities(s, entities)
return s:gsub('&([^;]+);', entities)
end
function createEntityTable(docEntities, resultEntities)
entities = resultEntities or defaultEntityTable()
for _,e in pairs(docEntities) do
e.value = replaceEntities(e.value, entities)
entities[e.name] = e.value
end
return entities
end
return parseText
end
local newEnv = setmetatable({},{__index = getfenv()})
setfenv(func,newEnv)
return func()
end)()
Lib.FastWait = function(s)
if not s then return signalWait(renderStepped) end
local start = tick()
while tick() - start < s do signalWait(renderStepped) end
end
Lib.ButtonAnim = function(button,data)
local holding = false
local disabled = false
local mode = data and data.Mode or 1
local control = {}
if mode == 2 then
local lerpTo = data.LerpTo or Color3.new(0,0,0)
local delta = data.LerpDelta or 0.2
control.StartColor = data.StartColor or button.BackgroundColor3
control.PressColor = data.PressColor or control.StartColor:lerp(lerpTo,delta)
control.HoverColor = data.HoverColor or control.StartColor:lerp(control.PressColor,0.6)
control.OutlineColor = data.OutlineColor
end
button.InputBegan:Connect(function(input)
if disabled then return end
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
if not holding then
if mode == 1 then
button.BackgroundTransparency = 0.4
elseif mode == 2 then
button.BackgroundColor3 = control.HoverColor
end
end
elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
holding = true
if mode == 1 then
button.BackgroundTransparency = 0
elseif mode == 2 then
button.BackgroundColor3 = control.PressColor
if control.OutlineColor then button.BorderColor3 = control.PressColor end
end
end
end)
button.InputEnded:Connect(function(input)
if disabled then return end
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
if not holding then
if mode == 1 then
button.BackgroundTransparency = 1
elseif mode == 2 then
button.BackgroundColor3 = control.StartColor
end
end
elseif input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
holding = false
if mode == 1 then
button.BackgroundTransparency = Lib.CheckMouseInGui(button) and 0.4 or 1
elseif mode == 2 then
button.BackgroundColor3 = Lib.CheckMouseInGui(button) and control.HoverColor or control.StartColor
if control.OutlineColor then button.BorderColor3 = control.OutlineColor end
end
end
end)
control.Disable = function()
disabled = true
holding = false
if mode == 1 then
button.BackgroundTransparency = 1
elseif mode == 2 then
button.BackgroundColor3 = control.StartColor
end
end
control.Enable = function()
disabled = false
end
return control
end
Lib.FindAndRemove = function(t,item)
local pos = table.find(t,item)
if pos then table.remove(t,pos) end
end
Lib.AttachTo = function(obj,data)
local target,posOffX,posOffY,sizeOffX,sizeOffY,resize,con
local disabled = false
local function update()
if not obj or not target then return end
local targetPos = target.AbsolutePosition
local targetSize = target.AbsoluteSize
obj.Position = UDim2.new(0,targetPos.X + posOffX,0,targetPos.Y + posOffY)
if resize then obj.Size = UDim2.new(0,targetSize.X + sizeOffX,0,targetSize.Y + sizeOffY) end
end
local function setup(o,data)
obj = o
data = data or {}
target = data.Target
posOffX = data.PosOffX or 0
posOffY = data.PosOffY or 0
sizeOffX = data.SizeOffX or 0
sizeOffY = data.SizeOffY or 0
resize = data.Resize or false
if con then con:Disconnect() con = nil end
if target then
con = target.Changed:Connect(function(prop)
if not disabled and prop == "AbsolutePosition" or prop == "AbsoluteSize" then
update()
end
end)
end
update()
end
setup(obj,data)
return {
SetData = function(obj,data)
setup(obj,data)
end,
Enable = function()
disabled = false
update()
end,
Disable = function()
disabled = true
end,
Destroy = function()
con:Disconnect()
con = nil
end,
}
end
Lib.ProtectedGuis = {}
Lib.ShowGui = Main.SecureGui
Lib.ColorToBytes = function(col)
local round = math.round
return string.format("%d, %d, %d",round(col.r*255),round(col.g*255),round(col.b*255))
end
Lib.ReadFile = function(filename)
if not env.readfile then return end
local s,contents = pcall(env.readfile,filename)
if s and contents then return contents end
end
Lib.DeferFunc = function(f,...)
signalWait(renderStepped)
return f(...)
end
Lib.LoadCustomAsset = function(filepath)
if not env.getcustomasset or not env.isfile or not env.isfile(filepath) then return end
return env.getcustomasset(filepath)
end
Lib.FetchCustomAsset = function(url,filepath)
if not env.writefile then return end
local s,data = pcall(oldgame.HttpGet,game,url)
if not s then return end
env.writefile(filepath,data)
return Lib.LoadCustomAsset(filepath)
end
local currentfilename, currentextension, currentclickhandler
currentclickhandler = function() end
Lib.SaveAsPrompt = function(filename, codeToSave, ext)
local win = ScriptViewer.SaveAsWindow
if not win then
win = Lib.Window.new()
win.Alignable = false
win.Resizable = false
win:SetTitle("Save As")
win:SetSize(300,95)
local saveButton = Lib.Button.new()
local nameLabel = Lib.Label.new()
nameLabel.Text = "Name"
nameLabel.Position = UDim2.new(0,30,0,10)
nameLabel.Size = UDim2.new(0,40,0,20)
win:Add(nameLabel)
local nameBox = Lib.ViewportTextBox.new()
nameBox.Position = UDim2.new(0,75,0,10)
nameBox.Size = UDim2.new(0,220,0,20)
win:Add(nameBox,"NameBox")
--nameBox.TextBox.Text = filename or ""
nameBox.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
saveButton:SetDisabled(#nameBox:GetText() == 0)
end)
local errorLabel = Lib.Label.new()
errorLabel.Text = ""
errorLabel.Position = UDim2.new(0,5,1,-45)
errorLabel.Size = UDim2.new(1,-10,0,20)
errorLabel.TextColor3 = Settings.Theme.Important
win.ErrorLabel = errorLabel
win:Add(errorLabel,"Error")
local cancelButton = Lib.Button.new()
cancelButton.AnchorPoint = Vector2.new(1,1)
cancelButton.Text = "Cancel"
cancelButton.Position = UDim2.new(1,-5,1,-5)
cancelButton.Size = UDim2.new(0.5,-10,0,20)
cancelButton.OnClick:Connect(function()
win:Close()
end)
win:Add(cancelButton)
saveButton.Text = "Save"
saveButton.AnchorPoint = Vector2.new(0,1)
saveButton.Position = UDim2.new(0,5,1,-5)
saveButton.Size = UDim2.new(0.5,-5,0,20)
saveButton.OnClick:Connect(function()
currentclickhandler()
end)
win:Add(saveButton,"SaveButton")
ScriptViewer.SaveAsWindow = win
end
currentclickhandler = function()
if type(codeToSave) == "string" then
filename = (win.Elements.NameBox.TextBox.Text ~= "" and win.Elements.NameBox.TextBox.Text) or filename
currentextension = ext or filename:match("%.([^%.]+)$") or "txt"
filename = filename:gsub("%.[^.]+$", "") .. "." .. currentextension
local codeText = codeToSave or ""
if env.writefile then
local s, msg = pcall(env.writefile, filename, codeText)
if not s then
win.Elements.Error.Text = "Error: " .. msg
task.spawn(error, msg)
task.wait(1)
end
else
win.Elements.Error.Text = "Your executor does not support 'writefile'"
task.wait(1)
end
elseif type(codeToSave) == "function" then
filename = (win.Elements.NameBox.TextBox.Text ~= "" and win.Elements.NameBox.TextBox.Text) or filename
currentextension = ext or filename:match("%.([^%.]+)$") or "txt"
filename = filename:gsub("%.[^.]+$", "") .. "." .. currentextension
local s, msg = pcall(codeToSave,filename) -- callback
if not s then
win.Elements.Error.Text = "Error: " .. msg
task.spawn(error, msg)
Lib.FastWait(1)
end
end
win:Close()
end
win:SetTitle("Save As")
win.Elements.Error.Text = ""
win.Elements.NameBox:SetText(filename or "")
win.Elements.SaveButton:SetDisabled(win.Elements.NameBox:GetText() == 0)
win:Show()
end
-- Classes
Lib.Signal = (function()
local funcs = {}
local disconnect = function(con)
local pos = table.find(con.Signal.Connections,con)
if pos then table.remove(con.Signal.Connections,pos) end
end
funcs.Connect = function(self,func)
if type(func) ~= "function" then error("Attempt to connect a non-function") end
local con = {
Signal = self,
Func = func,
Disconnect = disconnect
}
self.Connections[#self.Connections+1] = con
return con
end
funcs.Fire = function(self,...)
for i,v in next,self.Connections do
xpcall(coroutine.wrap(v.Func),function(e) warn(e.."\n"..debug.traceback()) end,...)
end
end
local mt = {
__index = funcs,
__tostring = function(self)
return "Signal: " .. tostring(#self.Connections) .. " Connections"
end
}
local function new()
local obj = {}
obj.Connections = {}
return setmetatable(obj,mt)
end
return {new = new}
end)()
Lib.Set = (function()
local funcs = {}
funcs.Add = function(self,obj)
if self.Map[obj] then return end
local list = self.List
list[#list+1] = obj
self.Map[obj] = true
self.Changed:Fire()
end
funcs.AddTable = function(self,t)
local changed
local list,map = self.List,self.Map
for i = 1,#t do
local elem = t[i]
if not map[elem] then
list[#list+1] = elem
map[elem] = true
changed = true
end
end
if changed then self.Changed:Fire() end
end
funcs.Remove = function(self,obj)
if not self.Map[obj] then return end
local list = self.List
local pos = table.find(list,obj)
if pos then table.remove(list,pos) end
self.Map[obj] = nil
self.Changed:Fire()
end
funcs.RemoveTable = function(self,t)
local changed
local list,map = self.List,self.Map
local removeSet = {}
for i = 1,#t do
local elem = t[i]
map[elem] = nil
removeSet[elem] = true
end
for i = #list,1,-1 do
local elem = list[i]
if removeSet[elem] then
table.remove(list,i)
changed = true
end
end
if changed then self.Changed:Fire() end
end
funcs.Set = function(self,obj)
if #self.List == 1 and self.List[1] == obj then return end
self.List = {obj}
self.Map = {[obj] = true}
self.Changed:Fire()
end
funcs.SetTable = function(self,t)
local newList,newMap = {},{}
self.List,self.Map = newList,newMap
table.move(t,1,#t,1,newList)
for i = 1,#t do
newMap[t[i]] = true
end
self.Changed:Fire()
end
funcs.Clear = function(self)
if #self.List == 0 then return end
self.List = {}
self.Map = {}
self.Changed:Fire()
end
local mt = {__index = funcs}
local function new()
local obj = setmetatable({
List = {},
Map = {},
Changed = Lib.Signal.new()
},mt)
return obj
end
return {new = new}
end)()
Lib.IconMap = (function()
local funcs = {}
local IconList = {
Old = {
MapId = 483448923,
IconSize = 16,
Witdh = 16,
Height = 16,
Icons = {
["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;
["ServerStorage"] = 74;
["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;
}
},
Vanilla3 = {
MapId = (114851699900089),
IconSize = 32,
Witdh = 25,
Height = 25,
Icons = {
Accessory = 1,
Accoutrement = 2,
Actor = 3,
AdGui = 4,
AdPortal = 5,
AdService = 6,
AdvancedDragger = 7,
AirController = 8,
AlignOrientation = 9,
AlignPosition = 10,
AnalysticsService = 11,
AnalysticsSettings = 12,
AnalyticsService = 13,
AngularVelocity = 14,
Animation = 15,
AnimationClip = 16,
AnimationClipProvider = 17,
AnimationController = 18,
AnimationFromVideoCreatorService = 19,
AnimationFromVideoCreatorStudioService = 20,
AnimationRigData = 21,
AnimationStreamTrack = 22,
AnimationTrack = 23,
Animator = 24,
AppStorageService = 25,
AppUpdateService = 26,
ArcHandles = 27,
AssetCounterService = 28,
AssetDeliveryProxy = 29,
AssetImportService = 30,
AssetImportSession = 31,
AssetManagerService = 32,
AssetService = 33,
AssetSoundEffect = 34,
Atmosphere = 35,
Attachment = 36,
AvatarEditorService = 37,
AvatarImportService = 38,
Backpack = 39,
BackpackItem = 40,
BadgeService = 41,
BallSocketConstraint = 42,
BasePart = 43,
BasePlayerGui = 44,
BaseScript = 45,
BaseWrap = 46,
Beam = 47,
BevelMesh = 48,
BillboardGui = 49,
BinaryStringValue = 50,
BindableEvent = 51,
BindableFunction = 52,
BlockMesh = 53,
BloomEffect = 54,
BlurEffect = 55,
BodyAngularVelocity = 56,
BodyColors = 57,
BodyForce = 58,
BodyGyro = 59,
BodyMover = 60,
BodyPosition = 61,
BodyThrust = 62,
BodyVelocity = 63,
Bone = 64,
BoolValue = 65,
BoxHandleAdornment = 66,
Breakpoint = 67,
BreakpointManager = 68,
BrickColorValue = 69,
BrowserService = 70,
BubbleChatConfiguration = 71,
BulkImportService = 72,
CacheableContentProvider = 73,
CalloutService = 74,
Camera = 75,
CanvasGroup = 76,
CatalogPages = 77,
CFrameValue = 78,
ChangeHistoryService = 79,
ChannelSelectorSoundEffect = 80,
CharacterAppearance = 81,
CharacterMesh = 82,
Chat = 83,
ChatInputBarConfiguration = 84,
ChatWindowConfiguration = 85,
ChorusSoundEffect = 86,
ClickDetector = 87,
ClientReplicator = 88,
ClimbController = 89,
Clothing = 90,
Clouds = 91,
ClusterPacketCache = 92,
CollectionService = 93,
Color3Value = 94,
ColorCorrectionEffect = 95,
CommandInstance = 96,
CommandService = 97,
CompressorSoundEffect = 98,
ConeHandleAdornment = 99,
Configuration = 100,
ConfigureServerService = 101,
Constraint = 102,
ContentProvider = 103,
ContextActionService = 104,
Controller = 105,
ControllerBase = 106,
ControllerManager = 107,
ControllerService = 108,
CookiesService = 109,
CoreGui = 110,
CorePackages = 111,
CoreScript = 112,
CoreScriptSyncService = 113,
CornerWedgePart = 114,
CrossDMScriptChangeListener = 115,
CSGDictionaryService = 116,
CurveAnimation = 117,
CustomEvent = 118,
CustomEventReceiver = 119,
CustomSoundEffect = 120,
CylinderHandleAdornment = 121,
CylinderMesh = 122,
CylindricalConstraint = 123,
DataModel = 124,
DataModelMesh = 125,
DataModelPatchService = 126,
DataModelSession = 127,
DataStore = 128,
DataStoreIncrementOptions = 129,
DataStoreInfo = 130,
DataStoreKey = 131,
DataStoreKeyInfo = 132,
DataStoreKeyPages = 133,
DataStoreListingPages = 134,
DataStoreObjectVersionInfo = 135,
DataStoreOptions = 136,
DataStorePages = 137,
DataStoreService = 138,
DataStoreSetOptions = 139,
DataStoreVersionPages = 140,
Debris = 141,
DebuggablePluginWatcher = 142,
DebuggerBreakpoint = 143,
DebuggerConnection = 144,
DebuggerConnectionManager = 145,
DebuggerLuaResponse = 146,
DebuggerManager = 147,
DebuggerUIService = 148,
DebuggerVariable = 149,
DebuggerWatch = 150,
DebugSettings = 151,
Decal = 152,
DepthOfFieldEffect = 153,
DeviceIdService = 154,
Dialog = 155,
DialogChoice = 156,
DistortionSoundEffect = 157,
DockWidgetPluginGui = 158,
DoubleConstrainedValue = 159,
DraftsService = 160,
Dragger = 161,
DraggerService = 162,
DynamicRotate = 163,
EchoSoundEffect = 164,
EmotesPages = 165,
EqualizerSoundEffect = 166,
EulerRotationCurve = 167,
EventIngestService = 168,
Explosion = 169,
FaceAnimatorService = 170,
FaceControls = 171,
FaceInstance = 172,
FacialAnimationRecordingService = 173,
FacialAnimationStreamingService = 174,
Feature = 175,
File = 176,
FileMesh = 177,
Fire = 178,
Flag = 179,
FlagStand = 180,
FlagStandService = 181,
FlangeSoundEffect = 182,
FloatCurve = 183,
FloorWire = 184,
FlyweightService = 185,
Folder = 186,
ForceField = 187,
FormFactorPart = 188,
Frame = 189,
FriendPages = 190,
FriendService = 191,
FunctionalTest = 192,
GamepadService = 193,
GamePassService = 194,
GameSettings = 195,
GenericSettings = 196,
Geometry = 197,
GetTextBoundsParams = 198,
GlobalDataStore = 199,
GlobalSettings = 200,
Glue = 201,
GoogleAnalyticsConfiguration = 202,
GroundController = 203,
GroupService = 204,
GuiBase = 205,
GuiBase2d = 206,
GuiBase3d = 207,
GuiButton = 208,
GuidRegistryService = 209,
GuiLabel = 210,
GuiMain = 211,
GuiObject = 212,
GuiService = 213,
HandleAdornment = 214,
Handles = 215,
HandlesBase = 216,
HapticService = 217,
Hat = 218,
HeightmapImporterService = 219,
HiddenSurfaceRemovalAsset = 220,
Highlight = 221,
HingeConstraint = 222,
Hint = 223,
Hole = 224,
Hopper = 225,
HopperBin = 226,
HSRDataContentProvider = 227,
HttpRbxApiService = 228,
HttpRequest = 229,
HttpService = 230,
Humanoid = 231,
HumanoidController = 232,
HumanoidDescription = 233,
IKControl = 234,
ILegacyStudioBridge = 235,
ImageButton = 236,
ImageHandleAdornment = 237,
ImageLabel = 238,
ImporterAnimationSettings = 239,
ImporterBaseSettings = 240,
ImporterFacsSettings = 241,
ImporterGroupSettings = 242,
ImporterJointSettings = 243,
ImporterMaterialSettings = 244,
ImporterMeshSettings = 245,
ImporterRootSettings = 246,
IncrementalPatchBuilder = 247,
InputObject = 248,
InsertService = 249,
Instance = 250,
InstanceAdornment = 251,
IntConstrainedValue = 252,
IntValue = 253,
InventoryPages = 254,
IXPService = 255,
JointInstance = 256,
JointsService = 257,
KeyboardService = 258,
Keyframe = 259,
KeyframeMarker = 260,
KeyframeSequence = 261,
KeyframeSequenceProvider = 262,
LanguageService = 263,
LayerCollector = 264,
LegacyStudioBridge = 265,
Light = 266,
Lighting = 267,
LinearVelocity = 268,
LineForce = 269,
LineHandleAdornment = 270,
LocalDebuggerConnection = 271,
LocalizationService = 272,
LocalizationTable = 273,
LocalScript = 274,
LocalStorageService = 275,
LodDataEntity = 276,
LodDataService = 277,
LoginService = 278,
LogService = 279,
LSPFileSyncService = 280,
LuaSettings = 281,
LuaSourceContainer = 282,
LuauScriptAnalyzerService = 283,
LuaWebService = 284,
ManualGlue = 285,
ManualSurfaceJointInstance = 286,
ManualWeld = 287,
MarkerCurve = 288,
MarketplaceService = 289,
MaterialService = 290,
MaterialVariant = 291,
MemoryStoreQueue = 292,
MemoryStoreService = 293,
MemoryStoreSortedMap = 294,
MemStorageConnection = 295,
MemStorageService = 296,
MeshContentProvider = 297,
MeshPart = 298,
Message = 299,
MessageBusConnection = 300,
MessageBusService = 301,
MessagingService = 302,
MetaBreakpoint = 303,
MetaBreakpointContext = 304,
MetaBreakpointManager = 305,
Model = 306,
ModuleScript = 307,
Motor = 308,
Motor6D = 309,
MotorFeature = 310,
Mouse = 311,
MouseService = 312,
MultipleDocumentInterfaceInstance = 313,
NegateOperation = 314,
NetworkClient = 315,
NetworkMarker = 316,
NetworkPeer = 317,
NetworkReplicator = 318,
NetworkServer = 319,
NetworkSettings = 320,
NoCollisionConstraint = 321,
NonReplicatedCSGDictionaryService = 322,
NotificationService = 323,
NumberPose = 324,
NumberValue = 325,
ObjectValue = 326,
OrderedDataStore = 327,
OutfitPages = 328,
PackageLink = 329,
PackageService = 330,
PackageUIService = 331,
Pages = 332,
Pants = 333,
ParabolaAdornment = 334,
Part = 335,
PartAdornment = 336,
ParticleEmitter = 337,
PartOperation = 338,
PartOperationAsset = 339,
PatchMapping = 340,
Path = 341,
PathfindingLink = 342,
PathfindingModifier = 343,
PathfindingService = 344,
PausedState = 345,
PausedStateBreakpoint = 346,
PausedStateException = 347,
PermissionsService = 348,
PhysicsService = 349,
PhysicsSettings = 350,
PitchShiftSoundEffect = 351,
Plane = 352,
PlaneConstraint = 353,
Platform = 354,
Player = 355,
PlayerEmulatorService = 356,
PlayerGui = 357,
PlayerMouse = 358,
Players = 359,
PlayerScripts = 360,
Plugin = 361,
PluginAction = 362,
PluginDebugService = 363,
PluginDragEvent = 364,
PluginGui = 365,
PluginGuiService = 366,
PluginManagementService = 367,
PluginManager = 368,
PluginManagerInterface = 369,
PluginMenu = 370,
PluginMouse = 371,
PluginPolicyService = 372,
PluginToolbar = 373,
PluginToolbarButton = 374,
PointLight = 375,
PointsService = 376,
PolicyService = 377,
Pose = 378,
PoseBase = 379,
PostEffect = 380,
PrismaticConstraint = 381,
ProcessInstancePhysicsService = 382,
ProximityPrompt = 383,
ProximityPromptService = 384,
PublishService = 385,
PVAdornment = 386,
PVInstance = 387,
QWidgetPluginGui = 388,
RayValue = 389,
RbxAnalyticsService = 390,
ReflectionMetadata = 391,
ReflectionMetadataCallbacks = 392,
ReflectionMetadataClass = 393,
ReflectionMetadataClasses = 394,
ReflectionMetadataEnum = 395,
ReflectionMetadataEnumItem = 396,
ReflectionMetadataEnums = 397,
ReflectionMetadataEvents = 398,
ReflectionMetadataFunctions = 399,
ReflectionMetadataItem = 400,
ReflectionMetadataMember = 401,
ReflectionMetadataProperties = 402,
ReflectionMetadataYieldFunctions = 403,
RemoteDebuggerServer = 404,
RemoteEvent = 405,
RemoteFunction = 406,
RenderingTest = 407,
RenderSettings = 408,
ReplicatedFirst = 409,
ReplicatedStorage = 410,
ReverbSoundEffect = 411,
RigidConstraint = 412,
RobloxPluginGuiService = 413,
RobloxReplicatedStorage = 414,
RocketPropulsion = 415,
RodConstraint = 416,
RopeConstraint = 417,
Rotate = 418,
RotateP = 419,
RotateV = 420,
RotationCurve = 421,
RtMessagingService = 422,
RunningAverageItemDouble = 423,
RunningAverageItemInt = 424,
RunningAverageTimeIntervalItem = 425,
RunService = 426,
RuntimeScriptService = 427,
ScreenGui = 428,
ScreenshotHud = 429,
Script = 430,
ScriptChangeService = 431,
ScriptCloneWatcher = 432,
ScriptCloneWatcherHelper = 433,
ScriptContext = 434,
ScriptDebugger = 435,
ScriptDocument = 436,
ScriptEditorService = 437,
ScriptRegistrationService = 438,
ScriptService = 439,
ScrollingFrame = 440,
Seat = 441,
Selection = 442,
SelectionBox = 443,
SelectionLasso = 444,
SelectionPartLasso = 445,
SelectionPointLasso = 446,
SelectionSphere = 447,
ServerReplicator = 448,
ServerScriptService = 449,
ServerStorage = 450,
ServiceProvider = 451,
SessionService = 452,
Shirt = 453,
ShirtGraphic = 454,
SkateboardController = 455,
SkateboardPlatform = 456,
Skin = 457,
Sky = 458,
SlidingBallConstraint = 459,
Smoke = 460,
Snap = 461,
SnippetService = 462,
SocialService = 463,
SolidModelContentProvider = 464,
Sound = 465,
SoundEffect = 466,
SoundGroup = 467,
SoundService = 468,
Sparkles = 469,
SpawnerService = 470,
SpawnLocation = 471,
Speaker = 472,
SpecialMesh = 473,
SphereHandleAdornment = 474,
SpotLight = 475,
SpringConstraint = 476,
StackFrame = 477,
StandalonePluginScripts = 478,
StandardPages = 479,
StarterCharacterScripts = 480,
StarterGear = 481,
StarterGui = 482,
StarterPack = 483,
StarterPlayer = 484,
StarterPlayerScripts = 485,
Stats = 486,
StatsItem = 487,
Status = 488,
StopWatchReporter = 489,
StringValue = 490,
Studio = 491,
StudioAssetService = 492,
StudioData = 493,
StudioDeviceEmulatorService = 494,
StudioHighDpiService = 495,
StudioPublishService = 496,
StudioScriptDebugEventListener = 497,
StudioService = 498,
StudioTheme = 499,
SunRaysEffect = 500,
SurfaceAppearance = 501,
SurfaceGui = 502,
SurfaceGuiBase = 503,
SurfaceLight = 504,
SurfaceSelection = 505,
SwimController = 506,
TaskScheduler = 507,
Team = 508,
TeamCreateService = 509,
Teams = 510,
TeleportAsyncResult = 511,
TeleportOptions = 512,
TeleportService = 513,
TemporaryCageMeshProvider = 514,
TemporaryScriptService = 515,
Terrain = 516,
TerrainDetail = 517,
TerrainRegion = 518,
TestService = 519,
TextBox = 520,
TextBoxService = 521,
TextButton = 522,
TextChannel = 523,
TextChatCommand = 524,
TextChatConfigurations = 525,
TextChatMessage = 526,
TextChatMessageProperties = 527,
TextChatService = 528,
TextFilterResult = 529,
TextLabel = 530,
TextService = 531,
TextSource = 532,
Texture = 533,
ThirdPartyUserService = 534,
ThreadState = 535,
TimerService = 536,
ToastNotificationService = 537,
Tool = 538,
ToolboxService = 539,
Torque = 540,
TorsionSpringConstraint = 541,
TotalCountTimeIntervalItem = 542,
TouchInputService = 543,
TouchTransmitter = 544,
TracerService = 545,
TrackerStreamAnimation = 546,
Trail = 547,
Translator = 548,
TremoloSoundEffect = 549,
TriangleMeshPart = 550,
TrussPart = 551,
Tween = 552,
TweenBase = 553,
TweenService = 554,
UGCValidationService = 555,
UIAspectRatioConstraint = 556,
UIBase = 557,
UIComponent = 558,
UIConstraint = 559,
UICorner = 560,
UIGradient = 561,
UIGridLayout = 562,
UIGridStyleLayout = 563,
UILayout = 564,
UIListLayout = 565,
UIPadding = 566,
UIPageLayout = 567,
UIScale = 568,
UISizeConstraint = 569,
UIStroke = 570,
UITableLayout = 571,
UITextSizeConstraint = 572,
UnionOperation = 573,
UniversalConstraint = 574,
UnvalidatedAssetService = 575,
UserGameSettings = 576,
UserInputService = 577,
UserService = 578,
UserSettings = 579,
UserStorageService = 580,
ValueBase = 581,
Vector3Curve = 582,
Vector3Value = 583,
VectorForce = 584,
VehicleController = 585,
VehicleSeat = 586,
VelocityMotor = 587,
VersionControlService = 588,
VideoCaptureService = 589,
VideoFrame = 590,
ViewportFrame = 591,
VirtualInputManager = 592,
VirtualUser = 593,
VisibilityService = 594,
Visit = 595,
VoiceChannel = 596,
VoiceChatInternal = 597,
VoiceChatService = 598,
VoiceSource = 599,
VRService = 600,
WedgePart = 601,
Weld = 602,
WeldConstraint = 603,
WireframeHandleAdornment = 604,
Workspace = 605,
WorldModel = 606,
WorldRoot = 607,
WrapLayer = 608,
WrapTarget = 609,
}
},
NewDark = {
MapId = 135148380892747,
Icons = {
Accessory = 1,
Actor = 2,
AdGui = 3,
AdPortal = 4,
AirController = 5,
AlignOrientation = 6,
AlignPosition = 7,
AngularVelocity = 8,
Animation = 9,
AnimationConstraint = 10,
AnimationController = 11,
AnimationFromVideoCreatorService = 12,
Animator = 13,
ArcHandles = 14,
Atmosphere = 15,
Attachment = 16,
AudioAnalyzer = 17,
AudioChannelMixer = 18,
AudioChannelSplitter = 19,
AudioChorus = 20,
AudioCompressor = 21,
AudioDeviceInput = 22,
AudioDeviceOutput = 23,
AudioDistortion = 24,
AudioEcho = 25,
AudioEmitter = 26,
AudioEqualizer = 27,
AudioFader = 28,
AudioFilter = 29,
AudioFlanger = 30,
AudioGate = 31,
AudioLimiter = 32,
AudioListener = 33,
AudioPitchShifter = 34,
AudioPlayer = 35,
AudioRecorder = 36,
AudioReverb = 37,
AudioTextToSpeech = 38,
AuroraScript = 39,
AvatarEditorService = 40,
AvatarSettings = 41,
Backpack = 42,
BallSocketConstraint = 43,
BasePlate = 44,
Beam = 45,
BillboardGui = 46,
BindableEvent = 47,
BindableFunction = 48,
BlockMesh = 49,
BloomEffect = 50,
BlurEffect = 51,
BodyAngularVelocity = 52,
BodyColors = 53,
BodyForce = 54,
BodyGyro = 55,
BodyPosition = 56,
BodyThrust = 57,
BodyVelocity = 58,
Bone = 59,
BoolValue = 60,
BoxHandleAdornment = 61,
Breakpoint = 62,
BrickColorValue = 63,
BubbleChatConfiguration = 64,
Buggaroo = 65,
Camera = 66,
CanvasGroup = 67,
CFrameValue = 68,
ChannelTabsConfiguration = 69,
CharacterControllerManager = 70,
CharacterMesh = 71,
Chat = 72,
ChatInputBarConfiguration = 73,
ChatWindowConfiguration = 74,
ChorusSoundEffect = 75,
Class = 76,
Cleanup = 77,
ClickDetector = 78,
ClientReplicator = 79,
ClimbController = 80,
Clouds = 81,
Color = 82,
ColorCorrectionEffect = 83,
CompressorSoundEffect = 84,
ConeHandleAdornment = 85,
Configuration = 86,
Constant = 87,
Constructor = 88,
Controller = 89,
CoreGui = 90,
CornerWedgePart = 91,
CylinderHandleAdornment = 92,
CylindricalConstraint = 93,
Decal = 94,
DepthOfFieldEffect = 95,
Dialog = 96,
DialogChoice = 97,
DistortionSoundEffect = 98,
DragDetector = 99,
EchoSoundEffect = 100,
EditableImage = 101,
EditableMesh = 102,
Enum = 103,
EnumMember = 104,
EqualizerSoundEffect = 105,
Event = 106,
Explosion = 107,
FaceControls = 108,
Field = 109,
File = 110,
Fire = 111,
FlangeSoundEffect = 112,
Folder = 113,
ForceField = 114,
Frame = 115,
Function = 116,
GameSettings = 117,
GroundController = 118,
Handles = 119,
HapticEffect = 120,
HapticService = 121,
HeightmapImporterService = 122,
Highlight = 123,
HingeConstraint = 124,
Humanoid = 125,
HumanoidDescription = 126,
IKControl = 127,
ImageButton = 128,
ImageHandleAdornment = 129,
ImageLabel = 130,
InputAction = 131,
InputBinding = 132,
InputContext = 133,
Interface = 134,
IntersectOperation = 135,
Keyword = 136,
Lighting = 137,
LinearVelocity = 138,
LineForce = 139,
LineHandleAdornment = 140,
LocalFile = 141,
LocalizationService = 142,
LocalizationTable = 143,
LocalScript = 144,
MaterialService = 145,
MaterialVariant = 146,
MemoryStoreService = 147,
MeshPart = 148,
Meshparts = 149,
MessagingService = 150,
Method = 151,
Model = 152,
Modelgroups = 153,
Module = 154,
ModuleScript = 155,
Motor6D = 156,
NegateOperation = 157,
NetworkClient = 158,
NoCollisionConstraint = 159,
Operator = 160,
PackageLink = 161,
Pants = 162,
Part = 163,
ParticleEmitter = 164,
Path2D = 165,
PathfindingLink = 166,
PathfindingModifier = 167,
PathfindingService = 168,
PitchShiftSoundEffect = 169,
Place = 170,
Placeholder = 171,
Plane = 172,
PlaneConstraint = 173,
Player = 174,
Players = 175,
PluginGuiService = 176,
PointLight = 177,
PrismaticConstraint = 178,
Property = 179,
ProximityPrompt = 180,
PublishService = 181,
Reference = 182,
RemoteEvent = 183,
RemoteFunction = 184,
RenderingTest = 185,
ReplicatedFirst = 186,
ReplicatedScriptService = 187,
ReplicatedStorage = 188,
ReverbSoundEffect = 189,
RigidConstraint = 190,
RobloxPluginGuiService = 191,
RocketPropulsion = 192,
RodConstraint = 193,
RopeConstraint = 194,
Rotate = 195,
ScreenGui = 196,
Script = 197,
ScrollingFrame = 198,
Seat = 199,
Selected_Workspace = 200,
SelectionBox = 201,
SelectionSphere = 202,
ServerScriptService = 203,
ServerStorage = 204,
Service = 205,
Shirt = 206,
ShirtGraphic = 207,
SkinnedMeshPart = 208,
Sky = 209,
Smoke = 210,
Snap = 211,
Snippet = 212,
SocialService = 213,
Sound = 214,
SoundEffect = 215,
SoundGroup = 216,
SoundService = 217,
Sparkles = 218,
SpawnLocation = 219,
SpecialMesh = 220,
SphereHandleAdornment = 221,
SpotLight = 222,
SpringConstraint = 223,
StandalonePluginScripts = 224,
StarterCharacterScripts = 225,
StarterGui = 226,
StarterPack = 227,
StarterPlayer = 228,
StarterPlayerScripts = 229,
Struct = 230,
StyleDerive = 231,
StyleLink = 232,
StyleRule = 233,
StyleSheet = 234,
SunRaysEffect = 235,
SurfaceAppearance = 236,
SurfaceGui = 237,
SurfaceLight = 238,
SurfaceSelection = 239,
SwimController = 240,
TaskScheduler = 241,
Team = 242,
Teams = 243,
Terrain = 244,
TerrainDetail = 245,
TestService = 246,
TextBox = 247,
TextBoxService = 248,
TextButton = 249,
TextChannel = 250,
TextChatCommand = 251,
TextChatService = 252,
TextLabel = 253,
TextString = 254,
Texture = 255,
Tool = 256,
Torque = 257,
TorsionSpringConstraint = 258,
Trail = 259,
TremoloSoundEffect = 260,
TrussPart = 261,
TypeParameter = 262,
UGCValidationService = 263,
UIAspectRatioConstraint = 264,
UICorner = 265,
UIDragDetector = 266,
UIFlexItem = 267,
UIGradient = 268,
UIGridLayout = 269,
UIListLayout = 270,
UIPadding = 271,
UIPageLayout = 272,
UIScale = 273,
UISizeConstraint = 274,
UIStroke = 275,
UITableLayout = 276,
UITextSizeConstraint = 277,
UnionOperation = 278,
Unit = 279,
UniversalConstraint = 280,
UnreliableRemoteEvent = 281,
UpdateAvailable = 282,
UserService = 283,
Value = 284,
Variable = 285,
VectorForce = 286,
VehicleSeat = 287,
VideoDisplay = 288,
VideoFrame = 289,
VideoPlayer = 290,
ViewportFrame = 291,
VirtualUser = 292,
VoiceChannel = 293,
Voicechat = 294,
VoiceChatService = 295,
VRService = 296,
WedgePart = 297,
Weld = 298,
WeldConstraint = 299,
Wire = 300,
WireframeHandleAdornment = 301,
Workspace = 302,
WorldModel = 303,
WrapDeformer = 304,
WrapLayer = 305,
WrapTarget = 306,
Color3Value = 284,
IntValue = 284,
NumberValue = 284,
ObjectValue = 284,
RayValue = 284,
StringValue = 284,
Vector3Value = 284,
},
IconSize = 32,
Witdh = 18,
Height = 18,
},
NewLight = {
MapId = "",
Icons = {
Class = "rbxasset://studio_svg_textures/Shared/InsertableObjects/Light/Standard/",
},
IconSize = 16,
Witdh = 18,
Height = 18,
}
}
if Settings.ClassIcon and IconList[Settings.ClassIcon] then
funcs.ExplorerIcons = {
["MapId"] = IconList[Settings.ClassIcon].MapId,
["Icons"] = IconList[Settings.ClassIcon].Icons,
["IconSize"] = IconList[Settings.ClassIcon].IconSize,
["Witdh"] = IconList[Settings.ClassIcon].Witdh,
["Height"] = IconList[Settings.ClassIcon].Height}
else
funcs.ExplorerIcons = { ["MapId"] = IconList.Old.MapId, ["Icons"] = IconList.Old.Icons, ["IconSize"] = IconList.Old.IconSize }
end
funcs.GetLabel = function(self)
local label = Instance.new("ImageLabel")
self:SetupLabel(label)
return label
end
funcs.SetupLabel = function(self,obj)
obj.BackgroundTransparency = 1
obj.ImageRectOffset = Vector2.new(0, 0)
obj.ImageRectSize = Vector2.new(self.IconSizeX, self.IconSizeY)
obj.ScaleType = Enum.ScaleType.Crop
obj.Size = UDim2.new(0, self.IconSizeX, 0, self.IconSizeY)
end
funcs.Display = function(self,obj,index)
obj.Image = self.MapId
obj.ImageRectSize = Vector2.new(self.IconSizeX, self.IconSizeY)
if not self.NumX then
obj.ImageRectOffset = Vector2.new(self.IconSizeX*index, 0)
else
obj.ImageRectOffset = Vector2.new(self.IconSizeX*(index % self.NumX), self.IconSizeY*math.floor(index / self.NumX))
end
end
funcs.DisplayByKey = function(self, obj, key)
if self.IndexDict[key] then
self:Display(obj, self.IndexDict[key])
else
local rmdEntry = RMD.Classes[obj.ClassName]
Explorer.ClassIcons:Display(obj, rmdEntry and rmdEntry.ExplorerImageIndex or 0)
end
end
funcs.IconDehash = function(self, _id)
return math.floor(_id / 14 % 14), math.floor(_id % 14)
end
local ClassNameNoImage = {}
funcs.GetExplorerIcon = function(self, obj, index)
if Settings.ClassIcon == "Vanilla3" then
obj.Size = UDim2.fromOffset(16, 16)
index = (self.ExplorerIcons.Icons[index] or 250) - 1
obj.ImageRectOffset = Vector2.new(funcs.ExplorerIcons.IconSize * (index % funcs.ExplorerIcons.Height), funcs.ExplorerIcons.IconSize * math.floor(index / funcs.ExplorerIcons.Height))
obj.ImageRectSize = Vector2.new(funcs.ExplorerIcons.IconSize, funcs.ExplorerIcons.IconSize)
elseif Settings.ClassIcon == "Old" then
index = (self.ExplorerIcons.Icons[index] or 0)
local row, col = self:IconDehash(index)
local MapSize = Vector2.new(256, 256)
local pad, border = 2, 1
obj.Position = UDim2.new(-col - (pad * (col + 1) + border) / funcs.ExplorerIcons.IconSize, 0, -row - (pad * (row + 1) + border) / funcs.ExplorerIcons.IconSize, 0)
obj.Size = UDim2.new(MapSize.X / funcs.ExplorerIcons.IconSize, 0, MapSize.Y / funcs.ExplorerIcons.IconSize, 0)
elseif Settings.ClassIcon == "NewLight" or Settings.ClassIcon == "NewDark" then
local isService = string.find(index, "Service") and game:GetService(index)
obj.Size = UDim2.fromOffset(16, 16)
index = (self.ExplorerIcons.Icons[index] or (isService and self.ExplorerIcons.Icons.Service) or self.ExplorerIcons.Icons.Placeholder) - 1
obj.ImageRectOffset = Vector2.new(funcs.ExplorerIcons.IconSize * (index % funcs.ExplorerIcons.Height), funcs.ExplorerIcons.IconSize * math.floor(index / funcs.ExplorerIcons.Height))
obj.ImageRectSize = Vector2.new(funcs.ExplorerIcons.IconSize, funcs.ExplorerIcons.IconSize)
else
index = (self.ExplorerIcons.Icons[index] or 0)
local row, col = self:IconDehash(index)
local MapSize = Vector2.new(256, 256)
local pad, border = 2, 1
obj.Position = UDim2.new(-col - (pad * (col + 1) + border) / funcs.ExplorerIcons.IconSize, 0, -row - (pad * (row + 1) + border) / funcs.ExplorerIcons.IconSize, 0)
obj.Size = UDim2.new(MapSize.X / funcs.ExplorerIcons.IconSize, 0, MapSize.Y / funcs.ExplorerIcons.IconSize, 0)
end
end
funcs.DisplayExplorerIcons = function(self, Frame, index)
if Frame:FindFirstChild("IconMap") then
self:GetExplorerIcon(Frame.IconMap, index)
else
Frame.ClipsDescendants = true
local obj = Instance.new("ImageLabel", Frame)
obj.BackgroundTransparency = 1
obj.Image = ("http://www.roblox.com/asset/?id=" .. (self.ExplorerIcons.MapId))
obj.Name = "IconMap"
self:GetExplorerIcon(obj, index)
end
end
funcs.SetDict = function(self,dict)
self.IndexDict = dict
end
local mt = {}
mt.__index = funcs
local function new(mapId,mapSizeX,mapSizeY,iconSizeX,iconSizeY)
local obj = setmetatable({
MapId = mapId,
MapSizeX = mapSizeX,
MapSizeY = mapSizeY,
IconSizeX = iconSizeX,
IconSizeY = iconSizeY,
NumX = mapSizeX/iconSizeX,
IndexDict = {}
}, mt)
return obj
end
local function newLinear(mapId,iconSizeX,iconSizeY)
local obj = setmetatable({
MapId = mapId,
IconSizeX = iconSizeX,
IconSizeY = iconSizeY,
IndexDict = {}
},mt)
return obj
end
local function getIconDataFromName(name)
return IconList[name] or error("Name not found")
end
return {new = new, newLinear = newLinear, getIconDataFromName = getIconDataFromName}
end)()
Lib.ScrollBar = (function()
local funcs = {}
local user = service.UserInputService
local mouse = plr:GetMouse()
local checkMouseInGui = Lib.CheckMouseInGui
local createArrow = Lib.CreateArrow
local function drawThumb(self)
local total = self.TotalSpace
local visible = self.VisibleSpace
local index = self.Index
local scrollThumb = self.GuiElems.ScrollThumb
local scrollThumbFrame = self.GuiElems.ScrollThumbFrame
if not (self:CanScrollUp() or self:CanScrollDown()) then
scrollThumb.Visible = false
else
scrollThumb.Visible = true
end
if self.Horizontal then
scrollThumb.Size = UDim2.new(visible/total,0,1,0)
if scrollThumb.AbsoluteSize.X < 16 then
scrollThumb.Size = UDim2.new(0,16,1,0)
end
local fs = scrollThumbFrame.AbsoluteSize.X
local bs = scrollThumb.AbsoluteSize.X
scrollThumb.Position = UDim2.new(self:GetScrollPercent()*(fs-bs)/fs,0,0,0)
else
scrollThumb.Size = UDim2.new(1,0,visible/total,0)
if scrollThumb.AbsoluteSize.Y < 16 then
scrollThumb.Size = UDim2.new(1,0,0,16)
end
local fs = scrollThumbFrame.AbsoluteSize.Y
local bs = scrollThumb.AbsoluteSize.Y
scrollThumb.Position = UDim2.new(0,0,self:GetScrollPercent()*(fs-bs)/fs,0)
end
end
local function createFrame(self)
local newFrame = createSimple("Frame",{Style=0,Active=true,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(0.35294118523598,0.35294118523598,0.35294118523598),BackgroundTransparency=0,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=0,ClipsDescendants=false,Draggable=false,Position=UDim2.new(1,-16,0,0),Rotation=0,Selectable=false,Size=UDim2.new(0,16,1,0),SizeConstraint=0,Visible=true,ZIndex=1,Name="ScrollBar",})
local button1, button2
if self.Horizontal then
newFrame.Size = UDim2.new(1,0,0,16)
button1 = createSimple("ImageButton",{
Parent = newFrame,
Name = "Left",
Size = UDim2.new(0,16,0,16),
BackgroundTransparency = 1,
BorderSizePixel = 0,
AutoButtonColor = false
})
createArrow(16,4,"left").Parent = button1
button2 = createSimple("ImageButton",{
Parent = newFrame,
Name = "Right",
Position = UDim2.new(1,-16,0,0),
Size = UDim2.new(0,16,0,16),
BackgroundTransparency = 1,
BorderSizePixel = 0,
AutoButtonColor = false
})
createArrow(16,4,"right").Parent = button2
else
newFrame.Size = UDim2.new(0,16,1,0)
button1 = createSimple("ImageButton",{
Parent = newFrame,
Name = "Up",
Size = UDim2.new(0,16,0,16),
BackgroundTransparency = 1,
BorderSizePixel = 0,
AutoButtonColor = false
})
createArrow(16,4,"up").Parent = button1
button2 = createSimple("ImageButton",{
Parent = newFrame,
Name = "Down",
Position = UDim2.new(0,0,1,-16),
Size = UDim2.new(0,16,0,16),
BackgroundTransparency = 1,
BorderSizePixel = 0,
AutoButtonColor = false
})
createArrow(16,4,"down").Parent = button2
end
local scrollThumbFrame = createSimple("ImageButton", {
BackgroundTransparency = 1,
Parent = newFrame
})
if self.Horizontal then
scrollThumbFrame.Position = UDim2.new(0,16,0,0)
scrollThumbFrame.Size = UDim2.new(1,-32,1,0)
else
scrollThumbFrame.Position = UDim2.new(0,0,0,16)
scrollThumbFrame.Size = UDim2.new(1,0,1,-32)
end
local scrollThumb = createSimple("Frame", {
BackgroundColor3 = Color3.new(120/255, 120/255, 120/255),
BorderSizePixel = 0,
Parent = scrollThumbFrame
})
local markerFrame = createSimple("Frame", {
BackgroundTransparency = 1,
Name = "Markers",
Size = UDim2.new(1, 0, 1, 0),
Parent = scrollThumbFrame
})
local buttonPress = false
local thumbPress = false
local thumbFramePress = false
local function handleButtonPress(button, scrollDirection)
if self:CanScroll(scrollDirection) then
button.BackgroundTransparency = 0.5
self:ScrollToDirection(scrollDirection)
self.Scrolled:Fire()
local buttonTick = tick()
local releaseEvent
releaseEvent = user.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
button.BackgroundTransparency = checkMouseInGui(button) and 0.8 or 1
buttonPress = false
end
end)
while buttonPress do
if tick() - buttonTick >= 0.25 and self:CanScroll(scrollDirection) then
self:ScrollToDirection(scrollDirection)
self.Scrolled:Fire()
end
task.wait()
end
end
end
button1.MouseButton1Down:Connect(function(input)
buttonPress = true
handleButtonPress(button1, "Up")
end)
button1.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
button1.BackgroundTransparency = 1
end
end)
button2.MouseButton1Down:Connect(function(input)
buttonPress = true
handleButtonPress(button2, "Down")
end)
button2.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
button2.BackgroundTransparency = 1
end
end)
scrollThumb.InputBegan:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then
local dir = self.Horizontal and "X" or "Y"
local lastThumbPos = nil
thumbPress = true
scrollThumb.BackgroundTransparency = 0
local mouseOffset = mouse[dir] - scrollThumb.AbsolutePosition[dir]
local releaseEvent
local mouseEvent
releaseEvent = user.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
if mouseEvent then mouseEvent:Disconnect() end
scrollThumb.BackgroundTransparency = 0.2
thumbPress = false
end
end)
mouseEvent = user.InputChanged:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and thumbPress then
local thumbFrameSize = scrollThumbFrame.AbsoluteSize[dir] - scrollThumb.AbsoluteSize[dir]
local pos = mouse[dir] - scrollThumbFrame.AbsolutePosition[dir] - mouseOffset
if pos > thumbFrameSize then pos = thumbFrameSize
elseif pos < 0 then pos = 0 end
if lastThumbPos ~= pos then
lastThumbPos = pos
self:ScrollTo(math.floor(0.5 + pos / thumbFrameSize * (self.TotalSpace - self.VisibleSpace)))
end
end
end)
end
end)
scrollThumb.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
scrollThumb.BackgroundTransparency = 0
end
end)
scrollThumbFrame.InputBegan:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and not checkMouseInGui(scrollThumb) then
local dir = self.Horizontal and "X" or "Y"
local scrollDir = (mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir]) and 1 or 0
local function doTick()
local scrollSize = self.VisibleSpace - 1
if scrollDir == 0 and mouse[dir] < scrollThumb.AbsolutePosition[dir] then
self:ScrollTo(self.Index - scrollSize)
elseif scrollDir == 1 and mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
self:ScrollTo(self.Index + scrollSize)
end
end
thumbPress = false
thumbFramePress = true
doTick()
local thumbFrameTick = tick()
local releaseEvent
releaseEvent = user.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
thumbFramePress = false
end
end)
while thumbFramePress do
if tick() - thumbFrameTick >= 0.3 and checkMouseInGui(scrollThumbFrame) then
doTick()
end
task.wait()
end
end
end)
newFrame.MouseWheelForward:Connect(function()
self:ScrollTo(self.Index - self.WheelIncrement)
end)
newFrame.MouseWheelBackward:Connect(function()
self:ScrollTo(self.Index + self.WheelIncrement)
end)
self.GuiElems.ScrollThumb = scrollThumb
self.GuiElems.ScrollThumbFrame = scrollThumbFrame
self.GuiElems.Button1 = button1
self.GuiElems.Button2 = button2
self.GuiElems.MarkerFrame = markerFrame
return newFrame
end
funcs.Update = function(self,nocallback)
local total = self.TotalSpace
local visible = self.VisibleSpace
local index = self.Index
local button1 = self.GuiElems.Button1
local button2 = self.GuiElems.Button2
self.Index = math.clamp(self.Index, 0, math.max(0, total - visible))
if self.LastTotalSpace ~= self.TotalSpace then
self.LastTotalSpace = self.TotalSpace
self:UpdateMarkers()
end
if self:CanScrollUp() then
for i,v in pairs(button1.Arrow:GetChildren()) do
v.BackgroundTransparency = 0
end
else
button1.BackgroundTransparency = 1
for i,v in pairs(button1.Arrow:GetChildren()) do
v.BackgroundTransparency = 0.5
end
end
if self:CanScrollDown() then
for i,v in pairs(button2.Arrow:GetChildren()) do
v.BackgroundTransparency = 0
end
else
button2.BackgroundTransparency = 1
for i,v in pairs(button2.Arrow:GetChildren()) do
v.BackgroundTransparency = 0.5
end
end
drawThumb(self)
end
funcs.UpdateMarkers = function(self)
local markerFrame = self.GuiElems.MarkerFrame
markerFrame:ClearAllChildren()
for i,v in pairs(self.Markers) do
if i < self.TotalSpace then
createSimple("Frame", {
BackgroundTransparency = 0,
BackgroundColor3 = v,
BorderSizePixel = 0,
Position = self.Horizontal and UDim2.new(i/self.TotalSpace,0,1,-6) or UDim2.new(1,-6,i/self.TotalSpace,0),
Size = self.Horizontal and UDim2.new(0,1,0,6) or UDim2.new(0,6,0,1),
Name = "Marker"..tostring(i),
Parent = markerFrame
})
end
end
end
funcs.AddMarker = function(self,ind,color)
self.Markers[ind] = color or Color3.new(0,0,0)
end
funcs.ScrollTo = function(self, ind, nocallback)
self.Index = ind
self:Update()
if not nocallback then
self.Scrolled:Fire()
end
end
funcs.ScrollUp = function(self)
self.Index = self.Index - self.Increment
self:Update()
end
funcs.CanScroll = function(self, direction)
if direction == "Up" then
return self:CanScrollUp()
elseif direction == "Down" then
return self:CanScrollDown()
end
return false
end
funcs.ScrollDown = function(self)
self.Index = self.Index + self.Increment
self:Update()
end
funcs.CanScrollUp = function(self)
return self.Index > 0
end
funcs.CanScrollDown = function(self)
return self.Index + self.VisibleSpace < self.TotalSpace
end
funcs.GetScrollPercent = function(self)
return self.Index/(self.TotalSpace-self.VisibleSpace)
end
funcs.SetScrollPercent = function(self,perc)
self.Index = math.floor(perc*(self.TotalSpace-self.VisibleSpace))
self:Update()
end
funcs.ScrollToDirection = function(self, Direaction)
if Direaction == "Up" then
self:ScrollUp()
elseif Direaction == "Down" then
self:ScrollDown()
end
end
funcs.Texture = function(self,data)
self.ThumbColor = data.ThumbColor or Color3.new(0,0,0)
self.ThumbSelectColor = data.ThumbSelectColor or Color3.new(0,0,0)
self.GuiElems.ScrollThumb.BackgroundColor3 = data.ThumbColor or Color3.new(0,0,0)
self.Gui.BackgroundColor3 = data.FrameColor or Color3.new(0,0,0)
self.GuiElems.Button1.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
self.GuiElems.Button2.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
for i,v in pairs(self.GuiElems.Button1.Arrow:GetChildren()) do
v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
end
for i,v in pairs(self.GuiElems.Button2.Arrow:GetChildren()) do
v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
end
end
funcs.SetScrollFrame = function(self,frame)
if self.ScrollUpEvent then self.ScrollUpEvent:Disconnect() self.ScrollUpEvent = nil end
if self.ScrollDownEvent then self.ScrollDownEvent:Disconnect() self.ScrollDownEvent = nil end
self.ScrollUpEvent = frame.MouseWheelForward:Connect(function() self:ScrollTo(self.Index - self.WheelIncrement) end)
self.ScrollDownEvent = frame.MouseWheelBackward:Connect(function() self:ScrollTo(self.Index + self.WheelIncrement) end)
end
local mt = {}
mt.__index = funcs
local function new(hor)
local obj = setmetatable({
Index = 0,
VisibleSpace = 0,
TotalSpace = 0,
Increment = 1,
WheelIncrement = 1,
Markers = {},
GuiElems = {},
Horizontal = hor,
LastTotalSpace = 0,
Scrolled = Lib.Signal.new()
},mt)
obj.Gui = createFrame(obj)
obj:Texture({
ThumbColor = Color3.fromRGB(60,60,60),
ThumbSelectColor = Color3.fromRGB(75,75,75),
ArrowColor = Color3.new(1,1,1),
FrameColor = Color3.fromRGB(40,40,40),
ButtonColor = Color3.fromRGB(75,75,75)
})
return obj
end
return {new = new}
end)()
Lib.Window = (function()
local funcs = {}
local static = {MinWidth = 200, FreeWidth = 200}
local mouse = plr:GetMouse()
local sidesGui,alignIndicator
local visibleWindows = {}
local leftSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
local rightSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
local displayOrderStart
local sideDisplayOrder
local sideTweenInfo = TweenInfo.new(0.3,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
local tweens = {}
local isA = game.IsA
local theme = {
MainColor1 = Color3.fromRGB(52,52,52),
MainColor2 = Color3.fromRGB(45,45,45),
Button = Color3.fromRGB(60,60,60)
}
local function stopTweens()
for i = 1,#tweens do
tweens[i]:Cancel()
end
tweens = {}
end
local function resizeHook(self,resizer,dir)
local pressing = false
local guiMain = self.GuiElems.Main
resizer.MouseEnter:Connect(function() resizer.BackgroundTransparency = 0.5 end)
resizer.MouseButton1Down:Connect(function() pressing = true resizer.BackgroundTransparency = 0.5 end)
resizer.MouseButton1Up:Connect(function() pressing = false resizer.BackgroundTransparency = 1 end)
resizer.InputBegan:Connect(function(input)
if not self.Dragging and not self.Resizing and self.Resizable and self.ResizableInternal and pressing then
local isH = dir:find("[WE]") and true
local isV = dir:find("[NS]") and true
local signX = dir:find("W",1,true) and -1 or 1
local signY = dir:find("N",1,true) and -1 or 1
if self.Minimized and isV then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
local releaseEvent, mouseEvent
local offX = input.Position.X - resizer.AbsolutePosition.X
local offY = input.Position.Y - resizer.AbsolutePosition.Y
self.Resizing = resizer
releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
if mouseEvent then mouseEvent:Disconnect() end
self.Resizing = false
resizer.BackgroundTransparency = 1
end
end)
mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
if self.Resizable and self.ResizableInternal and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
self:StopTweens()
local deltaX = input.Position.X - resizer.AbsolutePosition.X - offX
local deltaY = input.Position.Y - resizer.AbsolutePosition.Y - offY
if guiMain.AbsoluteSize.X + deltaX * signX < self.MinX then deltaX = signX * (self.MinX - guiMain.AbsoluteSize.X) end
if guiMain.AbsoluteSize.Y + deltaY * signY < self.MinY then deltaY = signY * (self.MinY - guiMain.AbsoluteSize.Y) end
if signY < 0 and guiMain.AbsolutePosition.Y + deltaY < 0 then deltaY = -guiMain.AbsolutePosition.Y end
guiMain.Position = guiMain.Position + UDim2.new(0, (signX < 0 and deltaX or 0), 0, (signY < 0 and deltaY or 0))
self.SizeX = self.SizeX + (isH and deltaX * signX or 0)
self.SizeY = self.SizeY + (isV and deltaY * signY or 0)
guiMain.Size = UDim2.new(0, self.SizeX, 0, self.Minimized and 20 or self.SizeY)
end
end)
end
end
end)
resizer.InputEnded:Connect(function(input)
--if input.UserInputType == Enum.UserInputType.Touch and Main.AllowDraggableOnMobile == false then return end
if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and self.Resizing ~= resizer then
resizer.BackgroundTransparency = 1
end
end)
end
local updateWindows
local function moveToTop(window)
local found = table.find(visibleWindows,window)
if found then
table.remove(visibleWindows,found)
table.insert(visibleWindows,1,window)
updateWindows()
end
end
local function sideHasRoom(side,neededSize)
local maxY = sidesGui.AbsoluteSize.Y - (math.max(0,#side.Windows - 1) * 4)
local inc = 0
for i,v in pairs(side.Windows) do
inc = inc + (v.MinY or 100)
if inc > maxY - neededSize then return false end
end
return true
end
local function getSideInsertPos(side,curY)
local pos = #side.Windows + 1
local range = {0,sidesGui.AbsoluteSize.Y}
for i,v in pairs(side.Windows) do
local midPos = v.PosY + v.SizeY/2
if curY <= midPos then
pos = i
range[2] = midPos
break
else
range[1] = midPos
end
end
return pos,range
end
local function focusInput(self,obj)
if isA(obj,"GuiButton") then
obj.MouseButton1Down:Connect(function()
moveToTop(self)
end)
elseif isA(obj,"TextBox") then
obj.Focused:Connect(function()
moveToTop(self)
end)
end
end
local createGui = function(self)
local gui = create({
{1,"ScreenGui",{Name="Window",}},
{2,"Frame",{Active=true,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Main",Parent={1},Position=UDim2.new(0.40000000596046,0,0.40000000596046,0),Size=UDim2.new(0,300,0,300),}},
--[[background mod set to 0.05]] {3,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,Name="Content",Parent={2},Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),ClipsDescendants=true}},
{4,"Frame",{BackgroundColor3=Color3.fromRGB(33,33,33),BorderSizePixel=0,Name="Line",Parent={3},Size=UDim2.new(1,0,0,1),}},
{5,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="TopBar",Parent={2},Size=UDim2.new(1,0,0,20),Text = ""}},
{6,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={5},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,20),Text="Window",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0}},
{7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Close",Parent={5},Position=UDim2.new(1,-18,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
{8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5054663650",Parent={7},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
{9,"UICorner",{CornerRadius=UDim.new(0,4),Parent={7},}},
--[[lol mod]] {9,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
{10,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Minimize",Parent={5},Position=UDim2.new(1,-36,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
{11,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034768003",Parent={10},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
{12,"UICorner",{CornerRadius=UDim.new(0,4),Parent={10},}},
{13,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1427967925",Name="Outlines",Parent={2},Position=UDim2.new(0,-5,0,-5),ScaleType=1,Size=UDim2.new(1,10,1,10),SliceCenter=Rect.new(6,6,25,25),TileSize=UDim2.new(0,20,0,20),}},
{14,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="ResizeControls",Parent={2},Position=UDim2.new(0,-5,0,-5),Size=UDim2.new(1,10,1,10),}},
{15,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="North",Parent={14},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{16,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="South",Parent={14},Position=UDim2.new(0,5,1,-5),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{17,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthEast",Parent={14},Position=UDim2.new(1,-5,0,0),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{18,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="East",Parent={14},Position=UDim2.new(1,-5,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{19,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="West",Parent={14},Position=UDim2.new(0,0,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{20,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthEast",Parent={14},Position=UDim2.new(1,-5,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{21,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthWest",Parent={14},Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
{22,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthWest",Parent={14},Position=UDim2.new(0,0,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
})
local guiMain = gui.Main
local guiTopBar = guiMain.TopBar
local guiResizeControls = guiMain.ResizeControls
self.GuiElems.Main = guiMain
self.GuiElems.TopBar = guiMain.TopBar
self.GuiElems.Content = guiMain.Content
self.GuiElems.Line = guiMain.Content.Line
self.GuiElems.Outlines = guiMain.Outlines
self.GuiElems.Title = guiTopBar.Title
self.GuiElems.Close = guiTopBar.Close
self.GuiElems.Minimize = guiTopBar.Minimize
self.GuiElems.ResizeControls = guiResizeControls
self.ContentPane = guiMain.Content
-- dont mind this, im testing what if the frame background is blurry
--blur.new(guiMain.Content, "Rectangle")
--blur.updateAll()
local ButtonDown = false
guiTopBar.MouseButton1Down:Connect(function() ButtonDown = true end)
guiTopBar.MouseButton1Up:Connect(function() ButtonDown = false end)
if Settings.Window.TitleOnMiddle then
self.GuiElems.Title.TextXAlignment = 2
self.GuiElems.Title.Size = UDim2.new(1,-20,0,20)
end
if Settings.Window.Transparency then
self.GuiElems.Content.BackgroundTransparency = Settings.Window.Transparency
--self.GuiElems
end
guiTopBar.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
if self.Draggable then
local releaseEvent, mouseEvent
local maxX = sidesGui.AbsoluteSize.X
local initX = guiMain.AbsolutePosition.X
local initY = guiMain.AbsolutePosition.Y
local offX = input.Position.X - initX
local offY = input.Position.Y - initY
local alignInsertPos, alignInsertSide
guiDragging = true
releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
if mouseEvent then mouseEvent:Disconnect() end
guiDragging = false
alignIndicator.Parent = nil
if alignInsertSide then
local targetSide = (alignInsertSide == "left" and leftSide) or (alignInsertSide == "right" and rightSide)
self:AlignTo(targetSide, alignInsertPos)
end
end
end)
mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) and self.Draggable and not self.Closed and ButtonDown then
if self.Aligned then
if leftSide.Resizing or rightSide.Resizing then return end
local posX, posY = input.Position.X - offX, input.Position.Y - offY
local delta = math.sqrt((posX - initX)^2 + (posY - initY)^2)
if delta >= 5 then
self:SetAligned(false)
end
else
local inputX, inputY = input.Position.X, input.Position.Y
local posX, posY = inputX - offX, inputY - offY
if posY < 0 then posY = 0 end
guiMain.Position = UDim2.new(0, posX, 0, posY)
if self.Resizable and self.Alignable then
if inputX < 25 then
if sideHasRoom(leftSide, self.MinY or 100) then
local insertPos, range = getSideInsertPos(leftSide, inputY)
alignIndicator.Indicator.Position = UDim2.new(0, -15, 0, range[1])
alignIndicator.Indicator.Size = UDim2.new(0, 40, 0, range[2] - range[1])
Lib.ShowGui(alignIndicator)
alignInsertPos = insertPos
alignInsertSide = "left"
return
end
elseif inputX >= maxX - 25 then
if sideHasRoom(rightSide, self.MinY or 100) then
local insertPos, range = getSideInsertPos(rightSide, inputY)
alignIndicator.Indicator.Position = UDim2.new(0, maxX - 25, 0, range[1])
alignIndicator.Indicator.Size = UDim2.new(0, 40, 0, range[2] - range[1])
Lib.ShowGui(alignIndicator)
alignInsertPos = insertPos
alignInsertSide = "right"
return
end
end
end
alignIndicator.Parent = nil
alignInsertPos = nil
alignInsertSide = nil
end
end
end)
end
end
end)
guiTopBar.Close.MouseButton1Click:Connect(function()
if self.Closed then return end
self:Close()
end)
guiTopBar.Minimize.MouseButton1Click:Connect(function()
if self.Closed then return end
if self.Aligned then
self:SetAligned(false)
else
self:SetMinimized()
end
end)
guiTopBar.Minimize.MouseButton2Click:Connect(function()
if self.Closed then return end
if not self.Aligned then
self:SetMinimized(nil,2)
guiTopBar.Minimize.BackgroundTransparency = 1
end
end)
guiMain.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch and not self.Aligned and not self.Closed then
moveToTop(self)
end
end)
guiMain:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
local absPos = guiMain.AbsolutePosition
self.PosX = absPos.X
self.PosY = absPos.Y
end)
resizeHook(self,guiResizeControls.North,"N")
resizeHook(self,guiResizeControls.NorthEast,"NE")
resizeHook(self,guiResizeControls.East,"E")
resizeHook(self,guiResizeControls.SouthEast,"SE")
resizeHook(self,guiResizeControls.South,"S")
resizeHook(self,guiResizeControls.SouthWest,"SW")
resizeHook(self,guiResizeControls.West,"W")
resizeHook(self,guiResizeControls.NorthWest,"NW")
guiMain.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
gui.DescendantAdded:Connect(function(obj) focusInput(self,obj) end)
local descs = gui:GetDescendants()
for i = 1,#descs do
focusInput(self,descs[i])
end
self.MinimizeAnim = Lib.ButtonAnim(guiTopBar.Minimize)
self.CloseAnim = Lib.ButtonAnim(guiTopBar.Close)
return gui
end
local function updateSideFrames(noTween)
stopTweens()
leftSide.Frame.Size = UDim2.new(0,leftSide.Width,1,0)
rightSide.Frame.Size = UDim2.new(0,rightSide.Width,1,0)
leftSide.Frame.Resizer.Position = UDim2.new(0,leftSide.Width,0,0)
rightSide.Frame.Resizer.Position = UDim2.new(0,-5,0,0)
--leftSide.Frame.Visible = (#leftSide.Windows > 0)
--rightSide.Frame.Visible = (#rightSide.Windows > 0)
--[[if #leftSide.Windows > 0 and leftSide.Frame.Position == UDim2.new(0,-leftSide.Width-5,0,0) then
leftSide.Frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
elseif #leftSide.Windows == 0 and leftSide.Frame.Position == UDim2.new(0,0,0,0) then
leftSide.Frame:TweenPosition(UDim2.new(0,-leftSide.Width-5,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
end
local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
local leftPos = (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
local rightPos = (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
sidesGui.LeftToggle.Text = leftHidden and ">" or "<"
sidesGui.RightToggle.Text = rightHidden and "<" or ">"
if not noTween then
local function insertTween(...)
local tween = service.TweenService:Create(...)
tweens[#tweens+1] = tween
tween:Play()
end
insertTween(leftSide.Frame,sideTweenInfo,{Position = leftPos})
insertTween(rightSide.Frame,sideTweenInfo,{Position = rightPos})
insertTween(sidesGui.LeftToggle,sideTweenInfo,{Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)})
insertTween(sidesGui.RightToggle,sideTweenInfo,{Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)})
else
leftSide.Frame.Position = leftPos
rightSide.Frame.Position = rightPos
sidesGui.LeftToggle.Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)
sidesGui.RightToggle.Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)
end
end
local function getSideFramePos(side)
local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
if side == leftSide then
return (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
else
return (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
end
end
local function sideResized(side)
local currentPos = 0
local sideFramePos = getSideFramePos(side)
for i,v in pairs(side.Windows) do
v.SizeX = side.Width
v.GuiElems.Main.Size = UDim2.new(0,side.Width,0,v.SizeY)
v.GuiElems.Main.Position = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
currentPos = currentPos + v.SizeY+4
end
end
local function sideResizerHook(resizer,dir,side,pos)
local pressing = false
local mouse = Main.Mouse
local windows = side.Windows
resizer.MouseEnter:Connect(function() resizer.BackgroundColor3 = theme.MainColor2 end)
resizer.MouseButton1Down:Connect(function() pressing = true resizer.BackgroundColor3 = theme.MainColor2 end)
resizer.MouseButton1Up:Connect(function() pressing = false resizer.BackgroundColor3 = theme.Button end)
resizer.InputBegan:Connect(function(input)
if not side.Resizing and pressing then
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
resizer.BackgroundColor3 = theme.MainColor2
end
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
local releaseEvent,mouseEvent
local offX = mouse.X - resizer.AbsolutePosition.X
local offY = mouse.Y - resizer.AbsolutePosition.Y
side.Resizing = resizer
resizer.BackgroundColor3 = theme.MainColor2
releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
releaseEvent:Disconnect()
mouseEvent:Disconnect()
side.Resizing = false
resizer.BackgroundColor3 = theme.Button
end
end)
mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
if not resizer.Parent then
releaseEvent:Disconnect()
mouseEvent:Disconnect()
side.Resizing = false
return
end
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
if dir == "V" then
local delta = input.Position.Y - resizer.AbsolutePosition.Y - offY
if delta > 0 then
local neededSize = delta
for i = pos+1,#windows do
local window = windows[i]
local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
neededSize = neededSize - (window.SizeY - newSize)
window.SizeY = newSize
end
windows[pos].SizeY = windows[pos].SizeY + math.max(0,delta-neededSize)
else
local neededSize = -delta
for i = pos,1,-1 do
local window = windows[i]
local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
neededSize = neededSize - (window.SizeY - newSize)
window.SizeY = newSize
end
windows[pos+1].SizeY = windows[pos+1].SizeY + math.max(0,-delta-neededSize)
end
updateSideFrames()
sideResized(side)
elseif dir == "H" then
local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
local otherSide = (side == leftSide and rightSide or leftSide)
local delta = input.Position.X - resizer.AbsolutePosition.X - offX
delta = (side == leftSide and delta or -delta)
local proposedSize = math.max(static.MinWidth,side.Width + delta)
if proposedSize + otherSide.Width <= maxWidth then
side.Width = proposedSize
else
local newOtherSize = maxWidth - proposedSize
if newOtherSize >= static.MinWidth then

Universal