Created
January 29, 2023 19:44
-
-
Save regginator/f3a81b457b5aaf1aa4d4ba2ef3c190e0 to your computer and use it in GitHub Desktop.
Boatbomber Highlighter Packed with Maui
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This script was automatically @generated by Maui, it is not intended for manual editing. | |
local ModuleRoot = { | |
{ | |
ClassName = "ModuleScript", | |
Closure = function() export type HighlighterColors = { [string]: Color3 } | |
export type TextObject = TextLabel | TextBox | |
export type HighlightProps = { | |
textObject: TextObject, | |
src: string?, | |
forceUpdate: boolean?, | |
lexer: Lexer?, | |
customLang: { [string]: string }? | |
} | |
export type Lexer = { | |
scan: (src: string) -> () -> (string, string), | |
navigator: () -> any, | |
finished: boolean?, | |
} | |
export type Highlighter = { | |
defaultLexer: Lexer, | |
setTokenColors: (colors: HighlighterColors?) -> (), | |
highlight: (props: HighlightProps) -> (() -> ())?, | |
refresh: () -> (), | |
} | |
export type ObjectData = { | |
Text: string, | |
Labels: { TextLabel }, | |
Lines: { string }, | |
Lexer: Lexer?, | |
CustomLang: { [string]: string }?, | |
} | |
local function SanitizeRichText(s: string): string | |
return string.gsub( | |
string.gsub(string.gsub(string.gsub(string.gsub(s, "&", "&"), "<", "<"), ">", ">"), '"', """), | |
"'", | |
"'" | |
) | |
end | |
local function SanitizeTabs(s: string): string | |
return string.gsub(s, "\t", " ") | |
end | |
local function SanitizeControl(s: string): string | |
return string.gsub(s, "[\0\1\2\3\4\5\6\7\8\11\12\13\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31]+", "") | |
end | |
local TokenColors: HighlighterColors = { | |
["background"] = Color3.fromRGB(47, 47, 47), | |
["iden"] = Color3.fromRGB(234, 234, 234), | |
["keyword"] = Color3.fromRGB(215, 174, 255), | |
["builtin"] = Color3.fromRGB(131, 206, 255), | |
["string"] = Color3.fromRGB(196, 255, 193), | |
["number"] = Color3.fromRGB(255, 125, 125), | |
["comment"] = Color3.fromRGB(140, 140, 155), | |
["operator"] = Color3.fromRGB(255, 239, 148), | |
["custom"] = Color3.fromRGB(119, 122, 255), | |
} | |
local ColorFormatter: { [Color3]: string } = {} | |
local LastData: { [TextObject]: ObjectData } = {} | |
local Cleanups: { [TextObject]: () -> () } = {} | |
local Highlighter = { | |
defaultLexer = require(script.lexer), | |
} | |
function Highlighter.highlight(props: HighlightProps) | |
-- Gather props | |
local textObject = props.textObject | |
local src = SanitizeTabs(SanitizeControl(props.src or textObject.Text)) | |
local lexer = props.lexer or Highlighter.defaultLexer | |
local customLang = props.customLang | |
local forceUpdate = props.forceUpdate | |
-- Avoid updating when unnecessary | |
local data = LastData[textObject] | |
if data == nil then | |
data = { | |
Text = "", | |
Labels = {}, | |
Lines = {}, | |
Lexer = lexer, | |
CustomLang = customLang, | |
} | |
LastData[textObject] = data | |
elseif forceUpdate ~= true and data.Text == src then | |
return | |
end | |
local lineLabels = data.Labels | |
local previousLines = data.Lines | |
local lines = string.split(src, "\n") | |
data.Lines = lines | |
data.Text = src | |
data.Lexer = lexer | |
data.CustomLang = customLang | |
-- Ensure valid object properties | |
textObject.RichText = false | |
textObject.Text = src | |
textObject.TextXAlignment = Enum.TextXAlignment.Left | |
textObject.TextYAlignment = Enum.TextYAlignment.Top | |
textObject.BackgroundColor3 = TokenColors.background | |
textObject.TextColor3 = TokenColors.iden | |
textObject.TextTransparency = 0.5 | |
-- Build the highlight labels | |
local lineFolder = textObject:FindFirstChild("SyntaxHighlights") | |
if lineFolder == nil then | |
local newLineFolder = Instance.new("Folder") | |
newLineFolder.Name = "SyntaxHighlights" | |
newLineFolder.Parent = textObject | |
lineFolder = newLineFolder | |
end | |
-- Add a cleanup handler for this textObject | |
local cleanup = Cleanups[textObject] | |
if not cleanup then | |
local connections: { RBXScriptConnection } = {} | |
local function newCleanup() | |
for _, label in ipairs(lineLabels) do | |
label:Destroy() | |
end | |
table.clear(lineLabels) | |
lineLabels = nil | |
LastData[textObject] = nil | |
Cleanups[textObject] = nil | |
for _, connection in connections do | |
connection:Disconnect() | |
end | |
table.clear(connections) | |
connections = nil | |
end | |
Cleanups[textObject] = newCleanup | |
cleanup = newCleanup | |
table.insert( | |
connections, | |
textObject.AncestryChanged:Connect(function() | |
if textObject.Parent then | |
return | |
end | |
cleanup() | |
end) | |
) | |
table.insert( | |
connections, | |
textObject:GetPropertyChangedSignal("TextBounds"):Connect(function() | |
Highlighter.highlight({ | |
textObject = textObject, | |
forceUpdate = true, | |
lexer = lexer, | |
customLang = customLang, | |
}) | |
end) | |
) | |
table.insert( | |
connections, | |
textObject:GetPropertyChangedSignal("Text"):Connect(function() | |
Highlighter.highlight({ | |
textObject = textObject, | |
lexer = lexer, | |
customLang = customLang, | |
}) | |
end) | |
) | |
table.insert( | |
connections, | |
textObject:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() | |
Highlighter.highlight({ | |
textObject = textObject, | |
forceUpdate = true, | |
lexer = lexer, | |
customLang = customLang, | |
}) | |
end) | |
) | |
end | |
-- Shortcut empty labels | |
if src == "" then | |
for l=1, #lineLabels do | |
if lineLabels[l].Text == "" then continue end | |
lineLabels[l].Text = "" | |
end | |
return cleanup | |
end | |
-- Wait for TextBounds to be non-NaN and non-zero because Roblox | |
local textBounds = textObject.TextBounds | |
while (textBounds.Y ~= textBounds.Y) or (textBounds.Y < 1) do | |
task.wait() | |
textBounds = textObject.TextBounds | |
end | |
if LastData[textObject] == nil then | |
-- Got cleaned up while we were waiting | |
return cleanup | |
end | |
local numLines = #lines | |
local textHeight = textBounds.Y / numLines * textObject.LineHeight | |
local richText, index, lineNumber = table.create(5), 0, 1 | |
for token: string, content: string in lexer.scan(src) do | |
local Color = | |
if customLang and customLang[content] then | |
TokenColors["custom"] | |
else | |
TokenColors[token] or TokenColors["iden"] | |
local tokenLines = string.split(SanitizeRichText(content), "\n") | |
for l, line in ipairs(tokenLines) do | |
-- Find line label | |
local lineLabel = lineLabels[lineNumber] | |
if not lineLabel then | |
local newLabel = Instance.new("TextLabel") | |
newLabel.Name = "Line_" .. lineNumber | |
newLabel.RichText = true | |
newLabel.BackgroundTransparency = 1 | |
newLabel.Text = "" | |
newLabel.TextXAlignment = Enum.TextXAlignment.Left | |
newLabel.TextYAlignment = Enum.TextYAlignment.Top | |
newLabel.Parent = lineFolder | |
lineLabels[lineNumber] = newLabel | |
lineLabel = newLabel | |
end | |
-- Align line label | |
lineLabel.TextColor3 = TokenColors["iden"] | |
lineLabel.Font = textObject.Font | |
lineLabel.TextSize = textObject.TextSize | |
lineLabel.Size = UDim2.new(1, 0, 0, math.ceil(textHeight)) | |
lineLabel.Position = UDim2.fromScale(0, textHeight * (lineNumber - 1) / textObject.AbsoluteSize.Y) | |
-- If multiline token, then set line & move to next | |
if l > 1 then | |
if forceUpdate or lines[lineNumber] ~= previousLines[lineNumber] then | |
-- Set line | |
lineLabels[lineNumber].Text = table.concat(richText) | |
end | |
-- Move to next line | |
lineNumber += 1 | |
index = 0 | |
table.clear(richText) | |
end | |
-- If changed, add token to line | |
if forceUpdate or lines[lineNumber] ~= previousLines[lineNumber] then | |
index += 1 | |
-- Only add RichText tags when the color is non-default and the characters are non-whitespace | |
if Color ~= TokenColors["iden"] and string.find(line, "[%S%C]") then | |
richText[index] = string.format(ColorFormatter[Color], line) | |
else | |
richText[index] = line | |
end | |
end | |
end | |
end | |
-- Set final line | |
if richText[1] and lineLabels[lineNumber] then | |
lineLabels[lineNumber].Text = table.concat(richText) | |
end | |
-- Clear unused line labels | |
for l=lineNumber+1, #lineLabels do | |
if lineLabels[l].Text == "" then continue end | |
lineLabels[l].Text = "" | |
end | |
return cleanup | |
end | |
function Highlighter.refresh(): () | |
-- Rehighlight existing labels using latest colors | |
for textObject, data in pairs(LastData) do | |
for _, lineLabel in ipairs(data.Labels) do | |
lineLabel.TextColor3 = TokenColors["iden"] | |
end | |
Highlighter.highlight({ | |
textObject = textObject, | |
forceUpdate = true, | |
src = data.Text, | |
lexer = data.Lexer, | |
customLang = data.CustomLang, | |
}) | |
end | |
end | |
function Highlighter.setTokenColors(colors: HighlighterColors) | |
for token, color in colors do | |
TokenColors[token] = color | |
ColorFormatter[color] = string.format( | |
'<font color="#%.2x%.2x%.2x">', | |
color.R * 255, | |
color.G * 255, | |
color.B * 255 | |
) .. "%s</font>" | |
end | |
Highlighter.refresh() | |
end | |
Highlighter.setTokenColors(TokenColors) | |
return Highlighter :: Highlighter | |
end, | |
Properties = { | |
Name = "MainModule" | |
}, | |
Reference = 1, | |
Children = { | |
{ | |
ClassName = "ModuleScript", | |
Closure = function() --[=[ | |
Lexical scanner for creating a sequence of tokens from Lua source code. | |
This is a heavily modified and Roblox-optimized version of | |
the original Penlight Lexer module: | |
https://github.com/stevedonovan/Penlight | |
Authors: | |
stevedonovan <https://github.com/stevedonovan> ----------- Original Penlight lexer author | |
ryanjmulder <https://github.com/ryanjmulder> ------------- Penlight lexer contributer | |
mpeterv <https://github.com/mpeterv> --------------------- Penlight lexer contributer | |
Tieske <https://github.com/Tieske> ----------------------- Penlight lexer contributer | |
boatbomber <https://github.com/boatbomber> --------------- Roblox port, added builtin token, | |
added patterns for incomplete syntax, bug fixes, | |
behavior changes, token optimization, thread optimization | |
Added lexer.navigator() for non-sequential reads | |
Sleitnick <https://github.com/Sleitnick> ----------------- Roblox optimizations | |
howmanysmall <https://github.com/howmanysmall> ----------- Lua + Roblox optimizations | |
List of possible tokens: | |
- iden | |
- keyword | |
- builtin | |
- string | |
- number | |
- comment | |
- operator | |
--]=] | |
local lexer = {} | |
local Prefix, Suffix, Cleaner = "^[%c%s]*", "[%c%s]*", "[%c%s]+" | |
local UNICODE = "[%z\x01-\x7F\xC2-\xF4][\x80-\xBF]+" | |
local NUMBER_A = "0[xX][%da-fA-F_]+" | |
local NUMBER_B = "0[bB][01_]+" | |
local NUMBER_C = "%d+%.?%d*[eE][%+%-]?%d+" | |
local NUMBER_D = "%d+[%._]?[%d_eE]*" | |
local OPERATORS = "[:;<>/~%*%(%)%-={},%.#%^%+%%]+" | |
local BRACKETS = "[%[%]]+" -- needs to be separate pattern from other operators or it'll mess up multiline strings | |
local IDEN = "[%a_][%w_]*" | |
local STRING_EMPTY = "(['\"])%1" --Empty String | |
local STRING_PLAIN = "(['\"])[^\n]-([^\\]%1)" --TODO: Handle escaping escapes | |
local STRING_INTER = "`[^\n]-`" | |
local STRING_INCOMP_A = "(['\"]).-\n" --Incompleted String with next line | |
local STRING_INCOMP_B = "(['\"])[^\n]*" --Incompleted String without next line | |
local STRING_MULTI = "%[(=*)%[.-%]%1%]" --Multiline-String | |
local STRING_MULTI_INCOMP = "%[=*%[.-.*" --Incompleted Multiline-String | |
local COMMENT_MULTI = "%-%-%[(=*)%[.-%]%1%]" --Completed Multiline-Comment | |
local COMMENT_MULTI_INCOMP = "%-%-%[=*%[.-.*" --Incompleted Multiline-Comment | |
local COMMENT_PLAIN = "%-%-.-\n" --Completed Singleline-Comment | |
local COMMENT_INCOMP = "%-%-.*" --Incompleted Singleline-Comment | |
-- local TYPED_VAR = ":%s*([%w%?%| \t]+%s*)" --Typed variable, parameter, function | |
local lang = require(script.language) | |
local lua_keyword = lang.keyword | |
local lua_builtin = lang.builtin | |
local lua_libraries = lang.libraries | |
lexer.language = lang | |
local lua_matches = { | |
-- Indentifiers | |
{ Prefix .. IDEN .. Suffix, "var" }, | |
-- Numbers | |
{ Prefix .. NUMBER_A .. Suffix, "number" }, | |
{ Prefix .. NUMBER_B .. Suffix, "number" }, | |
{ Prefix .. NUMBER_C .. Suffix, "number" }, | |
{ Prefix .. NUMBER_D .. Suffix, "number" }, | |
-- Strings | |
{ Prefix .. STRING_EMPTY .. Suffix, "string" }, | |
{ Prefix .. STRING_PLAIN .. Suffix, "string" }, | |
{ Prefix .. STRING_INCOMP_A .. Suffix, "string" }, | |
{ Prefix .. STRING_INCOMP_B .. Suffix, "string" }, | |
{ Prefix .. STRING_MULTI .. Suffix, "string" }, | |
{ Prefix .. STRING_MULTI_INCOMP .. Suffix, "string" }, | |
{ Prefix .. STRING_INTER .. Suffix, "string_inter" }, | |
-- Comments | |
{ Prefix .. COMMENT_MULTI .. Suffix, "comment" }, | |
{ Prefix .. COMMENT_MULTI_INCOMP .. Suffix, "comment" }, | |
{ Prefix .. COMMENT_PLAIN .. Suffix, "comment" }, | |
{ Prefix .. COMMENT_INCOMP .. Suffix, "comment" }, | |
-- Operators | |
{ Prefix .. OPERATORS .. Suffix, "operator" }, | |
{ Prefix .. BRACKETS .. Suffix, "operator" }, | |
-- Unicode | |
{ Prefix .. UNICODE .. Suffix, "iden" }, | |
-- Unknown | |
{ "^.", "iden" }, | |
} | |
-- To reduce the amount of table indexing during lexing, we separate the matches now | |
local PATTERNS, TOKENS = {}, {} | |
for i, m in lua_matches do | |
PATTERNS[i] = m[1] | |
TOKENS[i] = m[2] | |
end | |
--- Create a plain token iterator from a string. | |
-- @tparam string s a string. | |
function lexer.scan(s: string) | |
local index = 1 | |
local size = #s | |
local previousContent1, previousContent2, previousContent3, previousToken = "", "", "", "" | |
local thread = coroutine.create(function() | |
while index <= size do | |
local matched = false | |
for tokenType, pattern in ipairs(PATTERNS) do | |
-- Find match | |
local start, finish = string.find(s, pattern, index) | |
if start == nil then continue end | |
-- Move head | |
index = finish + 1 | |
matched = true | |
-- Gather results | |
local content = string.sub(s, start, finish) | |
local rawToken = TOKENS[tokenType] | |
local processedToken = rawToken | |
-- Process token | |
if rawToken == "var" then | |
-- Since we merge spaces into the tok, we need to remove them | |
-- in order to check the actual word it contains | |
local cleanContent = string.gsub(content, Cleaner, "") | |
if lua_keyword[cleanContent] then | |
processedToken = "keyword" | |
elseif lua_builtin[cleanContent] then | |
processedToken = "builtin" | |
elseif string.find(previousContent1, "%.[%s%c]*$") and previousToken ~= "comment" then | |
-- The previous was a . so we need to special case indexing things | |
local parent = string.gsub(previousContent2, Cleaner, "") | |
local lib = lua_libraries[parent] | |
if lib and lib[cleanContent] and not string.find(previousContent3, "%.[%s%c]*$") then | |
-- Indexing a builtin lib with existing item, treat as a builtin | |
processedToken = "builtin" | |
else | |
-- Indexing a non builtin, can't be treated as a keyword/builtin | |
processedToken = "iden" | |
end | |
-- print("indexing",parent,"with",cleanTok,"as",t2) | |
else | |
processedToken = "iden" | |
end | |
elseif rawToken == "string_inter" then | |
if not string.find(content, "[^\\]{") then | |
-- This inter string doesnt actually have any inters | |
processedToken = "string" | |
else | |
-- We're gonna do our own yields, so the main loop won't need to | |
-- Our yields will be a mix of string and whatever is inside the inters | |
processedToken = nil | |
local isString = true | |
local subIndex = 1 | |
local subSize = #content | |
while subIndex <= subSize do | |
-- Find next brace | |
local subStart, subFinish = string.find(content, "^.-[^\\][{}]", subIndex) | |
if subStart == nil then | |
-- No more braces, all string | |
coroutine.yield("string", string.sub(content, subIndex)) | |
break | |
end | |
if isString then | |
-- We are currently a string | |
subIndex = subFinish + 1 | |
coroutine.yield("string", string.sub(content, subStart, subFinish)) | |
-- This brace opens code | |
isString = false | |
else | |
-- We are currently in code | |
subIndex = subFinish | |
local subContent = string.sub(content, subStart, subFinish-1) | |
for innerToken, innerContent in lexer.scan(subContent) do | |
coroutine.yield(innerToken, innerContent) | |
end | |
-- This brace opens string/closes code | |
isString = true | |
end | |
end | |
end | |
end | |
-- Record last 3 tokens for the indexing context check | |
previousContent3 = previousContent2 | |
previousContent2 = previousContent1 | |
previousContent1 = content | |
previousToken = processedToken or rawToken | |
if processedToken then | |
coroutine.yield(processedToken, content) | |
end | |
break | |
end | |
-- No matches found | |
if not matched then | |
return | |
end | |
end | |
-- Completed the scan | |
return | |
end) | |
return function() | |
if coroutine.status(thread) == "dead" then | |
return | |
end | |
local success, token, content = coroutine.resume(thread) | |
if success and token then | |
return token, content | |
end | |
return | |
end | |
end | |
function lexer.navigator() | |
local nav = { | |
Source = "", | |
TokenCache = table.create(50), | |
_RealIndex = 0, | |
_UserIndex = 0, | |
_ScanThread = nil, | |
} | |
function nav:Destroy() | |
self.Source = nil | |
self._RealIndex = nil | |
self._UserIndex = nil | |
self.TokenCache = nil | |
self._ScanThread = nil | |
end | |
function nav:SetSource(SourceString) | |
self.Source = SourceString | |
self._RealIndex = 0 | |
self._UserIndex = 0 | |
table.clear(self.TokenCache) | |
self._ScanThread = coroutine.create(function() | |
for Token, Src in lexer.scan(self.Source) do | |
self._RealIndex += 1 | |
self.TokenCache[self._RealIndex] = { Token, Src } | |
coroutine.yield(Token, Src) | |
end | |
end) | |
end | |
function nav.Next() | |
nav._UserIndex += 1 | |
if nav._RealIndex >= nav._UserIndex then | |
-- Already scanned, return cached | |
return table.unpack(nav.TokenCache[nav._UserIndex]) | |
else | |
if coroutine.status(nav._ScanThread) == "dead" then | |
-- Scan thread dead | |
return | |
else | |
local success, token, src = coroutine.resume(nav._ScanThread) | |
if success and token then | |
-- Scanned new data | |
return token, src | |
else | |
-- Lex completed | |
return | |
end | |
end | |
end | |
end | |
function nav.Peek(PeekAmount) | |
local GoalIndex = nav._UserIndex + PeekAmount | |
if nav._RealIndex >= GoalIndex then | |
-- Already scanned, return cached | |
if GoalIndex > 0 then | |
return table.unpack(nav.TokenCache[GoalIndex]) | |
else | |
-- Invalid peek | |
return | |
end | |
else | |
if coroutine.status(nav._ScanThread) == "dead" then | |
-- Scan thread dead | |
return | |
else | |
local IterationsAway = GoalIndex - nav._RealIndex | |
local success, token, src = nil, nil, nil | |
for _ = 1, IterationsAway do | |
success, token, src = coroutine.resume(nav._ScanThread) | |
if not (success or token) then | |
-- Lex completed | |
break | |
end | |
end | |
return token, src | |
end | |
end | |
end | |
return nav | |
end | |
return lexer | |
end, | |
Properties = { | |
Name = "lexer" | |
}, | |
Reference = 2, | |
Children = { | |
{ | |
Closure = function() local language = { | |
keyword = { | |
["and"] = "keyword", | |
["break"] = "keyword", | |
["continue"] = "keyword", | |
["do"] = "keyword", | |
["else"] = "keyword", | |
["elseif"] = "keyword", | |
["end"] = "keyword", | |
["export"] = "keyword", | |
["false"] = "keyword", | |
["for"] = "keyword", | |
["function"] = "keyword", | |
["if"] = "keyword", | |
["in"] = "keyword", | |
["local"] = "keyword", | |
["nil"] = "keyword", | |
["not"] = "keyword", | |
["or"] = "keyword", | |
["repeat"] = "keyword", | |
["return"] = "keyword", | |
["self"] = "keyword", | |
["then"] = "keyword", | |
["true"] = "keyword", | |
["type"] = "keyword", | |
["typeof"] = "keyword", | |
["until"] = "keyword", | |
["while"] = "keyword", | |
}, | |
builtin = { | |
-- Luau Functions | |
["assert"] = "function", | |
["error"] = "function", | |
["getfenv"] = "function", | |
["getmetatable"] = "function", | |
["ipairs"] = "function", | |
["loadstring"] = "function", | |
["newproxy"] = "function", | |
["next"] = "function", | |
["pairs"] = "function", | |
["pcall"] = "function", | |
["print"] = "function", | |
["rawequal"] = "function", | |
["rawget"] = "function", | |
["rawlen"] = "function", | |
["rawset"] = "function", | |
["select"] = "function", | |
["setfenv"] = "function", | |
["setmetatable"] = "function", | |
["tonumber"] = "function", | |
["tostring"] = "function", | |
["unpack"] = "function", | |
["xpcall"] = "function", | |
-- Luau Functions (Deprecated) | |
["collectgarbage"] = "function", | |
-- Luau Variables | |
["_G"] = "table", | |
["_VERSION"] = "string", | |
-- Luau Tables | |
["bit32"] = "table", | |
["coroutine"] = "table", | |
["debug"] = "table", | |
["math"] = "table", | |
["os"] = "table", | |
["string"] = "table", | |
["table"] = "table", | |
["utf8"] = "table", | |
-- Roblox Functions | |
["DebuggerManager"] = "function", | |
["delay"] = "function", | |
["gcinfo"] = "function", | |
["PluginManager"] = "function", | |
["require"] = "function", | |
["settings"] = "function", | |
["spawn"] = "function", | |
["tick"] = "function", | |
["time"] = "function", | |
["UserSettings"] = "function", | |
["wait"] = "function", | |
["warn"] = "function", | |
-- Roblox Functions (Deprecated) | |
["Delay"] = "function", | |
["ElapsedTime"] = "function", | |
["elapsedTime"] = "function", | |
["printidentity"] = "function", | |
["Spawn"] = "function", | |
["Stats"] = "function", | |
["stats"] = "function", | |
["Version"] = "function", | |
["version"] = "function", | |
["Wait"] = "function", | |
["ypcall"] = "function", | |
-- Roblox Variables | |
["game"] = "Instance", | |
["plugin"] = "Instance", | |
["script"] = "Instance", | |
["shared"] = "Instance", | |
["workspace"] = "Instance", | |
-- Roblox Variables (Deprecated) | |
["Game"] = "Instance", | |
["Workspace"] = "Instance", | |
-- Roblox Tables | |
["Axes"] = "table", | |
["BrickColor"] = "table", | |
["CatalogSearchParams"] = "table", | |
["CFrame"] = "table", | |
["Color3"] = "table", | |
["ColorSequence"] = "table", | |
["ColorSequenceKeypoint"] = "table", | |
["DateTime"] = "table", | |
["DockWidgetPluginGuiInfo"] = "table", | |
["Enum"] = "table", | |
["Faces"] = "table", | |
["FloatCurveKey"] = "table", | |
["Font"] = "table", | |
["Instance"] = "table", | |
["NumberRange"] = "table", | |
["NumberSequence"] = "table", | |
["NumberSequenceKeypoint"] = "table", | |
["OverlapParams"] = "table", | |
["PathWaypoint"] = "table", | |
["PhysicalProperties"] = "table", | |
["Random"] = "table", | |
["Ray"] = "table", | |
["RaycastParams"] = "table", | |
["Rect"] = "table", | |
["Region3"] = "table", | |
["Region3int16"] = "table", | |
["RotationCurveKey"] = "table", | |
["task"] = "table", | |
["TweenInfo"] = "table", | |
["UDim"] = "table", | |
["UDim2"] = "table", | |
["Vector2"] = "table", | |
["Vector2int16"] = "table", | |
["Vector3"] = "table", | |
["Vector3int16"] = "table", | |
}, | |
libraries = { | |
-- Luau Libraries | |
bit32 = { | |
arshift = "function", | |
band = "function", | |
bnot = "function", | |
bor = "function", | |
btest = "function", | |
bxor = "function", | |
countlz = "function", | |
countrz = "function", | |
extract = "function", | |
lrotate = "function", | |
lshift = "function", | |
replace = "function", | |
rrotate = "function", | |
rshift = "function", | |
}, | |
coroutine = { | |
close = "function", | |
create = "function", | |
isyieldable = "function", | |
resume = "function", | |
running = "function", | |
status = "function", | |
wrap = "function", | |
yield = "function", | |
}, | |
debug = { | |
dumpheap = "function", | |
info = "function", | |
loadmodule = "function", | |
profilebegin = "function", | |
profileend = "function", | |
resetmemorycategory = "function", | |
setmemorycategory = "function", | |
traceback = "function", | |
}, | |
math = { | |
abs = "function", | |
acos = "function", | |
asin = "function", | |
atan2 = "function", | |
atan = "function", | |
ceil = "function", | |
clamp = "function", | |
cos = "function", | |
cosh = "function", | |
deg = "function", | |
exp = "function", | |
floor = "function", | |
fmod = "function", | |
frexp = "function", | |
ldexp = "function", | |
log10 = "function", | |
log = "function", | |
max = "function", | |
min = "function", | |
modf = "function", | |
noise = "function", | |
pow = "function", | |
rad = "function", | |
random = "function", | |
randomseed = "function", | |
round = "function", | |
sign = "function", | |
sin = "function", | |
sinh = "function", | |
sqrt = "function", | |
tan = "function", | |
tanh = "function", | |
huge = "number", | |
pi = "number", | |
}, | |
os = { | |
clock = "function", | |
date = "function", | |
difftime = "function", | |
time = "function", | |
}, | |
string = { | |
byte = "function", | |
char = "function", | |
find = "function", | |
format = "function", | |
gmatch = "function", | |
gsub = "function", | |
len = "function", | |
lower = "function", | |
match = "function", | |
pack = "function", | |
packsize = "function", | |
rep = "function", | |
reverse = "function", | |
split = "function", | |
sub = "function", | |
unpack = "function", | |
upper = "function", | |
}, | |
table = { | |
clear = "function", | |
clone = "function", | |
concat = "function", | |
create = "function", | |
find = "function", | |
foreach = "function", | |
foreachi = "function", | |
freeze = "function", | |
getn = "function", | |
insert = "function", | |
isfrozen = "function", | |
maxn = "function", | |
move = "function", | |
pack = "function", | |
remove = "function", | |
sort = "function", | |
unpack = "function", | |
}, | |
utf8 = { | |
char = "function", | |
codepoint = "function", | |
codes = "function", | |
graphemes = "function", | |
len = "function", | |
nfcnormalize = "function", | |
nfdnormalize = "function", | |
offset = "function", | |
charpattern = "string", | |
}, | |
-- Roblox Libraries | |
Axes = { | |
new = "function", | |
}, | |
BrickColor = { | |
Black = "function", | |
Blue = "function", | |
DarkGray = "function", | |
Gray = "function", | |
Green = "function", | |
new = "function", | |
New = "function", | |
palette = "function", | |
Random = "function", | |
random = "function", | |
Red = "function", | |
White = "function", | |
Yellow = "function", | |
}, | |
CatalogSearchParams = { | |
new = "function", | |
}, | |
CFrame = { | |
Angles = "function", | |
fromAxisAngle = "function", | |
fromEulerAngles = "function", | |
fromEulerAnglesXYZ = "function", | |
fromEulerAnglesYXZ = "function", | |
fromMatrix = "function", | |
fromOrientation = "function", | |
lookAt = "function", | |
new = "function", | |
identity = "CFrame", | |
}, | |
Color3 = { | |
fromHex = "function", | |
fromHSV = "function", | |
fromRGB = "function", | |
new = "function", | |
toHSV = "function", | |
}, | |
ColorSequence = { | |
new = "function", | |
}, | |
ColorSequenceKeypoint = { | |
new = "function", | |
}, | |
DateTime = { | |
fromIsoDate = "function", | |
fromLocalTime = "function", | |
fromUniversalTime = "function", | |
fromUnixTimestamp = "function", | |
fromUnixTimestampMillis = "function", | |
now = "function", | |
}, | |
DockWidgetPluginGuiInfo = { | |
new = "function", | |
}, | |
Enum = {}, | |
Faces = { | |
new = "function", | |
}, | |
FloatCurveKey = { | |
new = "function", | |
}, | |
Font = { | |
fromEnum = "function", | |
fromId = "function", | |
fromName = "function", | |
new = "function", | |
}, | |
Instance = { | |
new = "function", | |
}, | |
NumberRange = { | |
new = "function", | |
}, | |
NumberSequence = { | |
new = "function", | |
}, | |
NumberSequenceKeypoint = { | |
new = "function", | |
}, | |
OverlapParams = { | |
new = "function", | |
}, | |
PathWaypoint = { | |
new = "function", | |
}, | |
PhysicalProperties = { | |
new = "function", | |
}, | |
Random = { | |
new = "function", | |
}, | |
Ray = { | |
new = "function", | |
}, | |
RaycastParams = { | |
new = "function", | |
}, | |
Rect = { | |
new = "function", | |
}, | |
Region3 = { | |
new = "function", | |
}, | |
Region3int16 = { | |
new = "function", | |
}, | |
RotationCurveKey = { | |
new = "function", | |
}, | |
task = { | |
cancel = "function", | |
defer = "function", | |
delay = "function", | |
desynchronize = "function", | |
spawn = "function", | |
synchronize = "function", | |
wait = "function", | |
}, | |
TweenInfo = { | |
new = "function", | |
}, | |
UDim = { | |
new = "function", | |
}, | |
UDim2 = { | |
fromOffset = "function", | |
fromScale = "function", | |
new = "function", | |
}, | |
Vector2 = { | |
new = "function", | |
one = "Vector2", | |
xAxis = "Vector2", | |
yAxis = "Vector2", | |
zero = "Vector2", | |
}, | |
Vector2int16 = { | |
new = "function", | |
}, | |
Vector3 = { | |
fromAxis = "function", | |
FromAxis = "function", | |
fromNormalId = "function", | |
FromNormalId = "function", | |
new = "function", | |
one = "Vector3", | |
xAxis = "Vector3", | |
yAxis = "Vector3", | |
zAxis = "Vector3", | |
zero = "Vector3", | |
}, | |
Vector3int16 = { | |
new = "function", | |
}, | |
}, | |
} | |
-- Filling up language.libraries.Enum table | |
local enumLibraryTable = language.libraries.Enum | |
for _, enum in ipairs(Enum:GetEnums()) do | |
--TODO: Remove tostring from here once there is a better way to get the name of an Enum | |
enumLibraryTable[tostring(enum)] = "Enum" | |
end | |
return language | |
end, | |
Properties = { | |
Name = "language" | |
}, | |
Reference = 3, | |
ClassName = "ModuleScript" | |
} | |
} | |
} | |
} | |
} | |
} | |
do local a,b='0.4.0',Flags or{}local c,d,e=(b.ContextualExecution==nil and true)or b.ContextualExecution do if c then local f=game:GetService'RunService'd=f:IsServer()e=f:IsClient()end end local f,g,h,i,j,k,l=getfenv(0),{},{},{},{},{},{}local function m(n)local o,p=pcall(Instance.new,n.ClassName)if not o then return end g[n.Reference]=p if n.Closure then i[p]=n.Closure if p:IsA'BaseScript'then table.insert(k,p)end end if n.Properties then for q,r in next,n.Properties do pcall(function()p[q]=r end)end end if n.RefProperties then for q,r in next,n.RefProperties do table.insert(h,{InstanceObject=p,Property=q,ReferenceId=r})end end if n.Attributes then for q,r in next,n.Attributes do pcall(p.SetAttribute,p,q,r)end end if n.Children then for q,r in next,n.Children do local s=m(r)if s then s.Parent=p end end end return p end local n={}do for o,p in next,ModuleRoot do table.insert(n,m(p))end end local function o(p)local q=j[p]if p.ClassName=='ModuleScript'and q then return unpack(q)end local r=i[p]if not r then return end do local s local t={['maui']=table.freeze{Version=a,GetScript=function()return script end,GetShared=function()return l end},['script']=p,['require']=function(t,...)if t and t.ClassName=='ModuleScript'and i[t]then return o(t)end return require(t,...)end,['getfenv']=function(t,...)if type(t)=='number'and t>=0 then if t==0 then return s else local u,v=pcall(getfenv,t)if u and v==f then return s end end end return getfenv(t,...)end,['setfenv']=function(t,u,...)if type(t)=='number'and t>=0 then if t==0 then return setfenv(s,u)else local v,w=pcall(getfenv,t)if v and w==f then return setfenv(s,u)end end end return setfenv(t,u,...)end}s=setmetatable({},{__index=function(u,v)local w=rawget(s,v)if w~=nil then return w end local x=t[v]if x~=nil then return x end return f[v]end})setfenv(r,s)end local s=coroutine.wrap(r)if p:IsA'BaseScript'then local t=(not c or not p.Disabled)and task.defer(s)if c then local u u=p:GetPropertyChangedSignal'Disabled':Connect(function(v)u:Disconnect()if v==false then o(p)else pcall(task.cancel,t)end end)end return else local t={s()}j[p]=t return unpack(t)end end for p,q in next,h do pcall(function()q.InstanceObject[q.Property]=g[q.ReferenceId]end)end for r,s in next,k do if not c or((d and s.ClassName=='Script')or(e and s.ClassName=='LocalScript'))then o(s)end end if b.ReturnMainModule==nil or b.ReturnMainModule then local t do for u,v in next,n do if v.ClassName=='ModuleScript'and v.Name=='MainModule'then t=v break end end end if t then return o(t)end end end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment