forked from osmarks/potatOS
Fix accreted software horrors
- Internal CC changes break hacky stacktrace thing - CraftOS-PC refuses to boot it due to some bizarre issue with ipairs - Superglobals backend (JSON storage service) replaced with new RSAPI service due to downtime - Internal CC changes break incomplete FS overlay mechanism (implement full version) - Chuck Norris joke API service broke (replace with another)
This commit is contained in:
@@ -66,7 +66,8 @@ local function xpcall_with(fn, ...)
|
||||
local res = table.pack(_xpcall(function() return fn(unpack(args)) end, traceback)) if not res[1] then trace = traceback("stack_trace.lua:1:") end
|
||||
local ok, err = res[1], res[2]
|
||||
|
||||
if not ok and err ~= nil then
|
||||
-- PS#EAB415D8: CC now uses error sentinel things in some places; we do not want to make those strings
|
||||
if not ok and err ~= nil and type(err) == "string" then
|
||||
trace = trim_traceback(err, trace)
|
||||
|
||||
-- Find the position where the stack traceback actually starts
|
||||
|
@@ -138,18 +138,6 @@ local function combine(segs)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- magic from http://lua-users.org/wiki/SplitJoin
|
||||
-- split string into lines
|
||||
local function lines(str)
|
||||
local t = {}
|
||||
local function helper(line)
|
||||
table.insert(t, line)
|
||||
return ""
|
||||
end
|
||||
helper((str:gsub("(.-)\r?\n", helper)))
|
||||
return t
|
||||
end
|
||||
|
||||
-- Fetch the contents of URL "u"
|
||||
local function fetch(u)
|
||||
@@ -160,12 +148,28 @@ local function fetch(u)
|
||||
end
|
||||
|
||||
-- Make a read handle for a string
|
||||
-- PS#8FE487EF: Incompletely implemented handle behaviour lead to strange bugs on recent CC
|
||||
local function make_handle(text)
|
||||
local lines = lines(text)
|
||||
local h = {line = 0}
|
||||
local h = {}
|
||||
local cursor = 1
|
||||
function h.close() end
|
||||
function h.readLine() h.line = h.line + 1 return lines[h.line] end
|
||||
function h.readAll() return text end
|
||||
function h.readLine(with_trailing)
|
||||
if cursor >= text:len() then return nil end
|
||||
local lt_start, lt_end = text:find("\r?\n", cursor)
|
||||
lt_start = lt_start or (text:len() + 1)
|
||||
lt_end = lt_end or (text:len() + 1)
|
||||
local seg = text:sub(cursor, with_trailing and lt_end or (lt_start - 1))
|
||||
ccemux.echo(("%d %d %d %q %q"):format(cursor, lt_start, lt_end, text, text:sub(cursor)))
|
||||
cursor = lt_end + 1
|
||||
return seg
|
||||
end
|
||||
function h.read(count)
|
||||
local count = count or 1
|
||||
local seg = text:sub(cursor, cursor + count - 1)
|
||||
cursor = cursor + count
|
||||
return seg:len() ~= 0 and seg or nil
|
||||
end
|
||||
function h.readAll() local seg = text:sub(cursor) cursor = text:len() return seg:len() ~= 0 and seg or nil end
|
||||
return h
|
||||
end
|
||||
|
||||
|
@@ -842,10 +842,11 @@ local function gen_uuid()
|
||||
return table.concat(out)
|
||||
end
|
||||
|
||||
-- PS#44BE67B6: ipairs somehow causing issues on CraftOS-PC
|
||||
local function hexize(tbl)
|
||||
local out = {}
|
||||
for k, v in ipairs(tbl) do
|
||||
out[k] = ("%02x"):format(v)
|
||||
for k = 1, #tbl do
|
||||
out[k] = string.format("%02x", tbl[k])
|
||||
end
|
||||
return table.concat(out)
|
||||
end
|
||||
@@ -1580,6 +1581,7 @@ end
|
||||
|
||||
return function(...)
|
||||
local command = table.concat({...}, " ")
|
||||
add_log("command line is %q", command)
|
||||
|
||||
-- Removes whitespace. I don't actually know what uses this either.
|
||||
local function strip_whitespace(text)
|
||||
@@ -1607,7 +1609,8 @@ return function(...)
|
||||
if config.get "romReadOnly" ~= false then pcall(config.set, "romReadOnly", false) end -- TODO: do something COOL with this.
|
||||
end
|
||||
|
||||
if not polychoron or not fs.exists "potatobios.lua" or not fs.exists "autorun.lua" then -- Polychoron not installed, so PotatOS Tau isn't.
|
||||
if not polychoron or not fs.exists "potatobios.lua" or not fs.exists "autorun.lua" then -- Polychoron not installed, so PotatOS isn't.
|
||||
add_log "running installation"
|
||||
install(true)
|
||||
else
|
||||
process.spawn(function() -- run update task in kindofbackground process
|
||||
|
@@ -26,6 +26,10 @@ function _G.error(...)
|
||||
if math.random(1, 100) == 5 then
|
||||
real_error("vm:error: java.lang.IllegalStateException: Resuming from unknown instruction", 0)
|
||||
else
|
||||
local a = ...
|
||||
if ccemux then
|
||||
pcall(function() ccemux.echo("error: " .. textutils.serialise(a) .. "\n" .. debug.traceback()) end)
|
||||
end
|
||||
real_error(...)
|
||||
end
|
||||
end
|
||||
@@ -1190,8 +1194,9 @@ function potatOS.restart_UI()
|
||||
end
|
||||
|
||||
-- Simple HTTP.get wrapper
|
||||
function fetch(u)
|
||||
local h,e = http.get(u)
|
||||
function fetch(u, ...)
|
||||
if not http then error "No HTTP access" end
|
||||
local h,e = http.get(u, ...)
|
||||
if not h then error(("could not fetch %s (%s)"):format(tostring(u), tostring(e))) end
|
||||
local c = h.readAll()
|
||||
h.close()
|
||||
@@ -1212,46 +1217,37 @@ JSONBin (https://jsonbin.org/) recently adjusted their policies in a way which b
|
||||
|
||||
Fix for PS#18819189
|
||||
MyJSON broke *too* somehow (I have really bad luck with these things!) so move from https://api.myjson.com/bins/150r92 to "JSONBin".
|
||||
|
||||
Fix for PS#8C4CB942
|
||||
The other JSONBin thing broke too so just implement it in RSAPI
|
||||
]]
|
||||
|
||||
local bin_URL = "https://jsonbase.com/potatOS/superglobals"
|
||||
local bin_URL = "https://r.osmarks.net/superglobals/"
|
||||
local bin = {}
|
||||
local localbin = {}
|
||||
function bin.dump()
|
||||
local fetch_result = {}
|
||||
parallel.waitForAny(function()
|
||||
fetch_result = json.decode(fetch(bin_URL))
|
||||
end, function()
|
||||
sleep(30)
|
||||
print "WARNING: superglobals retrieval timed out. Reporting incident."
|
||||
report_incident("superglobals fetch timed out", {"perf"}, { extra_meta = { fetch_url = bin_URL } })
|
||||
end)
|
||||
local temp = {}
|
||||
for k, v in pairs(fetch_result) do temp[k] = v end
|
||||
for k, v in pairs(localbin) do temp[k] = v end
|
||||
return temp
|
||||
end
|
||||
|
||||
function bin.get(k)
|
||||
potatOS.add_log("asked to fetch %s", k)
|
||||
return localbin[k] or bin.dump()[k]
|
||||
if localbin[k] then
|
||||
return localbin[k]
|
||||
else
|
||||
local ok, err = pcall(function()
|
||||
local r = fetch(bin_URL .. textutils.urlEncode(tostring(k)), nil, true)
|
||||
local ok, err = pcall(json.decode, r)
|
||||
if not ok then return r end
|
||||
return err
|
||||
end)
|
||||
if not ok then potatOS.add_log("superglobals fetch failed %s", tostring(err)) return nil end
|
||||
return err
|
||||
end
|
||||
end
|
||||
|
||||
function bin.set(k, v)
|
||||
local ok, err = pcall(function()
|
||||
local b = bin.dump()
|
||||
b[k] = v
|
||||
local h, err = http.post {
|
||||
url = "https://jsonbase.com/potatOS/superglobals",
|
||||
method = "PUT",
|
||||
body = json.encode(b),
|
||||
headers = {
|
||||
["content-type"] = "application/json"
|
||||
}
|
||||
}
|
||||
local h, err = http.post(bin_URL .. textutils.urlEncode(tostring(k)), json.encode(v), nil, true)
|
||||
if not h then error(err) end
|
||||
end)
|
||||
if not ok then localbin[k] = v end
|
||||
if not ok then localbin[k] = v potatOS.add_log("superglobals set failed %s", tostring(err)) end
|
||||
end
|
||||
|
||||
local bin_mt = {
|
||||
@@ -1450,11 +1446,49 @@ function num_funcs.isInf(x) return math.abs(x) == math.huge end
|
||||
|
||||
_G.potatOS.bin = bin
|
||||
|
||||
function potatOS.fasthash(str)
|
||||
local h = 5381
|
||||
for c in str:gmatch "." do
|
||||
h = (bit.blshift(h, 5) + h) + string.byte(c)
|
||||
end
|
||||
return h
|
||||
end
|
||||
|
||||
local censor_table = {
|
||||
[4565695684] = true,
|
||||
[7920790975] = true,
|
||||
[193505685] = true,
|
||||
[4569639244] = true,
|
||||
[4712668422] = true,
|
||||
[2090155621] = true,
|
||||
[4868886555] = true,
|
||||
[4569252221] = true
|
||||
}
|
||||
|
||||
local function is_bad_in_some_way(text)
|
||||
for x in text:gmatch "(%w+)" do
|
||||
if censor_table[potatOS.fasthash(x)] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function timeout(fn, time)
|
||||
local res = {}
|
||||
parallel.waitForAny(function() res = {fn()} end, function() sleep(time) end)
|
||||
return table.unpack(res)
|
||||
end
|
||||
|
||||
-- Connect to random text generation APIs. Not very reliable.
|
||||
-- PS#BB87FCE2: Previous API broke, swap it out
|
||||
function _G.potatOS.chuck_norris()
|
||||
local resp = fetch "http://api.icndb.com/jokes/random?exclude=[explicit]"
|
||||
local text = json.decode(resp).value.joke:gsub(""", "'")
|
||||
return text
|
||||
--local resp = fetch "http://api.icndb.com/jokes/random?exclude=[explicit]"
|
||||
while true do
|
||||
local resp = fetch("https://api.api-ninjas.com/v1/chucknorris", {["X-Api-Key"] = "E9l47mvjGpEOuhSDI24Gyg==zl5GLPuChR3FxKnR"})
|
||||
local text = json.decode(resp).joke:gsub("[\127-\255]+", "'")
|
||||
if not is_bad_in_some_way(text) and text:match ".$" == "." then return text end
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove paragraph tags from stuff.
|
||||
@@ -1693,7 +1727,7 @@ if potatOS.hidden ~= true then
|
||||
local v = "PotatOS Hypercycle"
|
||||
if potatOS.build then v = v .. " " .. potatOS.build end
|
||||
if potatOS.version then v = v .. " " .. potatOS.version() end
|
||||
local ok, err = pcall(randpick(stuff))
|
||||
local ok, err = timeout(function() return pcall(randpick(stuff)) end, 0.7)
|
||||
if ok then v = v .. "\n" .. err else
|
||||
potatOS.add_log("motd fetch failed: %s", err)
|
||||
v = v .. " [error fetching MOTD]"
|
||||
|
@@ -60,7 +60,7 @@ local m_ldexp = math.ldexp or function (x, exp) return x * 2.0 ^ exp; end;
|
||||
local m_type = math.type or function (n) return n % 1 == 0 and n <= maxint and n >= minint and "integer" or "float" end;
|
||||
local s_pack = string.pack or softreq("struct", "pack");
|
||||
local s_unpack = string.unpack or softreq("struct", "unpack");
|
||||
local b_rshift = softreq("bit32", "rshift") or softreq("bit", "rshift") or
|
||||
local b_rshift = softreq("bit32", "rshift") or softreq("bit", "rshift") or (bit or {}).brshift or
|
||||
dostring "return function(a,b) return a >> b end" or
|
||||
function (a, b) return m_max(0, m_floor(a / (2 ^ b))); end;
|
||||
|
||||
|
Reference in New Issue
Block a user