Advertisement
CloneTrooper1019

Roblox Studio Core-Script Command Bar

Jan 31st, 2016
8,262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.11 KB | None | 0 0
  1. -------------------------------------------------------------------------------------------------------------------------------------
  2. -- @CloneTrooper1019, 2015-2016
  3. -- CoreScript Command Bar
  4. -- Allows you to use members that are normally locked down to RobloxScriptSecurity (ROBLOX STUDIO ONLY)
  5. -- Will probably get patched at some point, do not abuse :<
  6.  
  7. -- INSTALLATION:
  8. -- Go to the file directory for Roblox Studio
  9. -- Open content/scripts/StarterScript.lua
  10. -- Paste the contents of this script into there.
  11. -- (Protip: Use my Roblox Studio Mod Manager and you won't have to worry about updating this everytime Roblox Studio updates:
  12. --  https://github.com/CloneTrooper1019/Roblox-Studio-Mod-Manager)
  13.  
  14. -- CONTROLS:
  15. -- Press the ~ key to toggle the command bar
  16. -- Scroll up and down on the command bar to scroll through your history of command executions (current session only)
  17.  
  18. -- Handy resource:
  19. -- http://wiki.roblox.com/index.php?title=Hidden_Members#RobloxScriptSecurity
  20.  
  21. -------------------------------------------------------------------------------------------------------------------------------------
  22. -- Preload Default StarterScript
  23. -- (just to make sure we aren't behind or anything)
  24. -------------------------------------------------------------------------------------------------------------------------------------
  25.  
  26. local http = game:GetService("HttpService")
  27.  
  28. local enabledState = http.HttpEnabled
  29. http.HttpEnabled = true
  30.  
  31. local starterScript = http:GetAsync("https://raw.githubusercontent.com/ROBLOX/Core-Scripts/master/CoreScriptsRoot/StarterScript.lua")
  32. http.HttpEnabled = enabledState
  33.  
  34. -- The github repository may not be the version that is actually on production.
  35. -- Because of this, it may attempt to load CoreScripts that don't actually exist.
  36. -- To fix this, I'm just wrapping all invokes of that function into a pcall.
  37.  
  38. starterScript = [[local function pspawn(func,...)
  39.     local b = Instance.new("BindableEvent")
  40.     b.Event:connect(function (...)
  41.         pcall(func,...)
  42.     end)
  43.     b:Fire(...)
  44. end
  45.  
  46. ]]..starterScript:gsub("scriptContext:AddCoreScriptLocal%(","pspawn(scriptContext.AddCoreScriptLocal,scriptContext,")
  47.  
  48. loadstring(starterScript)()
  49.  
  50. -------------------------------------------------------------------------------------------------------------------------------------
  51. -- Setup
  52. -------------------------------------------------------------------------------------------------------------------------------------
  53.  
  54. local coreGui = game:GetService("CoreGui")
  55. local robloxGui = coreGui:WaitForChild("RobloxGui")
  56. local userInput = game:GetService("UserInputService")
  57. local guiService = game:GetService("GuiService")
  58. local rs = game:GetService("RunService")
  59. local history = {}
  60.  
  61. spawn(function ()
  62.     local controlFrame = robloxGui:WaitForChild("ControlFrame",5)
  63.     if controlFrame then
  64.         local toggleDevConsole = Instance.new("BindableFunction")
  65.         toggleDevConsole.Name = "ToggleDevConsole"
  66.         toggleDevConsole.Parent = controlFrame
  67.     end
  68. end)
  69.  
  70. local cmd = Instance.new("TextBox",robloxGui)
  71. cmd.Name = "Cmd"
  72. cmd.Size = UDim2.new(1,0,0,29)
  73. cmd.Position = UDim2.new(0,0,1,0)
  74. cmd.TextXAlignment = "Left"
  75. cmd.FontSize = Enum.FontSize.Size28
  76. cmd.Font = "SourceSans"
  77. cmd.Text = ""
  78.  
  79. -------------------------------------------------------------------------------------------------------------------------------------
  80. -- Input and Tweening
  81. -------------------------------------------------------------------------------------------------------------------------------------
  82.  
  83. local inset = 0
  84. local goalInset = 0
  85. local isActive = false
  86.  
  87. local function moveTowards(value,goal,rate)
  88.     if value < goal then
  89.         return math.min(goal,value + rate)
  90.     elseif value > goal then
  91.         return math.max(goal,value - rate)
  92.     else
  93.         return goal
  94.     end
  95. end
  96.  
  97. local function renderUpdate()
  98.     if inset ~= goalInset then
  99.         local yOffset = 0
  100.         if robloxGui:FindFirstChild("TopBarContainer") then
  101.             yOffset = robloxGui.TopBarContainer.Size.Y.Offset
  102.         end
  103.         inset = moveTowards(inset,goalInset,6)
  104.         guiService:SetGlobalGuiInset(0,yOffset,0,inset)
  105.     end
  106. end
  107.  
  108. local function setActive(active)
  109.     isActive = active
  110.     if isActive then
  111.         goalInset = 30
  112.         cmd:CaptureFocus()
  113.     else
  114.         goalInset = 0
  115.         cmd:ReleaseFocus()
  116.         cmd.Text = ""
  117.     end
  118. end
  119.  
  120. local function onInputBegan(input)
  121.     if input.KeyCode == Enum.KeyCode.Backquote then
  122.         setActive(not isActive)
  123.     end
  124. end
  125.  
  126. spawn(function ()
  127.     local topBar = robloxGui:WaitForChild("TopBarContainer",5)
  128.     if topBar then
  129.         inset = inset - 1 -- bump the inset
  130.     end
  131. end)
  132.  
  133. rs:BindToRenderStep(http:GenerateGUID(),0,renderUpdate)
  134. userInput.InputBegan:connect(onInputBegan)
  135.  
  136. -------------------------------------------------------------------------------------------------------------------------------------
  137. -- Syntax Highlighting
  138. -------------------------------------------------------------------------------------------------------------------------------------
  139. local primitivesRaw = "and break do else elseif end false for function if in local nil not or repeat return then true until while"
  140. local operators = "+ - * / %% ^ # = ~ < > %( %) { } %[ %] ; : , %."
  141. local env = getfenv()
  142. local studio = settings().Studio
  143.  
  144. local primitives = {}
  145. for primitive in primitivesRaw:gmatch("[^ ]+") do
  146.     primitives[primitive] = true
  147. end
  148.  
  149. local deprecatedBuiltInKeywords =
  150. {
  151.     Game = true;
  152.     PluginManager = true;
  153.     settings = true;
  154.     Workspace = true;
  155. }
  156.  
  157. local function isPrimitiveKeyword(keyword,s)
  158.     return primitives[keyword]
  159. end
  160.  
  161. local function isBuiltInKeyword(keyword)
  162.     return (env[keyword] ~= nil and rawget(env,keyword) == nil and not deprecatedBuiltInKeywords[keyword])
  163. end
  164.  
  165. local function indexGmatch(str,pattern)
  166.     local indexAt = 1
  167.     return function ()
  168.         local startIndex,endIndex = str:find(pattern,indexAt)
  169.         if startIndex and endIndex and startIndex <= endIndex then
  170.             indexAt = endIndex + 1
  171.             return startIndex,endIndex,str:sub(startIndex,endIndex)
  172.         end
  173.     end
  174. end
  175.  
  176. -- Main --
  177.  
  178. local blankC3 = Color3.new()
  179.  
  180. local function syntaxHighlight(str,fontSize)
  181.     -- Update colors
  182.  
  183.     local backgroundColor       = studio["Background Color"]
  184.     local builtInFunctionColor  = studio["Built-in Function Color"]
  185.     local commentColor          = studio["Comment Color"]
  186.     local keywordColor          = studio["Keyword Color"]
  187.     local numberColor           = studio["Number Color"]
  188.     local operatorColor         = studio["Operator Color"]
  189.     local stringColor           = studio["String Color"]
  190.     local textColor             = studio["Text Color"]
  191.    
  192.     cmd.BackgroundColor3 = backgroundColor
  193.     cmd.BorderColor3 = blankC3:lerp(Color3.new(1-backgroundColor.r,1-backgroundColor.g,1-backgroundColor.b),0.4)
  194.     cmd.TextColor3 = cmd.BorderColor3
  195.    
  196.  
  197.     -- Build the individual characters
  198.  
  199.     local fontHeight = tonumber(fontSize.Name:match("%d+$"))
  200.     local charMap = {}
  201.     local activeWidth = 0
  202.    
  203.     for _,v in pairs(cmd:GetChildren()) do
  204.         if tonumber(v.Name) then
  205.             v:Destroy()
  206.         end
  207.     end
  208.    
  209.     for char in str:gmatch(".") do
  210.         local label = Instance.new("TextLabel",cmd)
  211.         label.BackgroundTransparency = 1
  212.         label.FontSize = fontSize
  213.         label.Font = "SourceSans"
  214.         label.Text = ((char == "\n" or char == "\t") and " " or char)
  215.         label.TextColor3 = textColor
  216.         label.ZIndex = 2
  217.         local bounds = label.TextBounds
  218.         label.Size = UDim2.new(0,bounds.X,0,bounds.Y)
  219.         label.Position = UDim2.new(0,activeWidth-1,0,1)
  220.         activeWidth = activeWidth + bounds.X
  221.         table.insert(charMap,{
  222.             Character = char;
  223.             Label = label;
  224.         })
  225.         label.Name = #charMap
  226.     end
  227.    
  228.     local function markCharMap(tag,color,startIndex,endIndex,setBold)
  229.         for i = startIndex,endIndex do
  230.             local char = charMap[i]
  231.             char[tag] = true
  232.             char.Label.TextColor3 = color
  233.             if setBold ~= nil then
  234.                 if setBold then
  235.                     char.Label.Font = "SourceSansBold"
  236.                 else
  237.                     char.Label.Font = "SourceSans"
  238.                 end
  239.             end
  240.         end
  241.     end
  242.    
  243.     -- Process Numbers
  244.    
  245.     for startIndex,endIndex in indexGmatch(str,"%d+") do
  246.         local canMark = true
  247.         if startIndex-1 > 0 then
  248.             local charToLeft = str:sub(startIndex-1,startIndex-1)
  249.             if charToLeft:match("%w") then
  250.                 canMark = false
  251.             end
  252.         end
  253.         if canMark then
  254.             while endIndex < #str do
  255.                 local n = endIndex + 1
  256.                 if str:sub(n,n):match("[%s%)%}%]]") then
  257.                     break
  258.                 else
  259.                     endIndex = n
  260.                 end
  261.             end
  262.             markCharMap("Number",numberColor,startIndex,endIndex)
  263.         end
  264.     end
  265.    
  266.     -- Process built-in functions and primitives.
  267.    
  268.     for startIndex,endIndex,keyword in indexGmatch(str,"%w+") do
  269.         if #keyword > 1 then
  270.             if isPrimitiveKeyword(keyword) then
  271.                 markCharMap("Primitive",keywordColor,startIndex,endIndex,true)
  272.             elseif isBuiltInKeyword(keyword) then
  273.                 local canMark = true
  274.                 if startIndex-1 > 0 then
  275.                     local char = str:sub(startIndex-1,startIndex-1)
  276.                     if char == "." or char == ":" then
  277.                         canMark = false
  278.                     end
  279.                 end
  280.                 if canMark then
  281.                     markCharMap("BuiltIn",builtInFunctionColor,startIndex,endIndex,true)
  282.                 end
  283.             end
  284.         end
  285.     end
  286.    
  287.     -- Process basic strings
  288.    
  289.     local i = 1
  290.     local readingStr = false
  291.     local activeChar = ""
  292.    
  293.     while i <= #str do
  294.         local char = str:sub(i,i)
  295.         if char == '"' or char == "'" then
  296.             markCharMap("String",stringColor,i,i,false)
  297.             if not readingStr then
  298.                 readingStr = true
  299.                 activeChar = char
  300.             elseif activeChar == char then
  301.                 readingStr = false
  302.             end
  303.         end
  304.         if readingStr then
  305.             markCharMap("String",stringColor,i,i,false)
  306.             if char == "\\" then
  307.                 -- Mark the next character as a string and skip it.
  308.                 -- Don't even ask questions.
  309.                 i = i + 1
  310.                 if i <= #str then
  311.                     markCharMap("String",stringColor,i,i,false)
  312.                 end
  313.             elseif char == "\n" then
  314.                 -- Code execution will result in an error, but stop reading anyway.
  315.                 readingStr = false
  316.                 activeChar = ""
  317.             end
  318.         end
  319.         i = i + 1
  320.     end
  321.    
  322.     -- Process Blocks
  323.  
  324.     local i = 1
  325.     local startBlock = ""
  326.     local inBlock = false
  327.    
  328.     while i <= #str do
  329.         local char = str:sub(i,i)
  330.         if char == "[" then
  331.             local startedAt = i
  332.             local invalid = false
  333.             startBlock = "["
  334.             while true do
  335.                 i = i + 1
  336.                 if i > #str then
  337.                     break
  338.                 end
  339.                 local nextChar = str:sub(i,i)
  340.                 startBlock = startBlock .. nextChar
  341.                 if nextChar == "[" then
  342.                     break
  343.                 elseif nextChar ~= "=" then
  344.                     invalid = true
  345.                     break
  346.                 end
  347.             end
  348.             if not invalid and #startBlock > 1 then
  349.                 local endBlock = startBlock:gsub("%[","%]")
  350.                 local endedAt = #str
  351.                 local ebStart,ebEnd = str:find(endBlock,startedAt)
  352.                 if ebStart and ebEnd and ebStart < ebEnd then
  353.                     endedAt = ebEnd
  354.                     i = ebEnd
  355.                 end
  356.                 markCharMap("Block",stringColor,startedAt,endedAt,false)
  357.             end
  358.         end
  359.         i = i + 1
  360.     end
  361.  
  362.     -- Process Comments
  363.    
  364.     local inBlock = false
  365.    
  366.     for startIndex,endIndex,comment in indexGmatch(str,"%-%-") do
  367.         if not charMap[startIndex].Block then
  368.             while endIndex < #str do
  369.                 endIndex = endIndex + 1
  370.                 local char = charMap[endIndex].Character
  371.                 if charMap[endIndex].Block then
  372.                     inBlock = true
  373.                 elseif inBlock or char == "\n" then
  374.                     break
  375.                 end
  376.             end
  377.             markCharMap("Comment",commentColor,startIndex,endIndex,false)
  378.         end
  379.     end
  380.        
  381.     -- Process Operators
  382.    
  383.     for operator in operators:gmatch("[^ ]+") do
  384.         for startIndex,endIndex in indexGmatch(str,operator) do
  385.             local m = charMap[startIndex]
  386.             if not m.Comment and not m.Block and not m.String and not m.Number then
  387.                 markCharMap("Operator",operatorColor,startIndex,endIndex)
  388.             end
  389.         end
  390.     end
  391.  
  392.     lastCharTyped = tick()
  393. end
  394.  
  395. local function onChanged(property)
  396.     if property == "Text" or pcall(function () return studio[property] end) then
  397.         syntaxHighlight(cmd.Text,cmd.FontSize)
  398.     end
  399. end
  400.  
  401. onChanged("Text")
  402. cmd.Changed:connect(onChanged)
  403. studio.Changed:connect(onChanged)
  404.  
  405. --------------------------------------------------------------------------------------------------------------------------------------
  406. -- Command Execution
  407. --------------------------------------------------------------------------------------------------------------------------------------
  408. local historyIndex = -1
  409.  
  410. local function onMouseWheelBackward()
  411.     if isActive then
  412.         if historyIndex == -1 then
  413.             historyIndex = 1
  414.         else
  415.             historyIndex = math.min(#history,historyIndex+1)
  416.         end
  417.         if history[historyIndex] then
  418.             cmd.Text = history[historyIndex]
  419.         end
  420.     end
  421. end
  422.  
  423. local function onMouseWheelForward()
  424.     if isActive then
  425.         if historyIndex == -1 then
  426.             historyIndex = #history
  427.         else
  428.             historyIndex = math.max(1,historyIndex-1)
  429.         end
  430.         if history[historyIndex] then
  431.             cmd.Text = history[historyIndex]
  432.         end
  433.     end
  434. end
  435.  
  436. local function onFocusLost(enterPressed)
  437.     if enterPressed then
  438.         historyIndex = -1
  439.         local text = cmd.Text
  440.         if #text > 0 then
  441.             table.insert(history,text)
  442.             warn(">",text)
  443.             spawn(function ()
  444.                 local func,errorMsg = loadstring(text)
  445.                 if func then
  446.                     func()
  447.                 else
  448.                     error("Error in script: "..errorMsg)
  449.                 end
  450.             end)
  451.         end
  452.     end
  453.     if historyIndex == -1 then
  454.         setActive(false)
  455.     end
  456. end
  457.  
  458. cmd.FocusLost:connect(onFocusLost)
  459. cmd.MouseWheelBackward:connect(onMouseWheelBackward)
  460. cmd.MouseWheelForward:connect(onMouseWheelForward)
  461. --------------------------------------------------------------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement