Update mechanism mostly done
This commit is contained in:
89
Launch.lua
89
Launch.lua
@@ -9,33 +9,17 @@ SetWindowTitle("PathOfBuilding")
|
||||
ConExecute("set vid_mode 1")
|
||||
ConExecute("set vid_resizable 3")
|
||||
|
||||
local opFile = io.open("Update/opFile.txt", "r")
|
||||
if opFile then
|
||||
-- Update is pending, apply it
|
||||
opFile:close()
|
||||
LoadModule("Update")
|
||||
end
|
||||
|
||||
local launch = { }
|
||||
SetMainObject(launch)
|
||||
|
||||
function launch:ApplyUpdate(mode)
|
||||
if mode == "basic" then
|
||||
-- Need to revert to the basic environment to apply the update
|
||||
os.execute("PathOfBuilding Update.lua")
|
||||
Exit()
|
||||
elseif mode == "normal" then
|
||||
-- Update can be applied while normal environment is running
|
||||
Restart()
|
||||
end
|
||||
end
|
||||
|
||||
function launch:OnInit()
|
||||
ConPrintf("Loading main script...")
|
||||
local mainFile = io.open("Modules/Main.lua")
|
||||
if mainFile then
|
||||
mainFile:close()
|
||||
else
|
||||
ConClear()
|
||||
ConPrintf("Please wait while we complete installation...\n")
|
||||
local updateMode = LoadModule("Update", "CHECK")
|
||||
if not updateMode or updateMode == "none" then
|
||||
Exit("Failed to install.")
|
||||
@@ -56,6 +40,7 @@ function launch:OnInit()
|
||||
self:ShowErrMsg("In 'Init': %s", errMsg)
|
||||
end
|
||||
end
|
||||
self:CheckForUpdate(true)
|
||||
end
|
||||
|
||||
function launch:OnExit()
|
||||
@@ -76,20 +61,24 @@ function launch:OnFrame()
|
||||
if self.promptMsg then
|
||||
local r, g, b = unpack(self.promptCol)
|
||||
self:DrawPopup(r, g, b, "^0%s", self.promptMsg)
|
||||
elseif self.updateChecking then
|
||||
self:DrawPopup(0, 0.5, 0, "^0%s", self.updateMsg)
|
||||
end
|
||||
if self.doReload then
|
||||
if self.doRestart then
|
||||
local screenW, screenH = GetScreenSize()
|
||||
SetDrawColor(0, 0, 0, 0.75)
|
||||
DrawImage(nil, 0, 0, screenW, screenH)
|
||||
SetDrawColor(1, 1, 1)
|
||||
DrawString(0, screenH/2, "CENTER", 24, "FIXED", "Reloading...")
|
||||
DrawString(0, screenH/2, "CENTER", 24, "FIXED", "Restarting...")
|
||||
Restart()
|
||||
end
|
||||
end
|
||||
|
||||
function launch:OnKeyDown(key, doubleClick)
|
||||
if key == "F5" then
|
||||
self.doReload = true
|
||||
self.doRestart = true
|
||||
elseif key == "u" and IsKeyDown("CTRL") then
|
||||
self:CheckForUpdate()
|
||||
elseif self.promptMsg then
|
||||
local errMsg, ret = PCall(self.promptFunc, key)
|
||||
if errMsg then
|
||||
@@ -97,7 +86,7 @@ function launch:OnKeyDown(key, doubleClick)
|
||||
elseif ret then
|
||||
self.promptMsg = nil
|
||||
end
|
||||
else
|
||||
elseif not self.updateChecking then
|
||||
if self.main and self.main.OnKeyDown then
|
||||
local errMsg = PCall(self.main.OnKeyDown, self.main, key, doubleClick)
|
||||
if errMsg then
|
||||
@@ -108,7 +97,7 @@ function launch:OnKeyDown(key, doubleClick)
|
||||
end
|
||||
|
||||
function launch:OnKeyUp(key)
|
||||
if not self.promptMsg then
|
||||
if not self.promptMsg and not self.updateChecking then
|
||||
if self.main and self.main.OnKeyUp then
|
||||
local errMsg = PCall(self.main.OnKeyUp, self.main, key)
|
||||
if errMsg then
|
||||
@@ -126,7 +115,7 @@ function launch:OnChar(key)
|
||||
elseif ret then
|
||||
self.promptMsg = nil
|
||||
end
|
||||
else
|
||||
elseif not self.updateChecking then
|
||||
if self.main and self.main.OnChar then
|
||||
local errMsg = PCall(self.main.OnChar, self.main, key)
|
||||
if errMsg then
|
||||
@@ -136,6 +125,52 @@ function launch:OnChar(key)
|
||||
end
|
||||
end
|
||||
|
||||
function launch:OnSubCall(func, ...)
|
||||
if func == "ConPrintf" then
|
||||
self.updateMsg = string.format(...)
|
||||
end
|
||||
if _G[func] then
|
||||
return _G[func](...)
|
||||
end
|
||||
end
|
||||
|
||||
function launch:OnSubFinished(ret)
|
||||
self.updateAvailable = ret
|
||||
if not ret then
|
||||
self:ShowPrompt(1, 0, 0, self.updateMsg .. "\n\nEnter/Escape to dismiss")
|
||||
elseif self.updateChecking then
|
||||
if ret == "none" then
|
||||
self:ShowPrompt(0, 0, 0, "No update available.", function(key) return true end)
|
||||
else
|
||||
self:ShowPrompt(0.2, 0.8, 0.2, "An update has been downloaded.\n\nClick 'Apply Update' at the top right when you are ready.", function(key) return true end)
|
||||
end
|
||||
self.updateChecking = false
|
||||
end
|
||||
end
|
||||
|
||||
function launch:ApplyUpdate(mode)
|
||||
if mode == "basic" then
|
||||
-- Need to revert to the basic environment to apply the update
|
||||
os.execute("start PathOfBuilding Update.lua")
|
||||
Exit()
|
||||
elseif mode == "normal" then
|
||||
-- Update can be applied while normal environment is running
|
||||
LoadModule("Update")
|
||||
Restart()
|
||||
self.doRestart = true -- Will show "Restarting" message if main window is showing
|
||||
end
|
||||
end
|
||||
|
||||
function launch:CheckForUpdate(inBackground)
|
||||
if not IsSubScriptRunning() then
|
||||
self.updateChecking = not inBackground
|
||||
self.updateMsg = ""
|
||||
local update = io.open("Update.lua", "r")
|
||||
LaunchSubScript(update:read("*a"), "MakeDir", "ConPrintf", "CHECK")
|
||||
update:close()
|
||||
end
|
||||
end
|
||||
|
||||
function launch:ShowPrompt(r, g, b, str, func)
|
||||
if self.promptMsg then
|
||||
return
|
||||
@@ -150,11 +185,7 @@ function launch:ShowPrompt(r, g, b, str, func)
|
||||
end
|
||||
|
||||
function launch:ShowErrMsg(fmt, ...)
|
||||
self:ShowPrompt(1, 0, 0, "^1Error:\n\n^0" .. string.format(fmt, ...) .. "\n\nEnter/Escape to Dismiss, F5 to reload scripts", function(key)
|
||||
if key == "RETURN" or key == "ESCAPE" then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
self:ShowPrompt(1, 0, 0, "^1Error:\n\n^0" .. string.format(fmt, ...) .. "\n\nEnter/Escape to Dismiss, F5 to reload scripts")
|
||||
end
|
||||
|
||||
function launch:DrawPopup(r, g, b, fmt, ...)
|
||||
|
||||
@@ -5,18 +5,40 @@
|
||||
-- Installation bootstrap
|
||||
--
|
||||
|
||||
local basicFiles = {
|
||||
["Launch.lua"] = "https://raw.githubusercontent.com/Openarl/PathOfBuilding/master/Launch.lua",
|
||||
["Update.lua"] = "https://raw.githubusercontent.com/Openarl/PathOfBuilding/master/Update.lua",
|
||||
}
|
||||
local basicFiles = { "Launch.lua", "Update.lua" }
|
||||
|
||||
local xml = require("xml")
|
||||
local curl = require("lcurl")
|
||||
for name, url in pairs(basicFiles) do
|
||||
|
||||
local localSource
|
||||
local localManXML = xml.LoadXMLFile("manifest.xml")
|
||||
if localManXML and localManXML[1].elem == "PoBVersion" then
|
||||
for _, node in ipairs(localManXML[1]) do
|
||||
if type(node) == "table" then
|
||||
if node.elem == "Source" then
|
||||
if node.attrib.part == "program" then
|
||||
localSource = node.attrib.url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not localSource then
|
||||
Exit("Install failed. (Missing or invalid manifest)")
|
||||
return
|
||||
end
|
||||
for _, name in pairs(basicFiles) do
|
||||
local outFile = io.open(name, "wb")
|
||||
local easy = curl.easy()
|
||||
easy:setopt_url(url)
|
||||
easy:setopt_url(localSource..name)
|
||||
easy:setopt_writefunction(outFile)
|
||||
easy:perform()
|
||||
local size = easy:getinfo(curl.INFO_SIZE_DOWNLOAD)
|
||||
easy:close()
|
||||
outFile:close()
|
||||
if size == 0 then
|
||||
Exit("Install failed. (Couldn't download program files)")
|
||||
return
|
||||
end
|
||||
end
|
||||
Restart()
|
||||
@@ -32,6 +32,11 @@ function main:Init()
|
||||
|
||||
self.tree = common.New("PassiveTree")
|
||||
|
||||
self.controls = { }
|
||||
self.controls.applyUpdate = common.New("ButtonControl", 0, 4, 100, 20, "^x50E050Apply Update", function()
|
||||
launch:ApplyUpdate(launch.updateAvailable)
|
||||
end)
|
||||
|
||||
self.inputEvents = { }
|
||||
self.tooltipLines = { }
|
||||
|
||||
@@ -59,10 +64,17 @@ function main:OnFrame()
|
||||
self.modeArgs = self.newModeArgs
|
||||
self.newMode = nil
|
||||
self:CallMode("Init", unpack(self.modeArgs))
|
||||
end
|
||||
end
|
||||
|
||||
self.controls.applyUpdate.x = self.screenW - 104
|
||||
self.controls.applyUpdate.hidden = not launch.updateAvailable or launch.updateAvailable == "none"
|
||||
|
||||
common.controlsInput(self, self.inputEvents)
|
||||
|
||||
self:CallMode("OnFrame", self.inputEvents)
|
||||
|
||||
common.controlsDraw(self)
|
||||
|
||||
wipeTable(self.inputEvents)
|
||||
end
|
||||
|
||||
|
||||
54
Update.lua
54
Update.lua
@@ -12,16 +12,34 @@ local function downloadFile(curl, url, outName)
|
||||
easy:setopt_url(url)
|
||||
easy:setopt_writefunction(outFile)
|
||||
easy:perform()
|
||||
local code = easy:getinfo(curl.INFO_RESPONSE_CODE)
|
||||
local size = easy:getinfo(curl.INFO_SIZE_DOWNLOAD)
|
||||
easy:close()
|
||||
outFile:close()
|
||||
if code ~= 200 then
|
||||
ConPrintf("Download failed (code %d)", code)
|
||||
if size == 0 then
|
||||
ConPrintf("Download failed")
|
||||
os.remove(outName)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function downloadFileText(curl, url)
|
||||
local text = ""
|
||||
local easy = curl.easy()
|
||||
easy:setopt_url(url)
|
||||
easy:setopt_writefunction(function(data)
|
||||
text = text..data
|
||||
return true
|
||||
end)
|
||||
easy:perform()
|
||||
local size = easy:getinfo(curl.INFO_SIZE_DOWNLOAD)
|
||||
easy:close()
|
||||
if size == 0 then
|
||||
ConPrintf("Download failed")
|
||||
return nil
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
if mode == "CHECK" then
|
||||
ConPrintf("Checking for update...")
|
||||
|
||||
@@ -53,23 +71,19 @@ if mode == "CHECK" then
|
||||
end
|
||||
end
|
||||
if not localVer or not localSource or not next(localFiles) then
|
||||
ConPrintf("Update failed: invalid local manifest")
|
||||
ConPrintf("Update check failed: invalid local manifest")
|
||||
return
|
||||
end
|
||||
|
||||
-- Download and process remote manifest
|
||||
local remoteVer
|
||||
local remoteFiles = { }
|
||||
local remoteManText = ""
|
||||
local remoteSources = { }
|
||||
local easy = curl.easy()
|
||||
easy:setopt_url(localSource.."manifest.xml")
|
||||
easy:setopt_writefunction(function(data)
|
||||
remoteManText = remoteManText..data
|
||||
return true
|
||||
end)
|
||||
easy:perform()
|
||||
easy:close()
|
||||
local remoteManText = downloadFileText(curl, localSource.."manifest.xml")
|
||||
if not remoteManText then
|
||||
ConPrintf("Update check failed: couldn't download version manifest")
|
||||
return
|
||||
end
|
||||
local remoteManXML = xml.ParseXML(remoteManText)
|
||||
if remoteManXML and remoteManXML[1].elem == "PoBVersion" then
|
||||
for _, node in ipairs(remoteManXML[1]) do
|
||||
@@ -90,7 +104,7 @@ if mode == "CHECK" then
|
||||
end
|
||||
end
|
||||
if not remoteVer or not next(remoteSources) or not next(remoteFiles) then
|
||||
ConPrintf("Update failed: invalid remote manifest")
|
||||
ConPrintf("Update check failed: invalid remote manifest")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -154,7 +168,7 @@ if mode == "CHECK" then
|
||||
local file = io.open(fileName, "wb")
|
||||
file:write(zippedFile:Read("*a"))
|
||||
file:close()
|
||||
zippedFile:close()
|
||||
zippedFile:Close()
|
||||
else
|
||||
ConPrintf("Couldn't extract '%s' from '%s' (extract failed)", data.name, zipName)
|
||||
failedFile = true
|
||||
@@ -175,10 +189,10 @@ if mode == "CHECK" then
|
||||
end
|
||||
for name, zip in pairs(zipFiles) do
|
||||
zip:Close()
|
||||
os.remove(name)
|
||||
os.remove("Update/"..name)
|
||||
end
|
||||
if failedFile then
|
||||
ConPrintf("Update failed: failed to get all required files")
|
||||
ConPrintf("Update failed: one or more files couldn't be downloaded")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -229,6 +243,7 @@ if mode == "CHECK" then
|
||||
opFile:write(table.concat(ops, "\n"))
|
||||
opFile:close()
|
||||
|
||||
ConPrintf("Update is ready.")
|
||||
return coreUpdate and "basic" or "normal"
|
||||
end
|
||||
|
||||
@@ -239,7 +254,7 @@ if not opFile then
|
||||
end
|
||||
local launch = false
|
||||
for line in opFile:lines() do
|
||||
local op, args = line:match("(%a+) ?(.+)")
|
||||
local op, args = line:match("(%a+) ?(.*)")
|
||||
if op == "wait" then
|
||||
local name = args:match('"(.*)"')
|
||||
local file
|
||||
@@ -268,6 +283,5 @@ end
|
||||
opFile:close()
|
||||
os.remove("Update/opFile.txt")
|
||||
if launch then
|
||||
os.execute("PathOfBuilding")
|
||||
os.execute("start PathOfBuilding")
|
||||
end
|
||||
|
||||
|
||||
12
manifest.xml
12
manifest.xml
@@ -2,9 +2,9 @@
|
||||
<PoBVersion>
|
||||
<Version number="0.1.0"/>
|
||||
<Source part="program" url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/master/"/>
|
||||
<Source url="" part="runtime" platform="win32"/>
|
||||
<File sha1="420991b8e4453455cf5e4276ae137c15f837f3e6" name="Launch.lua" part="program"/>
|
||||
<File sha1="a7efc40e8e5338d0f0c01d1e57987e502403d73f" name="Update.lua" part="program"/>
|
||||
<Source url="file://localhost/E:/Documents/Path%20of%20Exile/Calcs/win32.zip" part="runtime" platform="win32"/>
|
||||
<File sha1="ab26bd775bea9fe99389bf501a81595e4d032d35" name="Launch.lua" part="program"/>
|
||||
<File sha1="f84b71bf8b9d610caed2517b6b7ce5fde352c354" name="Update.lua" part="program"/>
|
||||
<File sha1="434890f159cb67a73b0489e07471a101582e7168" name="Classes/ButtonControl.lua" part="program"/>
|
||||
<File sha1="991b3deecb4ae60eee54e5b81d4e10a67da80dc7" name="Classes/DropDownControl.lua" part="program"/>
|
||||
<File sha1="1571a47a5549a9ae38407b88012fda39f7ad1ce0" name="Classes/EditControl.lua" part="program"/>
|
||||
@@ -22,7 +22,7 @@
|
||||
<File sha1="708ee4686c95b00d78823e1872c47a13123f7d06" name="Modules/Data.lua" part="program"/>
|
||||
<File sha1="f936142ba367e7cc895663fc7f0c45f315572e40" name="Modules/Items.lua" part="program"/>
|
||||
<File sha1="44febf05f971e01fd9999f420822e3c09b8b2662" name="Modules/ItemTools.lua" part="program"/>
|
||||
<File sha1="e5d901a2f491d8f8977f35573111bb832f839434" name="Modules/Main.lua" part="program"/>
|
||||
<File sha1="0f1d852e26b0e066703c728b68bf90bc45c28f9a" name="Modules/Main.lua" part="program"/>
|
||||
<File sha1="9a2e8a8ce4b31c9402ef1f7bd861f2bd76b11328" name="Modules/ModParser.lua" part="program"/>
|
||||
<File sha1="f7969bfa98360e358166e42bbfd9062ac0c9445f" name="Modules/ModTools.lua" part="program"/>
|
||||
<File sha1="284687ef19bb15b9a49017667730ec49aa63fd9d" name="Items/axe.lua" part="program"/>
|
||||
@@ -49,10 +49,10 @@
|
||||
<File sha1="e7ee7e5b6388facb7bf568517ecc401590757df7" name="Assets/ring.png" part="program"/>
|
||||
<File platform="win32" sha1="f545caeb86d355698eaff4d665b3af7f17154fb9" name="PathOfBuilding.exe" part="runtime"/>
|
||||
<File platform="win32" sha1="914d42ca1836c5152a5f60aad23020a86bcb46d9" name="lua51.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="02a3faa603efa313e17397257be29de0762b2779" name="SimpleGraphic.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="235050cc51a8daddd8bbf941864c583ee9c55295" name="SimpleGraphic.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="887fd08cb3c2989a9d88adc9717d3ec00ab97462" name="libcurl.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="607918daf9cbaecee0090e9cec8d0e221338678e" name="lcurl.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="abd8665bff90094fea7d9f116f2a084430410d94" name="lzip.dll" part="runtime"/>
|
||||
<File platform="win32" sha1="f0c0f74958f742ac89bc83a6cccac1eb2ab15cde" name="lzip.dll" part="runtime"/>
|
||||
<File sha1="74cc6c47e7cda18211e57b9e062368eab3c26bab" name="DLSG/Fonts/Bitstream Vera Sans Mono.10.tga" part="runtime"/>
|
||||
<File sha1="1977206f0efc5035834ecbf93ca7d046010d8aab" name="DLSG/Fonts/Bitstream Vera Sans Mono.12.tga" part="runtime"/>
|
||||
<File sha1="93a4309dc814914be7d2dee708e3821494f145a2" name="DLSG/Fonts/Bitstream Vera Sans Mono.14.tga" part="runtime"/>
|
||||
|
||||
Reference in New Issue
Block a user