1711 lines
66 KiB
Lua
1711 lines
66 KiB
Lua
-- vim: set foldmethod=marker :
|
|
-- Texture dimensions --
|
|
size = 128
|
|
factor = size / 64
|
|
-- Values for UV mappings --
|
|
face_damage=0
|
|
face_expr=0
|
|
step_u_face=32
|
|
step_v_face=16
|
|
offset_u_face=64
|
|
offset_v_face=0
|
|
armor_enabled=true
|
|
|
|
-- initialize values --
|
|
function player_init()
|
|
old_health=player.getHealth()
|
|
end
|
|
expr_cooldown=0
|
|
|
|
-- Parts --
|
|
HEAD=model.Head.Head
|
|
|
|
-- Initial configuration --
|
|
for key, value in pairs(vanilla_model) do
|
|
value.setEnabled(false)
|
|
end
|
|
vanilla_model.CAPE.setEnabled(true)
|
|
|
|
-- Expression change --
|
|
function getExprUV(damage, expression)
|
|
local u=offset_u_face+(damage*step_u_face)
|
|
local v=offset_v_face+(expression*step_v_face)
|
|
return {u/size,v/size}
|
|
end
|
|
function changeExpression(_damage, _expression, ticks)
|
|
-- u is damage, v is expression
|
|
local damage = _damage
|
|
local expression = _expression
|
|
if damage == nil then
|
|
damage = face_damage
|
|
end
|
|
if expression == nil then
|
|
expression = face_expr
|
|
end
|
|
|
|
HEAD.setUV(getExprUV(damage,expression))
|
|
expr_cooldown=ticks
|
|
end
|
|
function setExpression(damage, expression)
|
|
face_damage=damage
|
|
face_expr=expression
|
|
HEAD.setUV(getExprUV(damage, expression))
|
|
end
|
|
function resetExpression()
|
|
HEAD.setUV(getExprUV(face_damage,face_expr))
|
|
end
|
|
|
|
-- Action Wheel --
|
|
action_wheel.SLOT_1.setTitle('test expression')
|
|
action_wheel.SLOT_1.setFunction(function() ping.expressionTest() end)
|
|
function ping.expressionTest()
|
|
setExpression(1,0)
|
|
changeExpression(nil, 1, 10)
|
|
end
|
|
action_wheel.SLOT_2.setTitle('log health')
|
|
action_wheel.SLOT_2.setFunction(function() print(player.getHealth()) end)
|
|
action_wheel.SLOT_3.setTitle('Toggle Armor')
|
|
action_wheel.SLOT_3.setFunction(function() ping.setArmor() end)
|
|
|
|
-- Pings --
|
|
--- Damage function --
|
|
function ping.oof(health)
|
|
if health <= 5 then
|
|
setExpression(1,0)
|
|
end
|
|
changeExpression(nil,1,10)
|
|
end
|
|
--- Heal function (revert expression) --
|
|
function ping.healed(health)
|
|
setExpression(0,0)
|
|
end
|
|
--- Toggle Armor ---
|
|
function ping.setArmor(enabled)
|
|
if enabled == nil then
|
|
armor_enabled=not armor_enabled
|
|
else
|
|
armor_enabled=enabled
|
|
end
|
|
|
|
for key, value in pairs(armor_model) do
|
|
value.setEnabled(armor_enabled)
|
|
end
|
|
end
|
|
|
|
|
|
-- does not work on multiplayer, use ping.oof()
|
|
function onDamage(amount, source)
|
|
end
|
|
|
|
-- Tick function --
|
|
function tick()
|
|
-- expression reset spaghetti code --
|
|
if expr_cooldown > 0 then
|
|
expr_cooldown = expr_cooldown-1
|
|
if expr_cooldown <= 0 then
|
|
resetExpression()
|
|
end
|
|
end
|
|
|
|
-- optimization, only execute these once a second --
|
|
if world.getTimeOfDay() % 20 then
|
|
-- if face is cracked
|
|
if face_damage==1 and player.getHealth() > 5 then
|
|
ping.healed()
|
|
end
|
|
end
|
|
|
|
-- Damage ping (onDamage doesn't work in multiplayer) --
|
|
if old_health>player.getHealth() then
|
|
-- debug
|
|
-- print(string.format('old_health=%03.2f, player.getHealth=%03.2f', old_health,player.getHealth()))
|
|
ping.oof(player.getHealth())
|
|
end
|
|
|
|
-- End of tick --
|
|
old_health=player.getHealth()
|
|
end
|
|
|
|
-- REPL CODE {{{
|
|
if client.isHost() then
|
|
local loadSecrets = false --Disable this if the REPL is slow to load.
|
|
--[[>========================================<< INFO >>========================================<[]--
|
|
FIGURA REPL
|
|
By: GrandpaScout [STEAM_1:0:55009667]
|
|
Version: 4.1.1
|
|
Compatibility: >= Figura 0.0.8
|
|
Description:
|
|
A REPL for use in Figura 0.0.8 or later.
|
|
Contains formatting for types, table printing, hover data, and many other useful tools.
|
|
Is also themeable!
|
|
--[]>======================================<< END INFO >>======================================<]]--
|
|
|
|
--Create a completely seperated string table.
|
|
local string = {}
|
|
for k,v in pairs(_G.string) do
|
|
string[k] = v
|
|
end
|
|
|
|
local function checkSMT()
|
|
return pcall(function()
|
|
---@diagnostic disable: unused-local
|
|
local str = "%s"
|
|
local str2 = "I"
|
|
local a, b
|
|
a = str:byte(1,3)
|
|
a = str:find("h", 1, true)
|
|
a = str:format("hello")
|
|
for _ in str:gmatch("h") do end
|
|
a = str:gsub("h", "i", 2)
|
|
a = str:len()
|
|
a = str:lower()
|
|
a = str:match("h", 2)
|
|
a = str:rep(5, "//")
|
|
a = str:reverse()
|
|
a = str:sub(1, 4)
|
|
a = str:upper()
|
|
---@diagnostic enable: unused-local
|
|
end)
|
|
end
|
|
--The REPL *requires* a functional string metatable.
|
|
--This will replace a missing one with a substitute.
|
|
if not checkSMT() then
|
|
local t = {}
|
|
for k,f in pairs(string) do
|
|
t[k] = f
|
|
end
|
|
getmetatable("").__index = t
|
|
end
|
|
|
|
---@type any #Shut up type hints for this value.
|
|
local Infinity = math.huge --An infinite value, for convenience.
|
|
--[=========================================[ CONFIG ]=========================================]--
|
|
|
|
local repl_theme = {
|
|
repl = { --Generic REPL text
|
|
--[[Normal text. | color ]] default = "white",
|
|
--[[INPUT: | color ]] input = "white",
|
|
--[[RETURNS: | color ]] returns = "white",
|
|
--[[REPL: Notice | color ]] notice = "white",
|
|
--[[REPL: Error | color ]] error = "red",
|
|
--[[return | color ]] repl_return = "light_purple",
|
|
--[[User Code. | color ]] user_input = "white",
|
|
},
|
|
any = { -- Any values
|
|
--[[Prop: | color ]] h_property = "dark_gray",
|
|
--[[Metatable: {} | number ]] meta_len = 16
|
|
},
|
|
null = { -- Nil values
|
|
--[[nil | color ]] default = "gray",
|
|
--[[(no value?) | color ]] no_value = "dark_gray"
|
|
},
|
|
boolean = { -- Booleans
|
|
--[[true false | color ]] default = "yellow",
|
|
--[[true color | color ]] t = "dark_green",
|
|
--[[false color | color ]] f = "dark_red",
|
|
--[[true symbol | string ]] true_char = "☑",
|
|
--[[false symbol | string ]] false_char = "☒"
|
|
},
|
|
number = { -- Numbers
|
|
--[[123 | color ]] default = "blue",
|
|
--[[(0x7B) | color ]] hex = "dark_blue",
|
|
--[[0b10 | color ]] bin = "dark_blue",
|
|
--[[0o71 | color ]] oct = "dark_blue",
|
|
--[[0x, 0X, #, etc. | string ]] hex_prefix = "0x",
|
|
--[[0b, 0B, etc. | string ]] bin_prefix = "0b",
|
|
--[[0o, 0O, 0, etc. | string ]] oct_prefix = "0o"
|
|
},
|
|
string = { -- Strings
|
|
--[["abc" | color ]] default = "red",
|
|
--[[\r\n§ | color ]] escaped = "dark_red",
|
|
--[[\ | color ]] slash = "dark_gray",
|
|
--[[(# bytes) | color ]] bytes = "dark_red",
|
|
--[[# characters | color ]] characters = "dark_red",
|
|
--[[... | color ]] len_limit = "gray",
|
|
--[[= "hello wo..." | number ]] value_size = 256,
|
|
--[["hello worl..." | number ]] max_size = Infinity,
|
|
--[["Hover Da..." | number ]] max_h_size = 4096,
|
|
--[[\0 -> ∅ | boolean]] use_symbols = true
|
|
},
|
|
table = { -- Tables
|
|
--[[table: 1234abcd | color ]] default = "aqua",
|
|
--[[(# indexes) | color ]] indexes = "dark_aqua",
|
|
--[[{ } | color ]] bracket = "dark_gray",
|
|
--[[[ ] | color ]] key_bracket = "dark_gray",
|
|
--[[= | color ]] equals = "dark_gray",
|
|
--[[ · · · (# more) | color ]] line_limit = "gray",
|
|
--[[<ROOT> | color ]] root = "white",
|
|
--[[<DUPE> | color ]] duplicate = "aqua",
|
|
--[[["string"] = | number ]] skey_len = 16,
|
|
--[[max table depth | number ]] max_indent = 1,
|
|
--[[max table len | number ]] max_length = Infinity,
|
|
--[[ · · · } | number ]] more_len = 48,
|
|
--[[Contents: {} | number ]] content_len = 32
|
|
},
|
|
func = { -- Functions
|
|
--[[function: | color ]] default = "light_purple",
|
|
--[[avatar | color ]] script = "dark_purple",
|
|
--[[:123-167 | color ]] lines = "dark_gray",
|
|
--[[builtin: | color ]] builtin = "dark_gray",
|
|
--[[figura: | color ]] figura = "dark_gray",
|
|
--[[unknown: | color ]] unknown = "dark_gray",
|
|
--[[(# bytes) | color ]] bytes = "dark_purple",
|
|
--[[Lua | color ]] lua = "blue",
|
|
--[[(JAVA) | color ]] java = "gold"
|
|
},
|
|
userdata = {
|
|
--[[userdata: | color ]] default = "gray",
|
|
--[[1 stick | color ]] value = "gray"
|
|
},
|
|
thread = { -- Threads
|
|
--[[thread: 1234abc | color ]] default = "green",
|
|
--[[(status) | color ]] parentheses = "dark_green",
|
|
--[[Running | color ]] running = "green",
|
|
--[[Suspended | color ]] suspended = "gold",
|
|
--[[Normal | color ]] normal = "dark_aqua",
|
|
--[[Dead | color ]] dead = "dark_red"
|
|
},
|
|
vector = { -- Vectors
|
|
--[[1.23 | color ]] default = "white",
|
|
--[[< > | color ]] bracket = "dark_gray",
|
|
--[[, | color ]] seperator = "dark_gray",
|
|
--[[(#/6 indexes) | color ]] indexes = "gray",
|
|
--[[123.45 | color ]] length = "gray",
|
|
},
|
|
other = { -- Unknown types.
|
|
--[[stringified val | color ]] default = "white",
|
|
--[[(type) | color ]] type = "gray"
|
|
}
|
|
}
|
|
--[=======================================[ END CONFIG ]=======================================]--
|
|
|
|
local replcatmt = {
|
|
__metatable = false,
|
|
__newindex = function(self, key, value)
|
|
if self[key] == nil then error("cannot change non-existent Theme Setting") end
|
|
if type(value) == "string" then
|
|
rawset(self, key, value:gsub("([\\\"])", "\\%1"))
|
|
else
|
|
rawset(self, key, value)
|
|
end
|
|
end,
|
|
__index = {
|
|
NewSetting = function(self, name, value)
|
|
if self[name] ~= nil then
|
|
rawset(self, name, value or false)
|
|
end
|
|
end
|
|
}
|
|
}
|
|
|
|
for _,c in pairs(repl_theme) do
|
|
setmetatable(c, replcatmt)
|
|
end
|
|
|
|
setmetatable(repl_theme, {
|
|
__metatable = false,
|
|
__newindex = function(self, key)
|
|
if not self[key] then
|
|
error("cannot add new Theme Setting category")
|
|
else
|
|
error("cannot replace Theme Setting category")
|
|
end
|
|
end,
|
|
__index = {
|
|
NewCategory = function(self, name)
|
|
if not self[name] then
|
|
rawset(self, name, setmetatable({}, replcatmt))
|
|
end
|
|
end
|
|
}
|
|
})
|
|
|
|
local
|
|
rtr, rta, rtx,
|
|
rtb, rtn, rts,
|
|
rtt, rtf, rtu,
|
|
rtc, rtv, rto
|
|
=
|
|
repl_theme.repl, repl_theme.any, repl_theme.null,
|
|
repl_theme.boolean, repl_theme.number, repl_theme.string,
|
|
repl_theme.table, repl_theme.func, repl_theme.userdata,
|
|
repl_theme.thread, repl_theme.vector, repl_theme.other
|
|
|
|
local strrep = {
|
|
all = '([\0\a\b\f\n\r\t\v\\"])', --∅♪←⊻↓⏮⇄⇵
|
|
["\0"] = {"0", "∅"},
|
|
["\a"] = {"a", "♪"},
|
|
["\b"] = {"b", "←"},
|
|
["\f"] = {"f", "⊻"},
|
|
["\n"] = {"n", "↓"},
|
|
["\r"] = {"r", "⏮"},
|
|
["\t"] = {"t", "⇄"},
|
|
["\v"] = {"v", "⇵"},
|
|
["\\"] = {"\\\\", "\\\\"},
|
|
["\""] = {'\\"', '\\"'}
|
|
}
|
|
|
|
function strrep.toStr(x)
|
|
return ('",{"text":"\\\\","color":"%s"},{"text":"%s","color":"%s"},"'):format(
|
|
rts.slash,
|
|
strrep[x][1],
|
|
rts.escaped
|
|
)
|
|
end
|
|
|
|
function strrep.toSym(x)
|
|
return ('",{"text":"%s","color":"%s"},"'):format(
|
|
strrep[x][2],
|
|
rts.escaped
|
|
)
|
|
end
|
|
|
|
local keyrank = {
|
|
boolean = 0, number = 1, string = 2, table = 3,
|
|
["function"] = 4, thread = 5, vector = 6, userdata = 7, other = 99
|
|
}
|
|
|
|
local function tblsort(a, b)
|
|
local ar, br = keyrank[type(a)] or keyrank.other, keyrank[type(b)] or keyrank.other
|
|
if ar == br then
|
|
if ar == 1 then
|
|
return a < b
|
|
else
|
|
return tostring(a) < tostring(b)
|
|
end
|
|
else
|
|
return ar < br
|
|
end
|
|
end
|
|
|
|
local figuraFIDs = {
|
|
PingFunction = true
|
|
}
|
|
|
|
H = {}
|
|
local H = H
|
|
setmetatable(H, {
|
|
__pow = function(self, ind)
|
|
if self ~= H then
|
|
error("index from the right side of the history list")
|
|
elseif type(ind) ~= "number" then
|
|
error("quick-history only works with a number")
|
|
else
|
|
local x,y = tostring(ind):match("^(%-?%d*)%.?(%d-)$")
|
|
x,y = tonumber(x) or 1, tonumber(y)
|
|
local res = self[x == 0 and 1 or #self-x+1]
|
|
return res and (y and res[y] or res) or nil
|
|
end
|
|
end
|
|
})
|
|
|
|
O = {}
|
|
local O = O
|
|
local Otypes = {number = true, ["function"] = true, table = true, userdata = true, thread = true, vector = true}
|
|
local Omt = {
|
|
__type = "PointersList",
|
|
__index = {
|
|
N = {},
|
|
Nindex = {}
|
|
}
|
|
}
|
|
local Oindex, OindexN, OindexNi = Omt.__index, Omt.__index.N, Omt.__index.Nindex
|
|
function Omt:__newindex(key)
|
|
local t = type(key)
|
|
if Otypes[t] then
|
|
if t == "number" then
|
|
if not OindexNi[key] then
|
|
OindexN[#Oindex.N+1] = key
|
|
OindexNi[key] = #Oindex.N
|
|
end
|
|
elseif not Oindex[key] then
|
|
Oindex[#Oindex+1] = key
|
|
Oindex[key] = #Oindex
|
|
end
|
|
end
|
|
end
|
|
function Omt:__len() return #Oindex end
|
|
setmetatable(O, Omt)
|
|
|
|
local JSON = {} do
|
|
local function PointersListHover(x, hasContents)
|
|
local xmt = getmetatable(x).__index
|
|
local str = ('{"text":"PointerList","color":"%s"},{"text":" (table)\n","color":"%s"},[{"text":"Pointers: ","color":"%s"},{"text":"%d","color":"%s"}'):format(
|
|
rtt.default,
|
|
rtt.indexes,
|
|
rta.h_property,
|
|
#xmt, rtt.indexes
|
|
)
|
|
if not hasContents then
|
|
str = str .. ',"\n\nContents: "' .. JSON.stringify.custom.PointersList(x, true, true, {
|
|
length = rtt.content_len, indent = "single"
|
|
})
|
|
end
|
|
return ('{"action":"show_text","value":[%s]]}'):format(str)
|
|
end
|
|
|
|
local function PointersListMoreHover(x, tbl, i)
|
|
local strs = {
|
|
('{"text":" · · ·","color":"%s"}'):format(rtt.line_limit)
|
|
}
|
|
for j = i+1, #tbl do
|
|
local v = x[j]
|
|
strs[#strs+1] = (',"\n "%s,{"text":" = ","color":"%s"}%s'):format(
|
|
JSON.stringify.number(j, false, true),
|
|
rtt.equals,
|
|
JSON.stringify.any(v, true, true, {indent = false})
|
|
)
|
|
if j >= (i+rtt.more_len) and j ~= #tbl then
|
|
strs[#strs+1] = (',{"text":"\n · · · (%d more)","color":"%s"}'):format(
|
|
#tbl - j, rtt.line_limit
|
|
)
|
|
break
|
|
end
|
|
end
|
|
return ('{"action":"show_text","value":[%s,{"text":"\n]","color":"%s"}]}'):format(
|
|
table.concat(strs), rtt.bracket
|
|
)
|
|
end
|
|
|
|
local function HistoryHover(x, hasContents)
|
|
--Not yet.
|
|
end
|
|
|
|
JSON.stringify = {
|
|
---@type table<string, fun(x: table, detail: boolean, inHover: boolean, options: {indent?:number|"false", DONE?: table, length?: number, max?: boolean}): string>
|
|
custom={
|
|
---@param x table
|
|
---@param detail? string
|
|
---@param inHover? boolean
|
|
---@param options? {indent?:number|"false", DONE?: table, length?: number, max?: boolean}
|
|
PointersList = function(x, detail, inHover, options)
|
|
local xmt = getmetatable(x).__index
|
|
local indent
|
|
if options.indent == false then
|
|
indent = rtt.max_indent + 1
|
|
else
|
|
indent = tonumber(options.indent) and math.max(options.indent, 0) or 1
|
|
end
|
|
local contents = indent <= rtt.max_indent
|
|
local str = (',[{"text":"PointerList: %s","color":"%s"%s}'):format(
|
|
tostring(x):match("^table: (%x%x?%x?%x?%x?%x?%x?%x?)$") or "???",
|
|
rtt.default,
|
|
not inHover and (',"insertion":"O","hoverEvent":' .. PointersListHover(x, contents)) or ""
|
|
)
|
|
if contents then str = str .. (',[{"text":" [","color":"%s"}'):format(rtt.bracket) end
|
|
if detail then
|
|
str = str .. (',{"text":" (%d pointers)","color":"%s"}'):format(
|
|
#xmt, rtt.indexes
|
|
)
|
|
end
|
|
if contents then
|
|
local strs = {}
|
|
for i,v in ipairs(xmt) do
|
|
strs[#strs+1] = (',"\n%s"%s,{"text":" = ","color":"%s"}%s'):format(
|
|
(" "):rep(indent),
|
|
JSON.stringify.number(i, false, inHover),
|
|
rtt.equals,
|
|
JSON.stringify.any(v, true, inHover, {indent = false})
|
|
)
|
|
if options.length and (i >= options.length) and ((#xmt - i) ~= 0) then
|
|
if inHover then
|
|
strs[#strs+1] = (',{"text":"\n%s · · · (%d more)","color":"%s"}'):format(
|
|
(" "):rep(indent), #xmt - i, rtt.line_limit
|
|
)
|
|
else
|
|
strs[#strs+1] = (',{"text":"\n%s · · · (%d more)","color":"%s","hoverEvent":%s}'):format(
|
|
(" "):rep(indent), #xmt - i, rtt.line_limit, PointersListMoreHover(x, Oindex, i)
|
|
)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
str = str .. ('%s,"\n%s]"]'):format(
|
|
table.concat(strs), (" "):rep(math.max(indent-1, 0))
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end
|
|
},
|
|
|
|
---@param x any
|
|
---@param detail? string
|
|
---@param inHover? boolean
|
|
---@param options? {indent?:number|"false", DONE?: table, length?: number, max?: boolean}
|
|
---@return string
|
|
any = function(x, detail, inHover, options)
|
|
options = options or {}
|
|
local t = type(x)
|
|
if t == "string" then
|
|
return JSON.stringify.string(x, detail, inHover, options.length)
|
|
elseif t == "table" then
|
|
local mt = getmetatable(x)
|
|
local mtt = type(mt) == "table" and mt.__type or nil
|
|
if mtt and JSON.stringify.custom[mtt] then
|
|
return JSON.stringify.custom[mtt](x, detail, inHover, options)
|
|
else
|
|
return JSON.stringify.table(x, detail, inHover, options.indent, options.length, options.DONE)
|
|
end
|
|
elseif t == "vector" then
|
|
return JSON.stringify.vector(x, detail, inHover, options.max)
|
|
else
|
|
return (JSON.stringify[t] or JSON.stringify.other)(x, detail, inHover)
|
|
end
|
|
end,
|
|
---@param inHover? boolean
|
|
---@return string
|
|
["nil"] = function(_, _, inHover)
|
|
return (',{"text":"nil","color":"%s"%s}'):format(
|
|
rtx.default,
|
|
not inHover and (',"insertion":"nil","hoverEvent":%s'):format(JSON.hoverData["nil"]()) or ""
|
|
)
|
|
end,
|
|
---@param x boolean
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@return string
|
|
boolean = function(x, detail, inHover)
|
|
local str = (',[{"text":"%s","color":"%s"%s}'):format(
|
|
tostring(x), rtb.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
tostring(x), JSON.hoverData.boolean(x)
|
|
) or ""
|
|
)
|
|
if detail then
|
|
str = str .. (',{"text":" %s","color":"%s"}'):format(
|
|
x and rtb.true_char or rtb.false_char,
|
|
x and rtb.t or rtb.f
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x number
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@return string
|
|
number = function(x, detail, inHover)
|
|
local unsafenum = tonumber(tostring(x)) ~= x
|
|
local insert = x
|
|
if unsafenum and not O.Nindex[x] then
|
|
O[x] = true
|
|
if not inHover then insert = "O.N[" .. O.Nindex[x] .. "]" end
|
|
end
|
|
local str = (',[{"text":"%s","color":"%s"%s}'):format(
|
|
tostring(x), rtn.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData.number(x)
|
|
) or ""
|
|
)
|
|
if detail and math.floor(x) == x and x-1 ~= x then
|
|
str = str .. (',{"text":" (%s%X)","color":"%s"}'):format(
|
|
rtn.hex_prefix, x, rtn.hex
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x string
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@param length? number
|
|
---@return string
|
|
string = function(x, detail, inHover, length)
|
|
length = tonumber(length)
|
|
local xstr
|
|
if not length or (length <= 0) or (length >= #x) then
|
|
xstr = x
|
|
length = false
|
|
else
|
|
xstr = x:sub(1, length-4)
|
|
end
|
|
|
|
local firstmatch = xstr:find(strrep.all) or xstr:find("§")
|
|
local str
|
|
if firstmatch then
|
|
str = xstr
|
|
:gsub(
|
|
strrep.all,
|
|
rts.use_symbols and strrep.toSym or strrep.toStr
|
|
)
|
|
:gsub(
|
|
"§(.)",
|
|
('",{"text":"ƒ","color":"%s"},"§%%1%%1§r'):format(rts.escaped)
|
|
)
|
|
str = (',[{"text":"\\"%s","color":"%s"%s}'):format(
|
|
str:sub(1, firstmatch-1), rts.default,
|
|
not inHover and (',"insertion":"\\"%s\\"","hoverEvent":%s'):format(
|
|
x
|
|
:gsub(strrep.all, function(c) return "\\\\" .. strrep[c][1] end)
|
|
:gsub("§", "\\\\xC2\\\\xA7")
|
|
:gsub("([\1\2\3\4\5\6\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\127])", function(c) return "\\\\" .. string.byte(c) end),
|
|
JSON.hoverData.string(x)
|
|
) or ""
|
|
) .. str:sub(firstmatch+1)
|
|
if str:find(',"$') then
|
|
str = str:sub(1, -3) .. (length and (',{"text":" · · · ","color":"%s"},"\\""'):format(rts.len_limit) or ',"\\""')
|
|
else
|
|
str = str .. (length and ('",{"text":" · · · ","color":"%s"},"\\""'):format(rts.len_limit) or '\\""')
|
|
end
|
|
else
|
|
str = (',[{"text":"\\"%s","color":"%s"%s}%s,"\\""'):format(
|
|
xstr, rts.default,
|
|
not inHover and (',"insertion":"\\"%s\\"","hoverEvent":%s'):format(
|
|
x
|
|
:gsub(strrep.all, function(c) return "\\\\" .. strrep[c][1] end)
|
|
:gsub("§", "\\\\xC2\\\\xA7")
|
|
:gsub("([\1\2\3\4\5\6\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\127])", function(c) return "\\\\" .. string.byte(c) end),
|
|
JSON.hoverData.string(x)
|
|
) or "",
|
|
length and (',{"text":" · · · ","color":"%s"}'):format(rts.len_limit) or ""
|
|
)
|
|
end
|
|
if detail then
|
|
str = str .. (',{"text":" (%d byte%s)","color":"%s"}'):format(
|
|
#x, #x ~= 1 and "s" or "", rts.bytes
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x table
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@param indent? "false"|number|'"single"'
|
|
---@param length? number
|
|
---@param DONE? table
|
|
---@return string
|
|
table = function(x, detail, inHover, indent, length, DONE)
|
|
local noindent
|
|
if indent == false then
|
|
indent = rtt.max_indent + 1
|
|
elseif indent == "single" then
|
|
noindent = true
|
|
indent = 1
|
|
end
|
|
indent = indent == nil and 1 or math.max(indent, 0)
|
|
if not O[x] then O[x] = true end
|
|
local insert = "O[" .. O[x] .. "]"
|
|
local contents = indent <= rtt.max_indent
|
|
local xlen = 0
|
|
if not inHover or detail then
|
|
for _ in pairs(x) do --Iterate the table for *every* key to get the real size.
|
|
xlen = xlen + 1
|
|
end
|
|
if xlen == 0 then xlen = tonumber(#x) or 0 end --If a table cannot be iterated, try getting the length. If that fails, use 0.
|
|
end
|
|
local str = (',[{"text":"%s","color":"%s"%s}'):format(
|
|
tostring(x), rtt.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData.table(x, contents, xlen)
|
|
) or ""
|
|
)
|
|
if contents then str = str .. (',{"text":" {","color":"%s"}'):format(rtt.bracket) end
|
|
if detail then
|
|
str = str .. (',{"text":" (%d index%s)","color":"%s"}'):format(
|
|
xlen, xlen ~= 1 and "es" or "", rtt.indexes
|
|
)
|
|
end
|
|
if contents and not next(x) then
|
|
str = str .. (',{"text":"%s}","color":"%s"}'):format(
|
|
detail and " " or "",
|
|
rtt.bracket
|
|
)
|
|
contents = false
|
|
end
|
|
str = str .. "]"
|
|
if not DONE then --DONE handles recursion.
|
|
DONE = {}
|
|
DONE.root = x
|
|
DONE[x] = true
|
|
elseif DONE.root == x then
|
|
str = str .. (',{"text":" <ROOT>","color":"%s"}'):format(rtt.root)
|
|
elseif DONE[x] then
|
|
str = str .. (',{"text":" <DUPE>","color":"%s"}'):format(rtt.duplicate)
|
|
else
|
|
DONE[x] = true
|
|
end
|
|
if contents then
|
|
local keys = {}
|
|
for k in pairs(x) do --Get all keys and sort them.
|
|
keys[#keys+1] = k
|
|
end
|
|
table.sort(keys, tblsort)
|
|
|
|
local strs = {}
|
|
for i,k in ipairs(keys) do
|
|
local v = x[k]
|
|
strs[#strs+1] = (',[{"text":"\n%s[","color":"%s"}%s,"]"],{"text":" = ","color":"%s"}%s'):format(
|
|
noindent and " " or (" "):rep(indent*2), rtt.key_bracket,
|
|
JSON.stringify.any(k, false, inHover, {
|
|
length = rtt.skey_len, indent = false, max = false
|
|
}),
|
|
rtt.equals,
|
|
JSON.stringify.any(v, true, inHover, {
|
|
indent = ((not DONE[v] and not noindent) and (indent + 1) or false),
|
|
length = rts.value_size,
|
|
DONE = DONE
|
|
})
|
|
)
|
|
if length and (i >= length) and ((#keys - i) ~= 0) then --If the line limit is hit, stop the table early.
|
|
if inHover then
|
|
strs[#strs+1] = (',{"text":"\n%s · · · (%d more)","color":"%s"}'):format(
|
|
(" "):rep(indent), #keys - i, rtt.line_limit
|
|
)
|
|
else
|
|
strs[#strs+1] = (',{"text":"\n%s · · · (%d more)","color":"%s","hoverEvent":%s}'):format(
|
|
(" "):rep(indent), #keys - i, rtt.line_limit, JSON.hoverData.tableMore(x, keys, i)
|
|
)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
str = str .. ('%s,{"text":"\n%s}","color":"%s"}'):format(
|
|
table.concat(strs), (" "):rep(math.max(indent-1, 0)), rtt.bracket
|
|
)
|
|
end
|
|
return str
|
|
end,
|
|
---@param x function
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@return string
|
|
["function"] = function(x, detail, inHover)
|
|
local s, dump = pcall(string.dump, x)
|
|
local insert
|
|
if not inHover then
|
|
if not O[x] then O[x] = true end
|
|
insert = "O[" .. O[x] .. "]"
|
|
end
|
|
local str
|
|
if s then
|
|
local fname, flines = tostring(x):match("^function: ([^:]+)(:%d+%-%d+)$")
|
|
str = (',[{"text":"function:","color":"%s"%s},{"text":" %s","color":"%s"},{"text":"%s","color":"%s"}'):format(
|
|
rtf.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData["function"](x, #dump)
|
|
) or "",
|
|
fname:gsub("([\\\"])", "\\%1"), rtf.script,
|
|
flines, rtf.lines
|
|
)
|
|
else
|
|
local fid = tostring(x):match(" ?([%w_]+)$")
|
|
local ftype = fid and (
|
|
(tonumber(fid) or figuraFIDs[fid]) and "figura" or "builtin"
|
|
) or "unknown"
|
|
str = (',[{"text":""%s},[{"text":"function: ","color":"%s"},{"text":"%s:","color":"%s"},"%s"]'):format(
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData["function"](x)
|
|
) or "",
|
|
rtf.default,
|
|
ftype, rtf[ftype],
|
|
(fid or "<NAME ERROR>"):gsub("([\\\"])", "\\%1")
|
|
)
|
|
end
|
|
if detail then
|
|
if s then
|
|
str = str .. (',{"text":" (%d byte%s)","color":"%s"}'):format(
|
|
#dump, #dump ~= 1 and "s" or "", rtf.bytes
|
|
)
|
|
else
|
|
str = str .. (',{"text":" (JAVA)","color":"%s"}'):format(rtf.java)
|
|
end
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x userdata
|
|
---@param inHover? boolean
|
|
---@return string
|
|
userdata = function(x, _, inHover)
|
|
local ustr = tostring(x):gsub("([\\\"])", "\\%1")
|
|
local insert
|
|
if not inHover then
|
|
if not O[x] then O[x] = true end
|
|
insert = "O[" .. O[x] .. "]"
|
|
end
|
|
if ustr:match("^userdata: ") then
|
|
ustr = ustr:sub(11)
|
|
end
|
|
return (',[{"text":"userdata: ","color":"%s"%s},{"text":"%s","color":"%s"}]'):format(
|
|
rtu.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData.userdata(x)
|
|
) or "",
|
|
ustr, rtu.value
|
|
)
|
|
end,
|
|
---@param x thread
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@return string
|
|
thread = function(x, detail, inHover)
|
|
local insert
|
|
local status
|
|
if detail or not inHover then status = coroutine.status(x) end
|
|
if not inHover then
|
|
if not O[x] then O[x] = true end
|
|
insert = "O[" .. O[x] .. "]"
|
|
end
|
|
local str = (',[{"text":"%s","color":"%s"%s}'):format(
|
|
tostring(x), rtc.default,
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData.thread(x, status)
|
|
) or ""
|
|
)
|
|
if detail then
|
|
str = str .. (',[{"text":" (","color":"%s"},{"text":"%s","color":"%s"},")"]'):format(
|
|
rtc.parentheses,
|
|
status:gsub("^.", string.upper), rtc[status]
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x Vector
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@param max? boolean
|
|
---@return string
|
|
vector = function(x, detail, inHover, max)
|
|
max = max == nil or max
|
|
local insert
|
|
if not inHover then
|
|
if not O[x] then O[x] = true end
|
|
insert = "O[" .. O[x] .. "]"
|
|
end
|
|
local i = 1
|
|
for j=6,1,-1 do
|
|
if x[j] ~= 0 then i = j break end
|
|
end
|
|
|
|
local strs = {}
|
|
if max then
|
|
for j = 1, i do
|
|
strs[#strs+1] = (',"%f"'):format(x[j])
|
|
end
|
|
else
|
|
for j = 1, i do
|
|
local fstr = tostring(x[j])
|
|
local fsub = fstr:sub(1, (fstr:find("%..*$") or #fstr) + 5)
|
|
strs[#strs+1] = (',"%s%s"'):format(
|
|
fsub, (#fstr > #fsub) and "..." or ""
|
|
)
|
|
end
|
|
end
|
|
strs[1] = (',[{"text":""%s},[{"text":"<","color":"%s"},[{"text":%s,"color":"%s"}'):format(
|
|
not inHover and (',"insertion":"%s","hoverEvent":%s'):format(
|
|
insert, JSON.hoverData.vector(x)
|
|
) or "",
|
|
rtv.bracket,
|
|
strs[1]:sub(2), rtv.default
|
|
)
|
|
strs[#strs] = strs[#strs] .. '],">"]'
|
|
|
|
local sep = (',{"text":",","color":"%s"}'):format(rtv.seperator)
|
|
local str = table.concat(strs, sep)
|
|
|
|
if detail then
|
|
str = str .. (',{"text":" (%d/6 indexes)","color":"%s"}'):format(
|
|
i, rtv.indexes
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end,
|
|
---@param x any
|
|
---@param detail? boolean
|
|
---@param inHover? boolean
|
|
---@return string
|
|
other = function(x, detail, inHover)
|
|
local str = (',[{"text":"%s","color":"%s"%s}'):format(
|
|
tostring(x):gsub("([\\\"])", "\\%1"), rto.default,
|
|
not inHover and (',"hoverEvent":' .. JSON.hoverData.other(x)) or ""
|
|
)
|
|
if detail then
|
|
str = str .. (',{"text":" (%s)","color":"%s"}'):format(
|
|
type(x), rto.type
|
|
)
|
|
end
|
|
return str .. "]"
|
|
end
|
|
}
|
|
local o2b = {
|
|
["0"] = "000", ["1"] = "001", ["2"] = "010", ["3"] = "011",
|
|
["4"] = "100", ["5"] = "101", ["6"] = "110", ["7"] = "111"
|
|
}
|
|
local vectorObj = {
|
|
asTable = 1, toDeg = 2, toRad = 3, angleTo = 4, cross = 5, dot = 6, normalized = 7,
|
|
getLength = 8, distanceTo = 9
|
|
}
|
|
function JSON.stringify.vectorMethods()
|
|
local str = (',{"text":"table: LuaVector","color":"%s"},{"text":" {","color":"%s"},{"text":" (9 indexes)","color":"%s"}'):format(
|
|
rtt.default,
|
|
rtt.bracket,
|
|
rtt.indexes
|
|
)
|
|
local keys = {}
|
|
for k in pairs(vectorObj) do keys[#keys+1] = k end
|
|
table.sort(keys)
|
|
local strs = {}
|
|
for _, k in ipairs(keys) do
|
|
local v = vectorObj[k]
|
|
strs[#strs+1] = (',[{"text":"\n [","color":"%s"}%s,"]"],{"text":" = ","color":"%s"},[{"text":"function: ","color":"%s"},{"text":"figura:","color":"%s"},"%s"],{"text":" (JAVA)","color":"%s"}'):format(
|
|
rtt.key_bracket,
|
|
JSON.stringify.any(k, false, false, {length = rtt.skey_len, indent = false, max = false}),
|
|
rtt.equals,
|
|
rtf.default,
|
|
rtf.figura,
|
|
v,
|
|
rtf.java
|
|
)
|
|
end
|
|
return str .. ('%s,{"text":"\n}","color":"%s"}'):format(
|
|
table.concat(strs),
|
|
rtt.bracket
|
|
)
|
|
end
|
|
JSON.hoverData = {
|
|
["nil"] = function()
|
|
return ('{"action":"show_text","value":[{"text":"Nil\nnil","color":"%s"}]}'):format(rtx.default)
|
|
end,
|
|
boolean = function(x)
|
|
return ('{"action":"show_text","value":[{"text":"Boolean\n","color":"%s"},{"text":"%s","color":"%s"}]}'):format(
|
|
rtb.default,
|
|
tostring(x),
|
|
x and rtb.t or rtb.f
|
|
)
|
|
end,
|
|
number = function(x)
|
|
local str = ('{"text":"Number\n%s","color":"%s"}'):format(
|
|
tostring(x),
|
|
rtn.default
|
|
)
|
|
if math.floor(x) == x and math.abs(x) <= 0x7FFFFFFFFFFFFFFF then
|
|
local sign = x < 0 and "-" or ""
|
|
x = math.abs(x)
|
|
local ostr = ("%o"):format(x)
|
|
str = str .. (',[{"text":"\nHex: ","color":"%s"},{"text":"%s%s%x\n","color":"%s"},"Oct: ",{"text":"%s%s%s\n","color":"%s"},"Bin: ",{"text":"%s%s%s","color":"%s"}]'):format(
|
|
rta.h_property,
|
|
sign, rtn.hex_prefix, x, rtn.hex,
|
|
sign, rtn.oct_prefix, ostr, rtn.oct,
|
|
sign, rtn.bin_prefix, ostr:gsub(".", o2b):gsub("^0+", "", 1), rtn.bin
|
|
)
|
|
end
|
|
return ('{"action":"show_text","value":[%s]}'):format(str)
|
|
end,
|
|
string = function(x)
|
|
local chars = 0
|
|
for i = 1, #x do
|
|
if math.floor(x:byte(i) * 0.015625) ~= 2 then chars = chars + 1 end
|
|
end
|
|
local mt = getmetatable("")
|
|
return ('{"action":"show_text","value":[{"text":"String\n","color":"%s"}%s,[{"text":"\nBytes: ","color":"%s"},{"text":"%d\n","color":"%s"},"Characters: ",{"text":"%d\n\n","color":"%s"},"Metatable: "%s]]}'):format(
|
|
rts.default,
|
|
JSON.stringify.string(x, false, true, rts.max_h_size),
|
|
rta.h_property,
|
|
#x, rts.bytes,
|
|
chars, rts.characters,
|
|
JSON.stringify.any(mt, true, true, {
|
|
indent = "single",
|
|
length = type(mt) == "string" and rts.value_size or rta.meta_len
|
|
})
|
|
)
|
|
end,
|
|
table = function(x, contentVisible, size)
|
|
local mt = getmetatable(x)
|
|
local str = ('{"text":"Table\n%s\n","color":"%s"},[{"text":"Indexes: ","color":"%s"},{"text":"%d\n\n","color":"%s"},"Metatable: "%s'):format(
|
|
tostring(x), rtt.default,
|
|
rta.h_property,
|
|
size, rtt.indexes,
|
|
JSON.stringify.any(mt, true, true, {
|
|
indent = "single",
|
|
length = type(mt) == "string" and rts.value_size or rta.meta_len
|
|
})
|
|
)
|
|
if not contentVisible then
|
|
str = str .. (',"\n\nContents: "' .. JSON.stringify.table(x, false, true, "single", rtt.content_len))
|
|
end
|
|
return ('{"action":"show_text","value":[%s]]}'):format(str)
|
|
end,
|
|
tableMore = function(x, keys, i)
|
|
local strs = {
|
|
('{"text":" · · ·","color":"%s"}'):format(rtt.line_limit)
|
|
}
|
|
for j = i+1, #keys do
|
|
local k = keys[j]
|
|
local v = x[k]
|
|
strs[#strs+1] = (',[{"text":"\n [","color":"%s"}%s,"]"],{"text":" = ","color":"%s"}%s'):format(
|
|
rtt.key_bracket,
|
|
JSON.stringify.any(k, false, true, {
|
|
indent = false, length = rtt.skey_len, max = false
|
|
}),
|
|
rtt.equals,
|
|
JSON.stringify.any(v, true, true, {
|
|
indent = false, length = rts.value_size
|
|
})
|
|
)
|
|
if j >= (i+rtt.more_len) and j ~= #keys then
|
|
strs[#strs+1] = (',{"text":"\n · · · (%d more)","color":"%s"}'):format(
|
|
#keys - j, rtt.line_limit
|
|
)
|
|
break
|
|
end
|
|
end
|
|
return ('{"action":"show_text","value":[%s,{"text":"\n}","color":"%s"}]}'):format(
|
|
table.concat(strs), rtt.bracket
|
|
)
|
|
end,
|
|
["function"] = function(x, size)
|
|
local str = ('{"text":"Function\n","color":"%s"}%s,[{"text":"\nSource: ","color":"%s"},{"text":"%s","color":"%s"}'):format(
|
|
rtf.default,
|
|
JSON.stringify["function"](x, false, true),
|
|
rta.h_property,
|
|
size and "Lua" or "Java", size and rtf.lua or rtf.java
|
|
)
|
|
if size then
|
|
str = str .. (',"\nBytes: ",{"text":"%d","color":"%s"}'):format(
|
|
size, rtf.bytes
|
|
)
|
|
end
|
|
return ('{"action":"show_text","value":[%s]]}'):format(str)
|
|
end,
|
|
userdata = function(x)
|
|
return ('{"action":"show_text","value":[{"text":"Userdata\n","color":"%s"},{"text":"%s","color":"%s"}]}'):format(
|
|
rtu.default,
|
|
tostring(x):gsub("([\\\"])", "\\%1"), rtu.value
|
|
)
|
|
end,
|
|
thread = function(x, status)
|
|
return ('{"action":"show_text","value":[{"text":"Thread\n%s\n","color":"%s"},{"text":"Status: ","color":"%s"},{"text":"%s","color":"%s"}]'):format(
|
|
tostring(x), rtc.default,
|
|
rta.h_property,
|
|
status, rtc[status]
|
|
)
|
|
end,
|
|
vector = function(x)
|
|
local str = ('{"text":"Vector\n","color":"%s"}%s,[{"text":"\nLength: ","color":"%s"},{"text":"%f\n","color":"%s"}'):format(
|
|
rtv.default,
|
|
JSON.stringify.vector(x, false, true, true),
|
|
rta.h_property,
|
|
x.getLength(), rtv.length
|
|
)
|
|
if
|
|
(x[1] >= 0 and x[1] <= 1) and
|
|
(x[2] >= 0 and x[2] <= 1) and
|
|
(x[3] >= 0 and x[3] <= 1)
|
|
then
|
|
local rgb_r,rgb_g,rgb_b = math.floor(x[1]*255), math.floor(x[2]*255), math.floor(x[3]*255)
|
|
local rgb_hsv = vectors.rgbToHSV(x)
|
|
local rgb_h,rgb_s,rgb_v = math.floor(rgb_hsv[1]*360)%360, math.floor(rgb_hsv[2]*10000)*0.01, math.floor(rgb_hsv[3]*10000)*0.01
|
|
|
|
local hsv_h, hsv_s, hsv_v = math.floor(x[1]*360)%360, math.floor(x[2]*10000)*0.01, math.floor(x[3]*10000)*0.01
|
|
local hsv_rgb = vectors.hsvToRGB(x)
|
|
local hsv_r, hsv_g, hsv_b = math.floor(hsv_rgb[1]*255), math.floor(hsv_rgb[2]*255), math.floor(hsv_rgb[3]*255)
|
|
str = str .. (',"\n[RGB]:\n Color: ",{"text":"Lorem_Ipsum █ ⏹⏺◆\n","color":"#%06X"}," RGB: ",{"text":"⏺ %d","color":"#%02X0000"},", ",{"text":"⏺ %d","color":"#00%02X00"},", ",{"text":"⏺ %d\n","color":"#0000%02X"}," HSV: ",{"text":"⏺ %d°","color":"#%06X"},", ",{"text":"⏺ %s%%","color":"#%06X"},", ",{"text":"⏺ %s%%\n","color":"#%06X"},"[HSV]:\n Color: ",{"text":"Lorem_Ipsum █ ⏹⏺◆\n","color":"#%06X"}," HSV: ",{"text":"⏺ %d°","color":"#%06X"},", ",{"text":"⏺ %s%%","color":"#%06X"},", ",{"text":"⏺ %s%%\n","color":"#%06X"}," RGB: ",{"text":"⏺ %d","color":"#%02X0000"},", ",{"text":"⏺ %d","color":"#00%02X00"},", ",{"text":"⏺ %d\n","color":"#0000%02X"}'):format(
|
|
vectors.rgbToINT(x),
|
|
rgb_r, rgb_r,
|
|
rgb_g, rgb_g,
|
|
rgb_b, rgb_b,
|
|
rgb_h, vectors.rgbToINT(vectors.hsvToRGB(vectors.of{rgb_hsv[1], 1, 1})),
|
|
tostring(rgb_s), vectors.rgbToINT(vectors.hsvToRGB(vectors.of{0, rgb_hsv[2], 1})),
|
|
tostring(rgb_v), vectors.rgbToINT(vectors.hsvToRGB(vectors.of{0, 0, rgb_hsv[3]})),
|
|
|
|
vectors.rgbToINT(vectors.hsvToRGB(x)),
|
|
hsv_h, vectors.rgbToINT(vectors.hsvToRGB(vectors.of{x[1], 1, 1})),
|
|
tostring(hsv_s), vectors.rgbToINT(vectors.hsvToRGB(vectors.of{0, x[2], 1})),
|
|
tostring(hsv_v), vectors.rgbToINT(vectors.hsvToRGB(vectors.of{0, 0, x[3]})),
|
|
hsv_r, hsv_r,
|
|
hsv_g, hsv_g,
|
|
hsv_b, hsv_b
|
|
)
|
|
end
|
|
|
|
return ('{"action":"show_text","value":[%s,"\nMethods: "%s]]}'):format(
|
|
str,
|
|
JSON.stringify.vectorMethods()
|
|
)
|
|
end,
|
|
other = function(x)
|
|
return ('{"action":"show_text","value":[{"text":"%s\n","color":"%s"},{"text":"%s","color":"%s"}]}'):format(
|
|
type(x):gsub("^.", string.upper), rto.type,
|
|
tostring(x):gsub("\\\"", "\\%1"), rto.default
|
|
)
|
|
end
|
|
}
|
|
end
|
|
|
|
local rotbl = {
|
|
__metatable = false,
|
|
__newindex = function() error("attempt to modify read-only table") end
|
|
}
|
|
|
|
REPL = {
|
|
currentcommand = "",
|
|
stringify = JSON.stringify,
|
|
theme = repl_theme,
|
|
bound = false,
|
|
key = keybind.newKey("[REPL] Bind to Chat", "GRAVE_ACCENT"),
|
|
keyWP = false,
|
|
log = function(x, detail, inHover, options)
|
|
options = type(options) == "table" and options or {}
|
|
log(('[{"text":"","italic":false}%s]'):format(
|
|
JSON.stringify.any(x, detail, inHover, {
|
|
indent = options.indent, length = options.length, max = options.max
|
|
})
|
|
), true)
|
|
end,
|
|
---@type {boolean: number, number: string, string: table, table: Vector, Vector: userdata, userdata: boolean}
|
|
testtable = setmetatable({
|
|
[true] = 123.456,
|
|
[123.456] = "\abcxyz",
|
|
["qwer\ty"] = setmetatable({"hello", "world", setmetatable({"!"}, rotbl)}, rotbl),
|
|
[setmetatable({"foo","bar","baz",yalike="jazz?"}, rotbl)] = vectors.of{1,2,3,4,5,math.sqrt(2)},
|
|
[vectors.of{1,2,3,4,5,math.sqrt(2)}] = item_stack.createItem("minecraft:stick")["figura$item_stack"],
|
|
[item_stack.createItem("minecraft:stone")["figura$item_stack"]] = false
|
|
}, rotbl),
|
|
RegisterStringifier = function(name, stringify)
|
|
|
|
end
|
|
}
|
|
local REPL = REPL
|
|
local REPLSuperActions = {
|
|
fixstringmt = {
|
|
func = function()
|
|
local t = {}
|
|
for k,f in pairs(string) do
|
|
t[k] = f
|
|
end
|
|
getmetatable("").__index = t
|
|
log("Set string metatable index to " .. tostring(string))
|
|
end,
|
|
desc = "Repairs the string metatable.",
|
|
help = "Repairs the string metatable.\n" ..
|
|
"This is useful if you somehow broke string methods.\n" ..
|
|
"The string metatable is required to be functional for the REPL to run.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#fixstringmt"
|
|
},
|
|
error = {
|
|
func = function()
|
|
error("forced critical REPL error.")
|
|
end,
|
|
desc = "Force a critical error in the REPL.",
|
|
help = "Force a critical error in the REPL.\n" ..
|
|
"Used to emulate a Lua error in the REPL itself instead of an error with REPL input.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#error"
|
|
},
|
|
avatarerror = {
|
|
func = function(yes)
|
|
if yes == "yes" then
|
|
return "\0\9\0\70\79\82\67\69\0\9\0"
|
|
else
|
|
log("Please use \"$$#avatarerror yes\" to confirm.")
|
|
end
|
|
end,
|
|
desc = "Force your avatar to error.",
|
|
help = "Force your avatar to error.\n" ..
|
|
"The only way to reverse this action is to reload the avatar.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#avatarerror - Does nothing.\n" ..
|
|
" $$#avatarerror yes - Causes an avatar error."
|
|
},
|
|
mlcancel = {
|
|
func = function()
|
|
if REPL.currentcommand == "" then
|
|
log("There is no current Multi-line input!")
|
|
else
|
|
REPL.currentcommand = ""
|
|
end
|
|
end,
|
|
desc = "Cancels the current multi-line input.",
|
|
help = "Cancels the current multi-line input.\n" ..
|
|
"Useful if you want to cancel an entire chunk of multi-line Lua without causing issues.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#mlcancel"
|
|
},
|
|
mlback = {
|
|
func = function()
|
|
local lastline = REPL.currentcommand:find("[^\n]*\n$")
|
|
if lastline then
|
|
REPL.currentcommand = REPL.currentcommand:sub(1, lastline-1)
|
|
else
|
|
log("There is no current Multi-line input!")
|
|
end
|
|
end,
|
|
desc = "Deletes the last line of a multi-line input.",
|
|
help = "Deletes the last line of a multi-line input.\n" ..
|
|
"Useful if you make an error and you want to try again.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#mlback"
|
|
},
|
|
mlrun = {
|
|
func = function()
|
|
if REPL.currentcommand == "" then
|
|
log("There is no current Multi-line input!")
|
|
else
|
|
REPL()
|
|
end
|
|
end,
|
|
desc = "Run the current Multi-line input as is.",
|
|
help = "Run the current Multi-line input as is.\n" ..
|
|
"Useful if you accidentally start a new line instead of running the input.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#mlrun"
|
|
},
|
|
mlprint = {
|
|
func = function()
|
|
if REPL.currentcommand == "" then
|
|
log("There is no current Multi-line input!")
|
|
else
|
|
log(('[{"text":"Current input:\n","italic":false},{"text":"%s","color":"%s"}]'):format(
|
|
REPL.currentcommand:gsub("([\\\"])", "\\%1"),
|
|
rtr.user_input
|
|
), true)
|
|
end
|
|
end,
|
|
desc = "Prints the current Multi-line input to chat.",
|
|
help = "Prints the current Multi-line input to chat.\n" ..
|
|
"Useful if you forgot where you were in your multi-line input.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#mlprint"
|
|
},
|
|
set = {
|
|
func = function(args)
|
|
local cat, set, val = args:match("^([^.]*)%.?(%S*) ?(.*)$")
|
|
if cat == "" then
|
|
local options = {}
|
|
for k in pairs(repl_theme) do
|
|
if k ~= "" then options[#options+1] = k end
|
|
end
|
|
table.sort(options)
|
|
local strs = {}
|
|
for _,k in ipairs(options) do
|
|
strs[#strs+1] = k
|
|
end
|
|
log("Categories:\n" .. table.concat(strs, ", "))
|
|
elseif not repl_theme[cat] then
|
|
log(("Theme category [%s] not found.\nUse \"$$#set\" to list all categories."):format(cat))
|
|
elseif set == "" then
|
|
local tcat = repl_theme[cat]
|
|
local options = {}
|
|
for k in pairs(tcat) do
|
|
if k ~= "" then options[#options+1] = k end
|
|
end
|
|
table.sort(options)
|
|
local strs = {}
|
|
for _,k in ipairs(options) do
|
|
local v = tcat[k]
|
|
strs[#strs+1] = ("[%s] - %s"):format(
|
|
k,
|
|
(type(v) == "string" and not v:match("^#%x%x%x%x%x%x$"))
|
|
and ('"' .. tostring(v):gsub("([\\\"])", "\\%1") .. '"')
|
|
or tostring(v)
|
|
)
|
|
end
|
|
log("Settings for category:\n[" .. cat .. "]:\n " .. table.concat(strs, "\n "))
|
|
elseif repl_theme[cat][set] == nil then
|
|
log(("Theme setting [%s.%s] not found.\nUse \"$$#set %s\" to list all settings in this category."):format(
|
|
cat, set,
|
|
cat
|
|
))
|
|
elseif val == "" then
|
|
local tset = repl_theme[cat][set]
|
|
local tsett = type(tset)
|
|
log(("Value for setting:\n[%s.%s]:\n %s"):format(
|
|
cat, set,
|
|
(tsett == "string" and not tset:match("^#%x%x%x%x%x%x$"))
|
|
and ('"' .. tostring(tset):gsub("([\\\"])", "\\%1") .. '"')
|
|
or (tsett == "number" and math.abs(tset) == math.huge)
|
|
and (tset < 0 and "-Infinity" or "Infinity")
|
|
or tostring(tset)
|
|
))
|
|
else
|
|
---@type string|number|boolean
|
|
local value
|
|
if val:match("^\".+\"$") then
|
|
value = val:sub(2,-2)
|
|
elseif val:match("^#%x%x%x%x%x%x$") then
|
|
value = val
|
|
elseif tonumber(val) then
|
|
value = tonumber(val)
|
|
elseif val == "true" or val == "false" then
|
|
value = val == "true"
|
|
elseif val:match("^%-?[Ii]nfinity$") or val:match("^%-?[Ii]nf$") then
|
|
local m = val:sub(1,1) == "-"
|
|
value = m and -math.huge or math.huge
|
|
else
|
|
log("Invalid value. Please do \"$$#help set\" to see what values can be used.")
|
|
return
|
|
end
|
|
repl_theme[cat][set] = value
|
|
end
|
|
end,
|
|
desc = "Quickly set REPL theme settings.",
|
|
help = "Quickly set REPL theme settings.\n" ..
|
|
"Please make sure you are using sane values. The resulting value is not checked.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#set - View all categories.\n" ..
|
|
" $$#set <category> - View all settings in the category.\n" ..
|
|
" $$#set <category.setting> - View the current value for this setting.\n" ..
|
|
" $$#set <category.setting> <value> - Sets the setting to the given value.\n" ..
|
|
" <value> can be:\n" ..
|
|
" {string} (\"string\"),\n" ..
|
|
" {number} (123.45),\n" ..
|
|
" {boolean} (true/false)"
|
|
}
|
|
}
|
|
|
|
local RSABlCSt, RSABlCStT, RSABlCStH = false, "", "" if loadSecrets then
|
|
--[[
|
|
I see you are poking around...
|
|
|
|
Everything in this block is part of the "REPL Secret" and is for fun.
|
|
If you ruin the fun and cheat to view these then I will be disappointed in you :(
|
|
|
|
If you *really* want a hint to one of them, mention GrandpaScout with the message
|
|
"I need a REPL moment." in Blancworks' general chat.
|
|
You will get a reply as soon as the message is recieved. The reply will have a warning and
|
|
will be spoilered to avoid spoiling it for others.
|
|
]]--
|
|
|
|
local function RSASt2Sc(a)
|
|
---@diagnostic disable-next-line: deprecated
|
|
return loadstring("return ".. loadstring(([[return(%s):gsub("(%%d%%d%%d)",function(a)return _G["\115\116\114\105\110\103"]["\99\104\97\114"](_G["\116\111\110\117\109\98\101\114"](a))end)]]):format(a))())()
|
|
end
|
|
RSABlCSt = RSASt2Sc[[(0 ..0x1EF6BAD164A9 ..0x9EB5E76D48F ..0x3BE5BEF1E60 ..0x931D9C4F0FF ..0x24F8D26F541A ..0x3DF25A8612EC ..0x98F37246B83 ..0x6C7D92)]]
|
|
RSABlCStT = RSASt2Sc[[(0 ..0x1EFD07B8A344 ..0x93226C12A77 ..0x40AF269AE82A ..0x5A25443C9646 ..0xA76E7ABBE7B ..0x4)]]
|
|
RSABlCStH = RSASt2Sc[[(0 ..0x319C4710DF4 ..0x4998C482275A ..0x630D54ECBA1 ..0x12A095FD6C98 ..0xBBA2)]]
|
|
|
|
local a = RSASt2Sc[[(
|
|
0x0B3231CBD021 ..0x526905BAC99C ..0x00E6C5CD67E7 ..0x0921A115728F ..0x095F167E326F
|
|
..0x256F8B738488 ..0x1EF9C105B2BE ..0x0AA6D8708B36 ..0x37FFC3C02FD8 ..0x1F0351679E0F
|
|
..0x0A5F0FF3BF8B ..0x2E1CAD3F0564 ..0x3C13A2D6FE82 ..0x098F6CC348DA ..0x2E601D23269C
|
|
..0x08D4F9787560 ..0x2DD4705871B5 ..0x0F8DA57AE936 ..0x091955403431 ..0x12A095FD6C98
|
|
..0x045F43E24636 ..0x496349555AA0 ..0x085F29620443 ..0x2539E689E835 ..0x00000104F145
|
|
)]]
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F0315CCDFC6 ..0x643B6EA)]]] = a
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F0315BDB4FD ..0x1D8CA)]]] = a
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F047A97F46A ..0xAA6C6738BDF ..0xFC2)]]] = a
|
|
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F047AD4F98C ..0x1B5A2)]]] = RSASt2Sc[[(
|
|
0x0B3231CBD021 ..0x526905BAC99C ..0x00E6C5CD67E7 ..0x0921A115728F ..0x095F167E326F
|
|
..0x256F8B738488 ..0x0318F9B3C707 ..0x096309D1B6DE ..0x1D2BD5A43A75 ..0x0B01FF8B9727
|
|
..0x03AACC21F4F4 ..0x09D52E028E0C ..0x24B09E71EFA9 ..0x0102C4CE21EB ..0x24B2D7A235E2
|
|
..0x04A4A5F8F2EC ..0x03AB436705C1 ..0x09D5049A462D ..0x075E6A9EBC93 ..0x09328033F89B
|
|
..0x058F8DC725F1 ..0x09322728DDB9 ..0x0967AEE45498 ..0x045FBAF1B627 ..0x1BE76712F45C
|
|
..0x085F29620449 ..0x12A073723033 ..0x0EA7DC39C645
|
|
)]]
|
|
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F0351C34AC9 ..0x18AAA)]]] = RSASt2Sc[[(
|
|
0x0B3231CBD021 ..0x526905BAC99C ..0x00E6C5CD67E7 ..0x0921A115728F ..0x095F167E326F
|
|
..0x256F8B738488 ..0x0318F9B3C76A ..0x2DE00D6584B4 ..0x08D4DB95B5F6 ..0x401553900D14
|
|
..0x09039C3D3DE7 ..0x24B085F6127E ..0x045EBABED2C9 ..0x0669EDFBF082 ..0x098F6CC348DA
|
|
..0x2E601D23269C ..0x08D4F9787560 ..0x2DD4705871B5 ..0x0F8DA57AE936 ..0x091955403431
|
|
..0x12A095FD6C98 ..0x045F43E24636 ..0x496349555AA0 ..0x085F29620443 ..0x2539E689E835
|
|
..0x00000104F145
|
|
)]]
|
|
|
|
a = RSASt2Sc[[(
|
|
0x0B3231CBD021 ..0x526905BAC99C ..0x00E6C5CD67E7 ..0x0921A115728F ..0x095F167E326F
|
|
..0x256F8B738488 ..0x1EF9C1060C97 ..0x0AA4DDBC283F ..0x49ADE03DDEFC ..0x58510B785A74
|
|
..0x0A192ADEE53F ..0x06789D11CEAD ..0x09309D5D23C3 ..0x492DA202AD14 ..0x09039C3D3DE7
|
|
..0x24B085F6127E ..0x04BC4DDD3629 ..0x03AFE7425482 ..0x098F6CC348DA ..0x2E601D23269C
|
|
..0x08D4F9787560 ..0x2DD4705871B5 ..0x0F8DA57AE936 ..0x091955403431 ..0x12A095FD6C98
|
|
..0x045F43E24636 ..0x496349555AA0 ..0x085F29620443 ..0x2539E689E835 ..0x00000104F145
|
|
)]]
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F065843EBC8 ..0xA77F9EE04FB ..0x16BA79CB2)]]] = a
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F065843EBC8 ..0xA77F9EE04FB ..0x58C86BD53DA)]]] = a
|
|
|
|
a = RSASt2Sc[[(
|
|
(0x0B3231CBD021 ..0x526905BAC99C ..0x00E6C5CD67E7 ..0x0921A115728F ..0x095F167E326F
|
|
..0x256F8B738488 ..0x004F4C2B94B9 ..0x0927B29E72B8 ..0x0A8F4258B5A2 ..0x40B5F99E5396
|
|
..0x1D359CF9FCA8 ..0x093227415F8F ..0x03BAD88F4BD9 ..0x0960E1E54627 ..0x1312B7069280
|
|
..0x3C1FFDA52053 ..0x0AD545908417 ..0x0493A07AE0C5 ..0x09EC94A89ECF ..0x37ABA370E8B7
|
|
..0x0CC31A671095 ..0x0A6116DBD22A ..0x2E79E2C4ADF9 ..0x09294F8018A1 ..0x0ABDC101B39E
|
|
..0x0103D8B25B08 ..0x09D528777C0B ..0x0100963B66CA ..0x0931D9C4D60B ..0x01E933FB41AC
|
|
..0x09309D5D2DE7 ..0x132C54246601 ..0x0A18E4AE4540 ..0x098F0779E887 ..0x02C1F75E606D
|
|
..0x001927372A29 ..0x091AA8A55EE7 ..0x01EAD46133EC ..0x098F49090CEA ..0x2E77941DDCEF
|
|
..0x0E94C449A790 ..0x00FE054A7CF9 ..0x092DC0A2F420 ..0x0A1B259F98E7 ..0x40B87F163209
|
|
..0x0101775D7E7B ..0x01D9210E2115 ..0x09ECAC09112A ..0x01020063F0A0 ..0x094975AAFEC9
|
|
..0x40A5E123574B ..0x0DABEFF0F2C9 ..0x098F49090CEB ..0x378437C7CA84 ..0x1D32D14DE7F4
|
|
..0x0932450EA80B ..0x058ED5E5D4A5 ..0x09D5168FBE8B ..0x0A26A1E281C5 ..0x015E45C6D07B
|
|
..0x01D920B2B6B1 ..0x0960827C8BAF ..0x131E5BDCBFE0 ..0x09039C404CB7 ..0x3773F0D38679
|
|
..0x1320EADB2301 ..0x0A0389363985 ..0x4090E5927D03 ..0x00034460CF56 ..0x09190DE47A4D
|
|
..0x52D421A51444 ..0x1D359CFA0C96 ..0x0960D57C6D86 ..0x04A72F903F46 ..0x098F1F6562B1
|
|
..0x4010CE147020 ..0x1D2AE766AA55 ..0x093244C6FE4F ..0x131E5BDCBFE1 ..0x0EA3E659D556
|
|
..0x095EE744A18E ..0x52C5FDDC5883 ..0x0E94C4498850 ..0x0A8F425ECE2F ..0x24ABF6F09BCA
|
|
..0x1D359D63BF30 ..0x001A918D7B19 ..0x091AA8A560E3 ..0x0103617D1188 ..0x093056460A3F
|
|
..0x01EC3AD79B15 ..0x09190DE47D6E ..0x409EB84AD00C ..0x1D220C37D0B1 ..0x09EC4D20890F
|
|
..0x377D43F1357D ..0x0A1BAFEF6754 ..0x0AD4F228E78F ..0x01E8809231D6 ..0x095EE727872B)..
|
|
(0x2E6E418DA17A ..0x02EB51AF40D3 ..0x1317634C9DBB ..0x0A1C67B14229 ..0x0A0377C3F9C2
|
|
..0x2E62A2ADC9C8 ..0x1D3130D88840 ..0x094975AAFECB ..0x0677EA332C5C ..0x098F49090CEB
|
|
..0x378437BCA5DC ..0x078E0E18161B ..0x09FF139C4BCE ..0x03BBA1DA607B ..0x127B495C1D83
|
|
..0x0CD57F94E666 ..0x0A1B133DC452 ..0x0A0D08F387B0 ..0x08D3346EFC8E ..0x075C131CAD33
|
|
..0x00F2637C0F00 ..0x008BD13625D9 ..0x091FC3B55529 ..0x0A03DD11CC59 ..0x2DC446968B64
|
|
..0x1D33FB53BEA1 ..0x0A038936385A ..0x03BAD88F4BD9 ..0x0960E1E54627 ..0x131C0D2E7733
|
|
..0x00178D128D67 ..0x000255F5A756 ..0x09190D939F79 ..0x40AA7D457155 ..0x0019E1ADB859
|
|
..0x091FC3B568B1 ..0x09EC2365DCFF ..0x2DC446968B64 ..0x1D3130BA4E39 ..0x0B03EDD8BB91
|
|
..0x40A828AC8FDB ..0x001785E05BD7 ..0x000255F5A756 ..0x09190DD84A5C ..0x2537AFA5FE41
|
|
..0x0EA58738B0B0 ..0x09322D31273A ..0x096316ECF856 ..0x1D356225BB30 ..0x0A1B13BDD70B
|
|
..0x52CD20BEFB00 ..0x06A4693D09E0 ..0x2537AFA5FE41 ..0x0EA58738B0B0 ..0x09322D31273A
|
|
..0x096316ECF856 ..0x1D3561D944F6 ..0x09190DDFE92A ..0x01014DEDE7F4 ..0x098F43101EAA
|
|
..0x03BADD178B50 ..0x098F49090CEB ..0x0A26A1E281C5 ..0x015E45C6D07B ..0x127B6395D472
|
|
..0x1D34AE613548 ..0x09D4EC5CA786 ..0x2563BE16E3B5 ..0x1320EBCF46B8 ..0x09EC1D6E7557
|
|
..0x133353413073 ..0x0CD669798C41 ..0x0AA684E45139 ..0x01EB47B5B174 ..0x0977CA8104CA
|
|
..0x0A1B026CD2B2 ..0x02EBC2E5CAEF ..0x057C75B85093 ..0x09305656D12A ..0x0962F7566B8B
|
|
..0x092F62683BCA ..0x09BDF7580BF6 ..0x0A220222F4C4 ..0x1D312C325135 ..0x0A8F89E55DAB
|
|
..0x01EBC373EE4B ..0x09309DB8C07B ..0x127B6395D472 ..0x1D3130401531 ..0x010061AC794B
|
|
..0x092F98D37A37 ..0x091AA9227E2F ..0x37948BDC2E71 ..0x0A18E4AE3988 ..0x0930560A8779
|
|
..0x40AA7D52B847 ..0x0CD491948E33 ..0x09323F1BEF3F ..0x24C7E2BC9020 ..0x1D3130D88840)..
|
|
(0x0A1ACBB738B7 ..0x0A28FBE66922 ..0x1D2F8ED6CC54 ..0x0109A7234680 ..0x06607895CF9C
|
|
..0x24ABD7F58B7C ..0x2D85A64E0844 ..0x093256E7447E ..0x075FCD15984F ..0x09EC70D924FB
|
|
..0x0A1D2DE523CB ..0x092F98D34B56 ..0x0B01FF8B997F ..0x37A284216390 ..0x3C1FFDA52053
|
|
..0x0AD545908417 ..0x0493A089FBFE ..0x09321B4DFF2A ..0x0A22004EA97D ..0x0A1BAFEFBD47
|
|
..0x0A60C358BDA2 ..0x1B93AF0E6BA1 ..0x0EA58738B086 ..0x098F1F6562B1 ..0x3FF4E7A7E858
|
|
..0x006B5109DA79 ..0x00EA58BB390F ..0x52BCE2B9B468 ..0x004AC87A57F3 ..0x091FC898EB7F
|
|
..0x0A60B77DC0FA ..0x1B982F2B39FF ..0x0102A1806FEB ..0x24E858C57E42 ..0x05EAF5D4245E
|
|
..0x36E11A831A3B ..0x0176CA3DB58D ..0x083767D2F551 ..0x09D5403840F7 ..0x0839BF540AC5
|
|
..0x00178684D936 ..0x091955403431 ..0x12A095FD6C98 ..0x045F43E24636 ..0x496349555AA0
|
|
..0x085F29620443 ..0x2539E689E835 ..0x00000104F145)
|
|
)]]
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x1F0403DC5B0D ..0x6CCFB8A)]]] = a
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x31A0062D5E7 ..0x6C4ACA)]]] = a
|
|
REPLSuperActions[RSASt2Sc[[(0 ..0x4F640E638B ..0x92F62683BCA ..0x662721A)]]] = a
|
|
end
|
|
REPLSuperActions.help = {
|
|
func = function(arg)
|
|
local SA = REPLSuperActions[arg]
|
|
if SA and not v[RSABlCStH] then
|
|
log(string.format('{"text":"Help for [%s]:\n%s\n","italic":false}',
|
|
arg == "" and "help" or arg,
|
|
SA.help
|
|
and string.gsub(SA.help, "([\\\"])", "\\%1")
|
|
or string.format("No help found for this SuperAction.\nAssumed usage:\n $$#%s - Run SuperAction", arg)
|
|
), true)
|
|
else
|
|
log("No SuperAction with that name found.")
|
|
end
|
|
end,
|
|
desc = "Provides help about SuperActions.",
|
|
help = "Provides help about SuperActions.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#help - Get help about the help SuperAction.\n" ..
|
|
" $$#help <name> - Get help about the named SuperAction."
|
|
}
|
|
REPLSuperActions[""] = {
|
|
func = function(arg)
|
|
local a = arg == RSABlCSt
|
|
local topics = {}
|
|
for k in pairs(REPLSuperActions) do
|
|
topics[#topics+1] = k
|
|
end
|
|
table.sort(topics)
|
|
local strs = {}
|
|
for _,k in ipairs(topics) do
|
|
v = REPLSuperActions[k]
|
|
if not v[RSABlCStH] then
|
|
strs[#strs+1] = string.format("[$$#%s]: %s", k, v.desc or "No description provided...")
|
|
end
|
|
end
|
|
log("All SuperActions:\n" .. table.concat(strs, "\n") .. "\n")
|
|
if a then
|
|
local astrs = {}
|
|
for _,k in ipairs(topics) do
|
|
if REPLSuperActions[k][RSABlCStH] then
|
|
astrs[#astrs+1] = string.format("@ [$$#%s]", k)
|
|
end
|
|
end
|
|
log(RSABlCStT .. table.concat(astrs, "\n") .. "\n")
|
|
end
|
|
end,
|
|
desc = "List all SuperActions.",
|
|
--"What? That's not what this SA does!"
|
|
--If this were to be typed out in chat, it would look like this "$$#help".
|
|
--Therefore, this is actually the help topic for the help SA.
|
|
help = "Provides help about SuperActions.\n" ..
|
|
"Usage:\n" ..
|
|
" $$#help - Get help about the help SuperAction.\n" ..
|
|
" $$#help <name> - Get help about the named SuperAction.\n\n" ..
|
|
"If you were looking for a list of SuperActions, try \"$$#\"."
|
|
}
|
|
local REPLmt = setmetatable({
|
|
__newindex = function()
|
|
error("The REPL table is immutable to avoid self-destruction of the REPL.")
|
|
end,
|
|
__call = function(self, cmd)
|
|
local str, nl
|
|
if cmd ~= nil then
|
|
cmd = tostring(cmd)
|
|
if string.sub(cmd, 1, 3) == "$$#" then
|
|
--Assume the worst, the code in this block should *all* run even if the string metatable is fucked.
|
|
local SAcmd, SAarg = string.match(cmd, "^$$#(%S*) ?(.*)$")
|
|
SAcmd = string.lower(SAcmd)
|
|
if REPLSuperActions[SAcmd] then
|
|
log(string.format('{"text":"REPL: Running SuperAction.","color":"%s","italic":false}', rtr.notice), true)
|
|
local ret = REPLSuperActions[SAcmd].func(SAarg)
|
|
if ret == "\0\9\0\70\79\82\67\69\0\9\0" then
|
|
return "\0\9\0\70\79\82\67\69\0\9\0"
|
|
end
|
|
else
|
|
log(string.format('{"text":"REPL: SuperAction not found!\nUse $$# to list all valid SuperActions.","color":"%s","italic":false}', rtr.error), true)
|
|
end
|
|
return
|
|
end
|
|
str, nl = cmd:match("^(.-)(;?)$")
|
|
if not str then error "Command error." end
|
|
if #REPL.currentcommand == 0 and str:sub(1,1) == "/" then
|
|
log(('{"text":"REPL: Ignoring Minecraft command.","color":"%s","italic":false}'):format(rtr.notice), true)
|
|
chat.setFiguraCommandPrefix()
|
|
chat.sendMessage(str)
|
|
chat.setFiguraCommandPrefix("")
|
|
return
|
|
end
|
|
REPL.currentcommand = REPL.currentcommand .. str .. "\n"
|
|
else
|
|
str = ""
|
|
end
|
|
if nl ~= ";" then
|
|
chat.setFiguraCommandPrefix()
|
|
local ccmd = REPL.currentcommand:sub(1, -2)
|
|
REPL.currentcommand = ""
|
|
local f = loadstring("return " .. ccmd)
|
|
if type(f) == "function" then
|
|
log(('[{"text":"INPUT:\n","color":"%s","italic":false},{"text":"return ","color":"%s"},{"text":"%s\n","color":"%s"}]'):format(
|
|
rtr.input,
|
|
rtr.repl_return,
|
|
ccmd:gsub("([\\\"])", "\\%1"), rtr.user_input
|
|
), true)
|
|
else
|
|
f = loadstring(ccmd)
|
|
if type(f) == "function" then
|
|
log(('[{"text":"INPUT:\n","color":"%s","italic":false},{"text":"%s\n","color":"%s"}]'):format(
|
|
rtr.input,
|
|
ccmd:gsub("([\\\"])", "\\%1"), rtr.user_input
|
|
), true)
|
|
else
|
|
log(('{"text":"REPL: Compile Error!\n%s","color":"%s","italic":false}'):format(
|
|
f:gsub("\t", " "):gsub("([\\\"])", "\\%1"), rtr.error
|
|
), true)
|
|
chat.setFiguraCommandPrefix("")
|
|
return
|
|
end
|
|
end
|
|
local r = {pcall(f)}
|
|
if not r[1] then
|
|
log(('{"text":"REPL: Runtime Error!\n%s","color":"%s","italic":false}'):format(
|
|
r[2]:gsub("\t", " "):gsub("([\\\"])", "\\%1"):gsub("§.", ""), rtr.error
|
|
), true)
|
|
chat.setFiguraCommandPrefix("")
|
|
return
|
|
end
|
|
table.remove(r, 1)
|
|
local _H = {}
|
|
H[#H+1] = _H
|
|
local rh = 0
|
|
for i in pairs(r) do if i > rh then rh = i end end
|
|
for i=1,rh do
|
|
local v = r[i]
|
|
_H[i] = v
|
|
r[i] = JSON.stringify.any(v, true, false, {
|
|
indent = rtt.max_indent < 0 and rtt.max_indent or nil,
|
|
length = type(v) == "string" and rts.max_size or rtt.max_length
|
|
})
|
|
end
|
|
if rh == 0 then
|
|
r[1] = ('%s,{"text":" (no value?)","color":"%s"}'):format(
|
|
JSON.stringify["nil"](),
|
|
rtx.no_value
|
|
)
|
|
end
|
|
log(('[{"text":"RETURNS:\n","color":"%s","italic":false}%s,"\n"]'):format(
|
|
rtr.returns,
|
|
table.concat(r, ',"\n"')
|
|
), true)
|
|
chat.setFiguraCommandPrefix("")
|
|
end
|
|
end
|
|
}, {
|
|
__newindex = function()
|
|
error("The REPL metatable is immutable to avoid self-destruction of the REPL.")
|
|
end,
|
|
__metatable = false
|
|
})
|
|
|
|
--Store pointer to the Environment.
|
|
--[[ O[1] ]] O[_ENV] = true
|
|
|
|
--Store pointers to REPL values.
|
|
--[[ O[2] ]] O[REPL] = true
|
|
--[[ O[3] ]] O[REPL.key] = true
|
|
--[[ O[4] ]] O[REPL.log] = true
|
|
--[[ O[5] ]] O[REPL.stringify] = true
|
|
--[[ O[6] ]] O[REPL.theme] = true
|
|
|
|
--Store pointer to REPL metatable.
|
|
--[[ O[7] ]] O[REPLmt] = true
|
|
|
|
--Store pointers to O values.
|
|
--[[ O[8] ]] O[O] = true
|
|
--[[ O[9] ]] O[O.N] = true
|
|
--[[ O[10] ]] O[O.Nindex] = true
|
|
|
|
--Store pointers to instances.
|
|
INSTANCE_Biome = biome.getBiome("minecraft:plains", {})
|
|
--[[ O[11] ]] O[INSTANCE_Biome] = true
|
|
|
|
INSTANCE_BlockState = block_state.createBlock("minecraft:stone")
|
|
--[[ O[12] ]] O[INSTANCE_BlockState] = true
|
|
|
|
INSTANCE_ItemStack = item_stack.createItem("minecraft:shield")
|
|
--[[ O[13] ]] O[INSTANCE_ItemStack] = true
|
|
|
|
INSTANCE_FiguraKeybind = keybind.newKey("[REPL] <INTERNAL USE>", "UNKNOWN")
|
|
--[[ O[14] ]] O[INSTANCE_FiguraKeybind] = true
|
|
|
|
INSTANCE_RegisteredKeybind = keybind.getRegisteredKeybind("key.jump")
|
|
--[[ O[15] ]] O[INSTANCE_RegisteredKeybind] = true
|
|
|
|
INSTANCE_Vector = vectors.of{1,2,3,4,5,6}
|
|
--[[ O[16] ]] O[INSTANCE_Vector] = true
|
|
|
|
setmetatable(REPL, REPLmt)
|
|
|
|
onCommand = function(cmd)
|
|
if REPL.bound then
|
|
local s, e = pcall(REPLmt.__call, nil, cmd)
|
|
if not s then
|
|
--Again, we have to assume the worst.
|
|
log(
|
|
string.format(
|
|
'{"text":"REPL: Critical REPL error!\n%s","color":"%s","italic":"false"}',
|
|
string.gsub(string.gsub(string.gsub(e, "\t", " "), "([\\\"])", "\\%1"), "§.", ""),
|
|
rtr.error
|
|
),
|
|
true
|
|
)
|
|
|
|
if not checkSMT() then
|
|
log('{"text":"\nThe string metatable has been tampered with!\nCore REPL functions cannot run without a valid string metatable!\nYou can use \\"$$#fixstringmt\\" to attempt to fix the issue.","color":"dark_red","italic":false}', true)
|
|
end
|
|
chat.setFiguraCommandPrefix("")
|
|
elseif e == "\0\9\0\70\79\82\67\69\0\9\0" then
|
|
error("FORCED AVATAR ERROR.\nRELOAD AVATAR TO REGAIN CONTROL.\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
function tick()
|
|
local REPLkeyIP = REPL.key.isPressed()
|
|
if REPLkeyIP and not REPL.keyWP then
|
|
if REPL.bound then
|
|
REPL.bound = false
|
|
chat.setFiguraCommandPrefix()
|
|
log(string.format('{"text":"REPL: Unbound from chat.","color":"%s","italic":false}', rtr.notice), true)
|
|
else
|
|
REPL.bound = true
|
|
chat.setFiguraCommandPrefix("")
|
|
log(string.format('{"text":"REPL: Bound to chat.","color":"%s","italic":false}', rtr.notice), true)
|
|
end
|
|
end
|
|
REPL.keyWP = REPLkeyIP
|
|
end
|
|
end
|
|
-- }}}
|
|
|