Skip to content

Commit

Permalink
scrapelib and dump utility
Browse files Browse the repository at this point in the history
  • Loading branch information
ferronn-dev committed Feb 4, 2024
1 parent 28047ce commit 034734a
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
2 changes: 2 additions & 0 deletions dump.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
local s = require('scrapelib')(arg[1]).Data
require('pl.pretty').dump(s)
133 changes: 133 additions & 0 deletions scrapelib.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
local sub = string.sub

local function ref(data, start, ...)
local x = start
for i = 1, select('#', ...) do
local ty = sub(x, 1, 1)
assert(ty == 't' or ty == 'f' or ty == 'u')
x = data[tonumber(sub(x, 2))][select(i, ...)]
end
return x
end

local function tpairs(data, x)
assert(type(x) == 'string')
local tx = sub(x, 1, 1)
assert(tx == 't' or tx == 'f' or tx == 'u')
return pairs(data[tonumber(sub(x, 2))])
end

local function resolve(data, top, depth)
depth = depth or math.huge
if top == nil then
return nil
end
local refs = {}
local function fun(x, lvl)
if lvl >= depth then
return x
end
assert(type(x) == 'string', tostring(x) .. ' is not a string')
local rx = refs[x]
if rx then
assert(type(rx) == 'table', 'unsupported loop in structure: ' .. x)
return rx
end
local tx = sub(x, 1, 1)
if tx == 'n' then
return tonumber(sub(x, 2))
elseif tx == 's' then
return sub(x, 2)
elseif tx == 'b' then
return x == 'btrue'
elseif tx == 'e' then
return '<function environment>'
elseif tx == 'm' then
return '<metatable>'
elseif tx == 'f' or tx == 'u' then
refs[x] = true
local ret = fun('t' .. sub(x, 2), lvl + 1)
refs[x] = ret
return ret
elseif tx == 't' then
refs[x] = true
local t = {}
for k, v in tpairs(data, x) do
t[fun(k, lvl + 1)] = fun(v, lvl + 1)
end
refs[x] = t
return t
else
error('invalid type on ' .. x)
end
end
return fun(top, 0)
end

local function names(data, rend)
local result = {}
local refs = {}
local stack = { { '_G', rend } }
while #stack > 0 do
local str, r = unpack(table.remove(stack))
refs[r] = true
for k, v in data:tpairs(r) do
local tk = sub(k, 1, 1)
local s = str
if tk == 'm' then
s = 'getmetatable(' .. s .. ')'
elseif tk == 'e' then
s = 'getfenv(' .. s .. ')'
elseif tk == 'n' or tk == 'b' then
s = s .. '[' .. sub(k, 2) .. ']'
elseif tk == 's' then
s = s .. '.' .. sub(k, 2)
elseif tk == 't' or tk == 'f' or tk == 'u' then
print('ignoring table key ' .. k)
else
error('invalid key ' .. k)
end
if v == rend then
table.insert(result, s)
elseif not refs[v] then
local tv = sub(v, 1, 1)
if tv == 't' or tv == 'u' or tv == 'f' then
table.insert(stack, { s, v })
end
end
end
end
return result
end

local function global(data, ...)
return ref(data, 't1', ...)
end

local function capsule(data, ...)
return global(data, 'sSimpleCheckout', 'sOnLoad', 'e', ...)
end

local dataMT = {
__index = {
capsule = capsule,
global = global,
names = names,
ref = ref,
resolve = resolve,
tpairs = tpairs,
},
__metatable = 'WowlessSaverData',
__newindex = function()
error('cannot modify a scrape table')
end,
}

return function(filename)
local fenv = {}
setfenv(loadfile(filename), fenv)()
local str = require('libdeflate'):DecompressDeflate(fenv.TheFlatDumper)
local ret = loadstring('return ' .. str)()
setmetatable(ret.Data, dataMT)
return ret
end

0 comments on commit 034734a

Please sign in to comment.