2013/luau/20000001.luau

430 lines
11 KiB
Plaintext

--!strict
-- Never trust the client
local CoreGui = game:GetService "CoreGui"
local Players = game:GetService "Players"
local RunService = game:GetService "RunService"
local MaxLength = 35
local New = (require "../Modules/New").New
local logEvent: BindableEvent
local function Colour3(r: number, g: number, b: number)
return Color3.new(r / 255, g / 255, b / 255)
end
local docs = {
{
"printTable(t: { [any]: any }, max: number?)",
"Prints the contents of a table to the console.",
"`max` - the maximum number of entries to print.",
"If not provided, all entries are printed.",
},
{
"setWalkspeed(speed: number, plr: string?)",
"Sets the walkspeed of a player. Go h4x0r mode!",
"`speed` - the new walkspeed.",
"`plr` - the name of the player to set the walkspeed of.",
"If not provided, sets your own walkspeed.",
},
{
"setHealth(health: number, plr: string?)",
"Sets the health of a player. Become invincible!",
"`health` - the new health value. Increases max health if necessary.",
"`plr` - the name of the player to set the health of.",
"If not provided, sets your own health.",
},
{
"setMaxHealth(health: number, plr: string?)",
"Sets the maximum health of a player.",
"`health` - the new max health value.",
"`plr` - the name of the player to set the max health of.",
"If not provided, sets your own max health.",
},
{
"setGravity(multi: number, plr: string?)",
"Sets the gravity of a player. Float like a feather!",
"`multi` - the multiplier to apply to gravity. 1 is normal, 2 is double,",
"0.5 is half, etc. Beware of negative numbers!",
"`plr` - the name of the player to set the gravity of.",
"If not provided, changes your own gravity.",
},
{
"sit(plr: string?)",
"Sits a player down.",
"`plr` - the name of the player to set the sitting state of.",
"If not provided, sets your own sitting state.",
},
{
"platformStand(plr: string?)",
"Sets a player to stand on a platform.",
"`plr` - the name of the player to set the platform standing state of.",
"If not provided, sets your own platform standing state.",
},
{
"stand(plr: string?)",
"Stands a player up, and removes platform standing.",
"`plr` - the name of the player to set the standing state of.",
"If not provided, sets your own standing state.",
},
{
"explode(plr: string?)",
"Detonates a player, killing them instantly, and probably anyone nearby",
"them too.",
"`plr` - the name of the player to explode.",
"If not provided, well... you know the deal.",
},
{
"help(max: number?)",
"You've already found this command!",
"`max` - the maximum number of entries to print.",
"If not provided, all entries are printed.",
},
{
"exit()",
"Exits the debug console. Watch out, you can't get back in!",
},
}
local function Fire(should: boolean, ...: any)
if should then
logEvent:Fire(...)
end
end
local utility = {
CoreGui = CoreGui, -- convenience/shorthands
Players = Players,
RunService = RunService,
}
local function Assert(condition: any, message: string)
if not condition then
error(message, -1)
end
end
local j = print -- j
function utility.print(...)
local args = { ... }
for i, v in ipairs(args) do
args[i] = tostring(v)
end
local p = table.concat(args, " ")
j(p)
logEvent:Fire(p)
end
function utility.printTable(t: { [any]: any }, max: number?)
assert(type(t) == "table", "Expected table, got " .. type(t))
local num = max or math.huge
local len = 0
for k, v in pairs(t) do
len += 1
Fire(len < num, tostring(k) .. " = " .. tostring(v))
end
if len >= num then
logEvent:Fire("... and " .. tostring(len - num) .. " more")
end
end
-- I will not drown in a sea of tiny functions, I promise
local function getPlayerByUsername(username: string?)
local player = (username and Players:FindFirstChild(username)) :: Player
Assert(not username or player, "Player not found")
player = player or Players.LocalPlayer
Assert(player, "No player provided and no local player found")
return player
end
local function getCharacterByUsername(username: string?)
local player = getPlayerByUsername(username)
return player.Character or player.CharacterAdded:wait(), player
end
local function getHumanoidByUsername(username: string?)
local character, player = getCharacterByUsername(username)
return character:WaitForChild "Humanoid" :: Humanoid, character, player
end
function utility.setWalkspeed(speed: number, plr: string?)
Assert(type(speed) == "number", "Expected number, got " .. type(speed))
local humanoid = getHumanoidByUsername(plr)
humanoid.WalkSpeed = speed
end
function utility.setHealth(health: number, plr: string?)
Assert(type(health) == "number", "Expected number, got " .. type(health))
local humanoid = getHumanoidByUsername(plr)
if humanoid.MaxHealth < health then
humanoid.MaxHealth = health
end
humanoid.Health = health
end
function utility.setMaxHealth(health: number, plr: string?)
Assert(type(health) == "number", "Expected number, got " .. type(health))
local humanoid = getHumanoidByUsername(plr)
humanoid.MaxHealth = health
end
function utility.sit(plr: string?)
local humanoid = getHumanoidByUsername(plr)
humanoid.Sit = true
end
function utility.platformStand(plr: string?)
local humanoid = getHumanoidByUsername(plr)
humanoid.PlatformStand = true
end
function utility.stand(plr: string?)
local humanoid = getHumanoidByUsername(plr)
humanoid.Sit = false
humanoid.PlatformStand = false
end
function utility.explode(plr: string?)
local character = getCharacterByUsername(plr)
local torso = character:FindFirstChild "Torso" :: Part
Assert(torso, "No torso found in character, required to explode")
New "Explosion" {
ExplosionType = Enum.ExplosionType.NoCraters,
Parent = character,
Position = torso.Position,
BlastPressure = 15e5, -- engineering moment
BlastRadius = 2,
}
end
local grav = 3372 -- just enough keep you on the ground, as long as you don't jump
function utility.setGravity(multi: number, plr: string?)
assert(type(multi) == "number", "Expected number, got " .. type(multi))
local character = getCharacterByUsername(plr)
local torso = character:FindFirstChild "Torso" :: Part
Assert(torso, "No torso found in character, required to apply gravity")
local bodyForce = torso:FindFirstChild "Gravity"
or New "BodyForce" {
Name = "Gravity",
Parent = torso,
}
bodyForce.force = Vector3.new(0, grav * (1 - multi), 0)
end
function utility.help(max: number?)
local num = max or math.huge
local len = 0
for _, doc in pairs(docs) do
if len < num then
RunService.RenderStepped:wait()
end
Fire(len < num, doc[1], Color3.new(1, 1, 0.3))
len += 1
for i = 2, #doc do
Fire(len < num, "\t" .. doc[i], Color3.new(1, 1, 1))
len += 1
end
end
if len >= num then
logEvent:Fire("... and " .. tostring(len - num) .. " more")
end
end
function utility.exit()
logEvent:Fire("Goodbye!", Color3.new(1, 1, 0.3))
for i = 1, MaxLength do
logEvent:Fire()
RunService.RenderStepped:wait()
end
local debug = game.CoreGui:FindFirstChild "Debug console" :: ScreenGui
debug:Destroy()
end
if not Players.LocalPlayer or Players.LocalPlayer.Name ~= "Heliodex" then -- Don't show the debug console for anyone but me
return
end
logEvent = logEvent or New "BindableEvent" {
Name = "Log",
Parent = game,
}
local screen = New "ScreenGui" {
Name = "Debug console",
Parent = CoreGui,
}
local frame = New "Frame" {
Name = "Frame",
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0.2, 0),
Size = UDim2.new(0.25, 0, 0.7, 0),
Parent = screen,
}
local console = New "Frame" {
Name = "Console",
BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 0.5,
BorderSizePixel = 0,
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 1, -30),
Parent = frame,
}
local logLines = {}
local logLineInstances: { TextLabel } = {}
for i = 1, MaxLength do
table.insert(logLines, {
Text = "",
Colour = Color3.new(1, 1, 1),
})
table.insert(
logLineInstances,
New "TextLabel" {
Name = "LogLine",
BackgroundTransparency = 1,
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0, 0, 0, (i - 1) * 18),
Size = UDim2.new(1, 0, 0, 18),
Text = "",
TextColor3 = Color3.new(1, 1, 1),
TextXAlignment = Enum.TextXAlignment.Left,
Parent = console,
}
)
end
local function recomputeLogLines()
for i, line in ipairs(logLines) do
logLineInstances[i].Text = " " .. line.Text -- yeah pad
logLineInstances[i].TextColor3 = line.Colour or Color3.new(1, 1, 1)
end
end
logEvent.Event:connect(function(text: string?, colour: Color3?)
table.insert(logLines, {
Text = text or "",
Colour = colour or Color3.new(1, 1, 1),
})
if #logLines > MaxLength then
table.remove(logLines, 1)
end
recomputeLogLines()
end)
local input = New "TextBox" {
Name = "Input",
BackgroundColor3 = Color3.new(0.2, 0.2, 0.2),
BackgroundTransparency = 0.2,
BorderSizePixel = 0,
Position = UDim2.new(0, 0, 1, -30),
Size = UDim2.new(1, -30, 0, 30),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
Text = "",
TextColor3 = Color3.new(1, 1, 1),
TextXAlignment = Enum.TextXAlignment.Left,
ClearTextOnFocus = false,
Parent = frame,
}
local upButton = New "TextButton" {
Name = "UpButton",
BackgroundColor3 = Color3.new(0.2, 0.2, 0.2),
BackgroundTransparency = 0.2,
BorderSizePixel = 0,
Position = UDim2.new(1, -30, 1, -30),
Size = UDim2.new(0, 30, 0, 30),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size24,
Text = "^",
TextColor3 = Color3.new(1, 1, 1),
Parent = frame,
}
local history = {}
local historyPos = 1
-- on upButton pressed, go back in history
upButton.MouseButton1Click:connect(function()
if historyPos > #history then
return
end
input.Text = history[historyPos]
historyPos += 1
end)
input.FocusLost:connect(function(enterPressed)
if enterPressed then
historyPos = 1
local text = input.Text
table.insert(history, 1, text)
logEvent:Fire("> " .. text)
-- run the command
local fn = loadstring(text)
if fn then
local env = getfenv(fn)
for k, v in pairs(utility) do
env[k] = v
end
setfenv(fn, env)
local success, output = ypcall(fn)
if success then
logEvent:Fire("= " .. tostring(output), Color3.new(0.5, 1, 0.5))
else
logEvent:Fire("! " .. tostring(output), Color3.new(1, 0.5, 0.5))
end
else
logEvent:Fire("Invalid command", Color3.new(1, 0.3, 0.3))
end
input.Text = ""
input.BackgroundColor3 = Color3.new(0.2, 0.2, 0.2)
end
end)
input.Changed:connect(function(property)
if property ~= "Text" or input.Text == "" then
return
end
input.BackgroundColor3 = Color3.new(0, 0, 0)
end)
local welcome: { { any } } = {
{ "[Reading access...]", Color3.new(0.6, 0.6, 0.6) }, -- haxor text
{ "[Access granted.]", Color3.new(0.5, 1, 0.5) }, -- i'm in
{ "Welcome to the Graphictoria Debug Console!", Colour3(139, 82, 255) }, -- mercury light purple
{ "Run `help()` for a list of functions.", Color3.new(1, 1, 1) },
{ "" },
}
for _, line in ipairs(welcome) do
logEvent:Fire(unpack(line))
RunService.RenderStepped:wait()
end