Created
January 3, 2014 17:56
-
-
Save warmist/8242853 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--installs a modpack | |
-- args: modpack_name [-i|install|-if] [-u|uninstall] [entity_to_patch] | |
args={...} | |
if args[1]==nil or #args<2 then | |
print("Usage: modpack_name [-i|install|-if] [-u|uninstall] [entity_to_patch]") | |
end | |
local modPath=dfhack.getDFPath()..'/mods/'..args[1]..'/' | |
local dfMod=dofile(modPath..'init.lua') | |
local name=dfMod.name | |
local guard={">>"..name.." patch","<<End "..name.." patch"} | |
local guard_init={"--"..guard[1],"--"..guard[2]} | |
local entity_file=dfhack.getDFPath().."/raw/objects/entity_default.txt" | |
local init_file=dfhack.getDFPath().."/raw/init.lua" | |
function fileExists(filename) | |
local file=io.open(filename,"rb") | |
if file==nil then | |
return | |
else | |
file:close() | |
end | |
end | |
function copyFile(from,to) --oh so primitive | |
local filefrom=io.open(from,"rb") | |
local fileto=io.open(to,"w+b") | |
local buf=filefrom:read("*a") | |
printall(buf) | |
fileto:write(buf) | |
filefrom:close() | |
fileto:close() | |
end | |
function patchInit(initFileName,patch_guard,code) | |
local initFile=io.open(initFileName,"a") | |
initFile:write(string.format("%s\n%s\n%s",patch_guard[1], | |
code,patch_guard[2])) | |
initFile:close() | |
end | |
function patchEntity(file_name,patch_guard,entity_name,code) | |
local input_lines=patch_guard[1].."\n"..code.."\n"..patch_guard[2] | |
local badchars="[%:%[%]]" | |
local find_string=entity_name:gsub(badchars,"%%%1") --escape some bad chars | |
local entityFile=io.open(file_name,"r") | |
local buf=entityFile:read("*all") | |
entityFile:close() | |
local entityFile=io.open(file_name,"w+") | |
print("Patching:"..entity_name) | |
buf=string.gsub(buf,find_string,entity_name.."\n"..input_lines) | |
entityFile:write(buf) | |
entityFile:close() | |
end | |
function findGuards(str,start,patch_guard) | |
local pStart=string.find(str,patch_guard[1],start) | |
if pStart==nil then return nil end | |
local pEnd=string.find(str,patch_guard[2],pStart) | |
if pEnd==nil then error("Start guard token found, but end was not found") end | |
return pStart-1,pEnd+#patch_guard[2]+1 | |
end | |
function findGuardsFile(filename,patch_guard) | |
local file=io.open(filename,"r") | |
local buf=file:read("*all") | |
return findGuards(buf,1,patch_guard) | |
end | |
function unPatchFile(filename,patch_guard) | |
local file=io.open(filename,"r") | |
local buf=file:read("*all") | |
file:close() | |
local newBuf="" | |
local pos=1 | |
local lastPos=1 | |
repeat | |
local endPos | |
pos,endPos=findGuards(buf,lastPos,patch_guard) | |
newBuf=newBuf..string.sub(buf,lastPos,pos) | |
if endPos~=nil then | |
lastPos=endPos | |
end | |
until pos==nil | |
local file=io.open(filename,"w+") | |
file:write(newBuf) | |
file:close() | |
end | |
function checkInstalled() --try to figure out if installed | |
if dfMod.checkInstalled then | |
return dfMod.checkInstalled() | |
else | |
if dfMod.raws_list then | |
for k,v in pairs(dfMod.raws_list) do | |
if fileExists(dfhack.getDFPath().."/raw/objects/"..v) then | |
return true | |
end | |
end | |
end | |
if dfMod.patch_entity then | |
if findGuardsFile(entity_file,guard)~=nil then | |
return true | |
end | |
end | |
if dfMod.patch_init then | |
if findGuardsFile(init_file,guard_init)~=nil then | |
return true | |
end | |
end | |
end | |
end | |
if args[2]=="install" or args[2]=="-i" or args[2]=="-if" then | |
if args[2]~='-if' and checkInstalled() then | |
qerror("Mod already installed.") | |
return | |
end | |
if dfMod.pre_install then | |
dfMod.pre_install(args) | |
end | |
if dfMod.raws_list then | |
for k,v in pairs(dfMod.raws_list) do | |
copyFile(modPath..v,dfhack.getDFPath().."/raw/objects/"..v) | |
end | |
end | |
if dfMod.patch_entity then | |
local entity_target | |
if args[3]==nil then | |
entity_target="[ENTITY:MOUNTAIN]" | |
else | |
entity_target="[ENTITY:"..args[3].."]" -- todo multiple entities | |
end | |
patchEntity(entity_file,guard,entity_target,dfMod.patch_entity) | |
end | |
if dfMod.patch_init then | |
patchInit(init_file,guard_init,dfMod.patch_init) | |
end | |
if dfMod.post_install then | |
dfMod.post_install(args) | |
end | |
return | |
elseif args[2]=="uninstall" or args[2]=="-u" then | |
if dfMod.pre_uninstall then | |
dfMod.pre_uninstall(args) | |
end | |
if dfMod.raws_list then | |
for k,v in pairs(dfMod.raws_list) do | |
os.remove(dfhack.getDFPath().."/raw/objects/"..v) | |
end | |
end | |
if dfMod.patch_entity then | |
unPatchFile(entity_file,guard) | |
end | |
if dfMod.patch_init then | |
unPatchFile(init_file,guard_init) | |
end | |
if dfMod.post_uninstall then | |
dfMod.post_uninstall(args) | |
end | |
return | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment