Crimsonland Pak Format Again
Have been spending a little bit of time playing with Lua and an early project was to rewrite the Python script for reading a Crimsonland Pak file. So far I’m enjoying Lua and its language design, even with the very limited standard libraries.
clpak.lua
BinaryFile = {}
BinaryFile.new = function(file)
return setmetatable({file=file}, {__index=BinaryFile})
end
BinaryFile.readint32 = function(self)
local data = self.file:read(4)
return (data:byte(4) * (256^3)) +
(data:byte(3) * (256^2)) +
(data:byte(2) * (256^1)) +
(data:byte(1) * (256^0))
end
BinaryFile.readnulstring = function(self)
local buf = ''
while true do
local ch = self.file:read(1)
if ch:byte() == 0 then break end
buf = buf .. ch
end
return buf
end
BinaryFile.read = function(self, ...)
return self.file:read(...)
end
BinaryFile.skip = BinaryFile.read
BinaryFile.seek = function(self, ...)
return self.file:seek(...)
end
local readindex = function(filename)
local f = io.open(filename, 'rb')
local bf = BinaryFile.new(f)
-- Header
assert(bf:readnulstring() == 'PAK')
assert(bf:readnulstring() == 'V11')
-- index offsets
local indexstartoffset = bf:readint32()
local indexendoffset = bf:readint32()
-- just to index
bf:seek('set', indexstartoffset)
-- number of entries
local indexsize = bf:readint32()
local index = {}
for i=1, indexsize do
table.insert(index, {
name = bf:readnulstring(),
offset = bf:readint32(),
length = bf:readint32()
})
-- Unknown (junk?)
bf:skip(8)
end
f:close()
return index
end
local index = readindex('D:\\Steam\\steamapps\\common\\Crimsonland\\data.pak')
for _,v in ipairs(index) do
print(string.format('name:%s offset:%d length:%d', v.name, v.offset, v.length))
end