Allows support for uninstalling than installing mudlet xml packages and .mpackage data packages.
This does not require that you compress your project into one mpackage. It supports downloading multiple xml files through github. Including images and other resources in .mpackages.
However it does not support an .mpackage with multiple packages within it. .mpackages can only contain data, like images.
Usage:
There are two attachments intended as examples.
in function `GitUpdateconfig()` there is a section labeled `--edit below this line-` and `--edit above this line` Configurations there need to be filled out.
Running the update:
If you do not provide need to provide an option for player to update.
set `GitUpdate.repairInstall` to `true`. Call `GitUpdateconfig()` from what method you prefer, alias, event or any other method.
Providing an option for player to update.
call `DownloadGitReleaseJSON()` from an alias, cecholink, repeating temp timer or any other method. The git updater will check if the string in GitUpdate.localVersion matches the most recent tag in your github release. If it does not it will prompt the player to run an update via an alias. You can set the alias name in `GitUpdateconfig()` though it does require you make an alias. If you want to provide an option for the player to update via command. If not you could set `GitUpdate.aliasName = "click here"` As it will provide a cecholink for the player to click. If you do make an aliase all it needs to do is call `DownloadGitScripts()`. After that the update will process.
It requires a github site. A working example of a project that uses this can be found at: https://github.com/TheEternalCitizens/m ... ntegration
With each new release the player will receive an message to update, or could automatically update. If the player has the `GitUpdate.betaTester` set to true, they will receive an update notice for pre releases also. Currently this only allows for running the latest release or prerelease of a project.
Example of a working configuration. Also may be a decent reference for a github page.
Code: Select all
--API URL for git hub for project
GitUpdate.gitReleaseURL = [[https://api.github.com/repos/TheEternalCitizens/mudlet-integration/releases]]
GitUpdate.localRespitory = getMudletHomeDir().."/settings/" --local directory for source files
if not io.exists(GitUpdate.localRespitory) then --if folder does not exists
lfs.mkdir(GitUpdate.localRespitory) --create the folder
debugToDisplay("Update: ERROR localRespitory was not present. Has been created.")
end --if GitUpdate.localRespitory not exist
GitUpdate.gitReleaseURLJSONFile = "ParthiaLatest.json" --local file name REST API latest JSON
GitUpdate.localVersion = "0.1.21" --Must match the tag in your github release
GitUpdate.aliasName = "tecclient update" --Name of alias user runs to process update
--Name of the alias to check if an update is available.
GitUpdate.updateCheckAlias = "tecclient update check"
--The full name or a word in the file that this update script is in.
GitUpdate.updateFileNameReference = "Scripts"
--notify update engine if player is a beta tester. If the player is a beta
--tester they will receive update notices for pre-releases for your project
GitUpdate.betaTester = tecSettings.betaTester
--packages that are no longer used in the project and should be removed.
--They can not share a name with a package that you need. Otherwise this will uninstall it.
GitUpdate.removePackages = {"TECClientScripts", "TECClientTriggers",
"TECClientAliases", "TECClientKeyBindings"}
GitUpdate.removeModules = {} --modules that are no longer used in the project and should be removed.
--Used to tell player correct installation method if they installed scripts as modules
GitUpdate.installationURL = "https://github.com/TheEternalCitizens/mudlet-integration/wiki/Installation"
--use in a repair aliase, set this variable to true if a repair install
--is needed.
GitUpdate.repairInstall = fuzzyBoolean(GitUpdate.repairInstall)
--cecho compatible color, it will hightlight cecholinks in the update process
GitUpdate.cmdHighlight = "blue"
You could also download and install the attached `Git Update Alias.xml` and import it. That does have preconfigured settings in it. The code below does not.
Code: Select all
--Installs updates from github.
--Intended for projects that do not support downloading over telnet
--To allow error checking package file names must contain package type starting with a capitol
--IE: "My Project Name Scripts.xml" or "MyPackageNameTriggers.xml".
--start of section dedicated for functions used by update process.
--To understand the flow of updates you will need to scroll past these.
--There will be a comment stating when update flow starts.
-- fuzzyBoolean Provided by demonnic
-- Expands boolean definitions to be more flexible.
-- True values are "true", "yes", "0", 0, and true
-- False values are "false", "no", "1", 1, false, and nil
-- @param bool item to test for truthiness
if not fuzzyBoolean then
function fuzzyBoolean(bool)
if type(bool) == "boolean" or bool == nil then
return bool
elseif tostring(bool) then
local truth = {
"yes",
"true",
"0"
}
local untruth = {
"no",
"false",
"1"
}
local boolstr = tostring(bool)
if table.contains(truth, boolstr) then
return true
elseif table.contains(untruth, boolstr) then
return false
else
return nil
end
else
return nil
end
end
end --if not fuzzyBoolean
function GitUpdateconfig() --Create variables used for updates
if GitUpdate then
--if events were previously created, kill them.
if GitUpdate.downloadDoneID then
killAnonymousEventHandler(GitUpdate.downloadDoneID)
end --if GitUpdate.downloadDoneID
if GitUpdate.downloadErrorID then
killAnonymousEventHandler(GitUpdate.downloadErrorID)
end --if GitUpdate.downloadErrorID
if GitUpdate.installPackageID then
killAnonymousEventHandler(GitUpdate.installPackageID)
end --if GitUpdate.installPackageID
if GitUpdate.uninstallPackageID then
killAnonymousEventHandler(GitUpdate.uninstallPackageID)
end --if GitUpdate.downloadDoneID
end --if GitUpdate
GitUpdate = GitUpdate or {} --table to hold project variables
--Edit below this line---------------------
--API URL for git hub for project
GitUpdate.gitReleaseURL = [[https://api.github.com/repos/yourproject/releases]]
GitUpdate.localRespitory = getMudletHomeDir().."/settings/" --local directory for source files
if not io.exists(GitUpdate.localRespitory) then --if folder does not exists
lfs.mkdir(GitUpdate.localRespitory) --create the folder
debugToDisplay("Update: ERROR localRespitory was not present. Has been created.")
end --if GitUpdate.localRespitory not exist
GitUpdate.gitReleaseURLJSONFile = "Project.json" --local file name REST API latest JSON
GitUpdate.localVersion = "github tag here" --Must match the tag in your github release
GitUpdate.aliasName = "update command here" --Name of alias user runs to process update
--Name of the alias to check if an update is available.
GitUpdate.updateCheckAlias = "check for updates command here"
--The full name or a word in the file that this update script is in.
--Decides what package is installed last
GitUpdate.updateFileNameReference = "Name of file containing this script"
--notify update engine if player is a beta tester. If the player is a beta
--tester they will receive update notices for pre-releases for your project
GitUpdate.betaTester = false
--packages that are no longer used in the project and should be removed.
--They can not share a name with a package that you need. Otherwise this will uninstall it.
GitUpdate.removePackages = {} --can be empty
--modules that are no longer used in the project and should be removed.
GitUpdate.removeModules = {} --can be empty
--Used to tell player correct installation method if they installed scripts as modules
GitUpdate.installationURL = "https://github.com/yourproject/wiki/Installation"
--cecho compatible color, it will hightlight cecholinks in the update process
GitUpdate.cmdHighlight = "blue"
--use in a repair aliase, set this variable to true if a repair install is needed.
--no need to change this, here to show it exists.
GitUpdate.repairInstall = fuzzyBoolean(GitUpdate.repairInstall)
--Edit above this line---------------------
--No need to change variables below
GitUpdate.filePattern = ".*%/(.*%..*)$" --string pattern to detect file name at end of url or file path string
GitUpdate.downloadError = false --Sets to true if there is a download error.
GitUpdate.installationError = false --sets to true if there is a package installation error.
GitUpdate.installationInProgress = false --notifies update engine if update is running.
GitUpdate.releaseIndex = 0 --Position on proper update in gitHub JSON table
GitUpdate.trackedURLs = {} --will be URLs that need to have downloads tracked
--create event handlers.
GitUpdate.downloadDoneID = registerAnonymousEventHandler("sysDownloadDone", "GitUpdateEventHandler")
GitUpdate.downloadErrorID = registerAnonymousEventHandler("sysDownloadError", "GitUpdateEventHandler")
GitUpdate.installPackageID = registerAnonymousEventHandler("sysInstallPackage", "GitUpdateEventHandler")
GitUpdate.uninstallPackageID = registerAnonymousEventHandler("sysUninstallPackage", "GitUpdateEventHandler")
trackedDownloads = {} --leave blank, needed for events. Is initialized in function trackDownloads
trackedDownloads.fileList = "" --leave blank, needed for events. Initialized in function trackDownloads
trackedDownloads.urlList = "" --leave blank, used to check for download errors.
debugToDisplay("function GitUpdate.config: Initialized update engine.\n\tgitReleaseURL: "..GitUpdate.gitReleaseURL
.."\n\tScriptFileNameReference: "..GitUpdate.updateFileNameReference
.."\n\tlocalRespitory: "..GitUpdate.localRespitory
.."\n\tgitReleaseURLJSONFile: "..GitUpdate.gitReleaseURLJSONFile
.."\n\tLocal Parthia version: "..GitUpdate.localVersion)
end --function GitUpdateconfig()
--displays messages to debugc.
--can be changed to send to what ever console you would like with cecho
--if not debugToDisplay then
function debugToDisplay(textMessage)
debugc(textMessage) -- print message to screen
end --end displayToDebug function
--end --if not debugToDisplay
--Displays a yellow notice to debug console
if not tecWarningNotification then
--fully notifies user when an error is found.
function tecWarningNotification(errorFound)
debugc("Warning: "..errorFound)
end --function tecErrorNotification
end --if not tecWarningNotification then
if not ReplaceStringMagicChar then
--used to replace magic characters in a string with the proper escape character
--sequence. Useful for replacing file names on sysDownload events.
function ReplaceStringMagicChar(tmpString)
tmpString = tmpString:gsub("%%", "%%%")
tmpString = tmpString:gsub("%(", "%%(")
tmpString = tmpString:gsub("%)", "%%)")
tmpString = tmpString:gsub("%.", "%%.")
tmpString = tmpString:gsub("%+", "%%+")
tmpString = tmpString:gsub("%[", "%%[")
tmpString = tmpString:gsub("%^", "%%^")
tmpString = tmpString:gsub("%$", "%%$")
tmpString = tmpString:gsub("%-", "%%-")
tmpString = tmpString:gsub("%*", "%%*")
tmpString = tmpString:gsub("%?", "%%?")
return tmpString
end --function ReplaceStringMagicChar(tmpString)
end --if not ReplaceStringMagicChar
--displays a message to player that an error was found, and to contact a developer
if not tecErrorNotification then
function tecErrorNotification(errorFound)
debugc("Error: "..errorFound)
cecho("<red:>Error: "..errorFound.."\n\tPlease contact a developer.")
end --function tecErrorNotification
end --if not tecErrorNotification
--Used to easily change update notification. There are multiple instances where
--Parthia notifies player an update is available.
local function updateAvailable(updateBody)
--if this is a repair install. Download and install without prompting player.
if GitUpdate.repairInstall then
--Start downloading scripts as a temptimer so the function that called
--updateAvailable can complete.
tempTimer(1, "DownloadGitScripts()")
GitUpdate.repairInstall = false --reset so it will not run if player checks for updates
else --this is not a repair install prompt the user if they would like to update.
enableAlias(GitUpdate.aliasName) --enable alias so user can run update with command
cecho("An update is available. The new features it offers are: \n\t")
cecho(updateBody)
cecho("\n<:maroon>To update now, please run: ")
cechoLink("<:blue>"..GitUpdate.aliasName, --link text to display
[[expandAlias(GitUpdate.aliasName)]], --link command to run
"Update game client", true) --link tool tip for mouse hover
echo("\n") --cechoLinks don't cause the window to autoscroll.
end --if GitUpdate.repairInstall
end --function updateAvailable
--gather urls from github release that player needs to update to
local function collectURLs()
if GitUpdate.releaseIndex == 0 then --make certain releaseIndex has been initialized
debugc("function: collectURL, url collection releaseIndex was not initialized.")
return "function: compareVersions, url collection releaseIndex was not initialized."
elseif GitUpdate.gitJSONTable[GitUpdate.releaseIndex].assets.browser_download_url then
debugc("function: collectURL, url collection JSONTable lacks assets.")
return "function: compareVersions, url collection JSONTable lacks assets."
else
for index, gitAsset in --loop through git release assets.
ipairs(GitUpdate.gitJSONTable[GitUpdate.releaseIndex].assets) do
--save URL needing download to a new table.
--debugc("function: compareVersions tracking URL: "..gitAsset.browser_download_url)
GitUpdate.trackedURLs[index] = gitAsset.browser_download_url
end --for GitUpdate.gitJSONTable[GitUpdate.releaseIndex].assets
debugToDisplay("function collectURLs(): GitUpdate.trackedURLs initialized.")
end --if releaseIndex == 0
end --collectURLS
--Search for latest nonbeta release or release that is NOT a prerelease
--function is here to reduce complexity of function that calls it.
local function releaseSearch()
if GitUpdate.gitJSONTable[1].name then --if the table exists
--debugc("gitUpdate release search, JSON table exists.")
for index, releaseData in ipairs(GitUpdate.gitJSONTable) do --loop through the JSON table
--debugc("gitUpdate release search, searching index: "..tostring(index))
debugToDisplay("function releaseSearch, searching index: "..tostring(index))
--Find the latest release that is NOT a prerelease.
if not releaseData.prerelease then --if the release is not a prerelease
--debugc("gitUpdate release search, found latest release at: "..tostring(index))
debugToDisplay("function releaseSearch, found latest release at: "..tostring(index)
.."\n\tRelease tab_name: "..releaseData.tag_name
.." Local release: "..GitUpdate.localVersion)
--If the installed Parthia is different that latest release
if releaseData.tag_name ~= GitUpdate.localVersion then
GitUpdate.releaseIndex = index --collect the release index
local errorFound collectURLs() --gather URLs into trackedURLs table
if errorFound then --collectURLs returns a string if error occured.
return errorFound
else
updateAvailable(releaseData.body) --notify player an update is available
return
end --if errorFound else
else --if releaseData.tag_name ~= GitUpdate.localVersion, Parthia up to date.
cecho("Parthia is up to date.\n")
return --end releaseSearch()
end --if releaseData.prerelease.tag_name ~= GitUpdate.localVersion
end --if releaseData.prerelease == "false"
end --for
else --if the JSON table does NOT exist.
errorFound = "function releaseSearch, Error, JSON table not found during release search."
return errorFound--error found stop update.
end --if GitUpdate.gitJSONTable[1].name exists
end --function releaseSearch
--Tracks downloads so updates do not start until all downloads have completed.
--This has been created to allow it to be module.
--downloadURL is a table containing a urls that need to be downloaded.
--!!!trackDownloads(downloadURLs) HAS to be ran BEFORE the downloads are initiated!!!
function trackDownloads(downloadURLs)
if downloadURLs[1] then --if downloadURLs is a table
debugToDisplay("function trackDownloads, table passed.")
--move the URL containing the script name to the end of the table.
for index, urlToTrack in ipairs(downloadURLs) do
if urlToTrack:match(GitUpdate.updateFileNameReference) then
debugToDisplay("function trackDownloads, URL containing update script was found at\n\t"
..urlToTrack.." moving it to end of table.")
table.remove(downloadURLs, index) --remove the URL from the table
table.insert(downloadURLs, urlToTrack) --insert it on the end of the table
break --Update script can only be in one file.
end --urlToTrack:match(GitUpdate.updateFileNameReference)
end --for downloadURLs
--Make a global table to store URLs that require tracking.
trackedDownloads = {files = {}, URLs = {}, downloaded = {}, fileList = "", tmpFiles = {}
, urlList = ""}
for index, urlToTrack in ipairs(downloadURLs) do --initialize trackedDownloads table
--Get the name of the file you need to download.
local TmpPackageFileName = urlToTrack:match(GitUpdate.filePattern)
--debugc("TmpPackageFileName "..TmpPackageFileName)
--Collect package name removing any .s periods that are in it.
--in git releases spaces in filenames are replaced with .s mudlets install package process
--is sometimes not compatible with this.
local PackageNameNoExtension = string.gsub(TmpPackageFileName:match("(.*)%..*$"), "%.", " ")
--debugc("PackageNameNoExtension: "..PackageNameNoExtension)
local PackageNameExtensionOnly = TmpPackageFileName:match(".*(%..*)$")
--debugc("PackageNameExtensionOnly: "..PackageNameExtensionOnly)
--Combine the package name with file extension.
trackedDownloads.files[index] = PackageNameNoExtension..PackageNameExtensionOnly
debugToDisplay("function: trackDownloads tracking file: "..trackedDownloads.files[index])
--Boolean to notify client when download has completed.
trackedDownloads.downloaded[index] = false
--Get the name of the file you need to download.
trackedDownloads.URLs[index] = urlToTrack
--create a string that contains a list of files needing download.
--This list will be used during sysDownloadDone event to veirfy the correct download
trackedDownloads.fileList = trackedDownloads.fileList..trackedDownloads.files[index].." "
--Used to catch download errors.
trackedDownloads.urlList = trackedDownloads.urlList..urlToTrack.." "
end --for downloadURLs
elseif type(downloadURLs) == "string" then --if the variable passed is a string
debugToDisplay("function: trackDownloads string passed.")
debugToDisplay("function trackedDownloads: URL passed: "..downloadURLs)
if trackedDownloads.files[1] then --make certain the trackedDownloads table exists
--Look through trackedDownloads table to see if this is one of the tracked URLs
for index, trackedDownload in ipairs(trackedDownloads.files) do
--if the string passed matches a file name in trackedDownloads
if trackedDownload:match(downloadURLs) then
debugToDisplay("function trackedDownload: download completed and recorded for: "
..trackedDownload)
trackedDownloads.downloaded[index] = true --record that this URL downloaded successfully.
--check if all downloads have completed.
for index, urlDownloaded in ipairs(trackedDownloads.downloaded) do
if urlDownloaded then --has the current URL affiliaed with the bool been downloaded.
--debugc("function trackedDownloads: Verifing download completed for index "..index)
--If all downloaded booleans in table are true.
if index == #trackedDownloads.downloaded then
debugToDisplay("function trackedDownloads: downloads completed.")
return true --tells parthia all downloads are complete.
end --if index == #trackedDownloads.downloaded
else --Some file in the set has not been downloaded.
return false --tells parthia all downloads are not complete
end --if urlDownloaded
end --for trackedDownloads.downloaded
break --break the for loop.
end --if trackedDownload == downloadURLs
end --for trackedDownloads
else
--display error to debug, and return error message to called function
errorc("function trackDownloads: was not initialized with a table of URLs.")
return "function trackDownloads: was not initialized with a table of URLs."
end --if downloadURLs
else --argument was not a table or string.
local errorFound = "function trackDownloads: does not accept "..type(downloadURLs)
.." as an argument.\n\tOnly supports tables for initilization and strings for tracking."
errorc(errorFound)
return errorFound
end --if downloadURLs type check
end --function trackDownloads
--Here moving forward if you would like to understand the flow of updates
--it starts here.
--downloads the github JSON REST API JSON file
function DownloadGitReleaseJSON()
--check if an installation is in progress.
if GitUpdate then if GitUpdate.installationInProgress then
echo("An update is currently processing. Only one update can run at a time.\n")
return --stop updates one is processing.
end end
GitUpdateconfig() --initialize update engine.
GitUpdate.installationInProgress = true --notify Parthia an update is in progress
debugToDisplay("Update: Downloading "..GitUpdate.gitReleaseURL
.."\n\tTo: "..GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile)
downloadFile(GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile,
GitUpdate.gitReleaseURL) --download the projects latest release JSON info file.
GitUpdate.installationInProgress = false --notify Parthia installation not running.
end --function DownloadGitReleaseJSON
--after the JSON files is downloaded GitUpdateEventHandler will run compareVersions
--check if version in use is the latest released
--If player is beta test we compare the latest release both prerelease and release
--If standard player we look for latest release not prerelease
local function compareVersions()
debugToDisplay("function compareVersions, opening & reading file:\n\t"
..GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile)
--open the local github latest release JSON file in read only mode
local gitJSONFile, errorFound =
io.open(GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile, "r")
if not gitJSONFile then --file was not created error occured.
tecErrorNotification("function compareVersions: "..errorFound)
gitJSONFile:close() --incase of partial failure, close file.
gitJSONFile = nil
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --error found stop update.
end --if not gitJSONFile
local gitJSONString = gitJSONFile:read("*a") --read the entire file to a string
gitJSONFile:close() --close the file
gitJSONFile = nil
if not gitJSONString then --the file did not read correctly.
tecErrorNotification("function compareVersions, file read failure.\n\t"
..GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile)
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --error found stop update.
end --if not gitJSONString
--Convert github release JSON into a table
GitUpdate.gitJSONTable = yajl.to_value(gitJSONString)
if GitUpdate.gitJSONTable[1].name then --if the table was made.
debugToDisplay("function compareVersions, file read successful.")
else --if the table was not successfully made we can not continue. Notify player.
errorFound = "Update: Error, JSON to table conversion unsuccessfull.\n\tOpened file: "
..GitUpdate.localRespitory..GitUpdate.gitReleaseURLJSONFile
.."\n\tIt contained: "..gitJSONString
tecErrorNotification(errorFound) --Notify player provide method to report error
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --error found stop update.
end --GitUpdate.gitJSONTable exists
--Look the table for the latest non beta release.
if GitUpdate.betaTester then --if player is a beta tester install latest release
--if latest release tag_name does not match local version number.
debugToDisplay("Update: Release installed: "..GitUpdate.localVersion
.."\n\tLatest release: "..GitUpdate.gitJSONTable[1].tag_name)
if GitUpdate.gitJSONTable[1].tag_name ~= GitUpdate.localVersion then
GitUpdate.releaseIndex = 1 --notify update engine which version to use
updateAvailable(GitUpdate.gitJSONTable[1].body) --notify player update is available
local errorFound collectURLs() --gather URLs into trackedURLs table
if errorFound then
tecErrorNotification(errorFound)
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --error found stop update.
end --if error found
else
cecho("Thank you for beta testing!\n\tNo new releases at this time.")
end --if beta tester is not using latest release
else --The user is not a beta tester.
local errorFound = releaseSearch() --search for latest NONbeta release
if errorFound then
tecErrorNotification(errorFound)
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --error found stop update.
end --if error found
end --if betaTester
--We do not know how large the git release JSON is we will trash it just incase
--doing this after error catch, if error is found this table will still exist
GitUpdate.gitJSONTable = nil
GitUpdate.installationInProgress = false --notify Parthia installation not running.
end --function compareVersions
--The user has now run the aliase GitUpdate.aliasName to continue forward.
--Download the scripts in the latest release
function DownloadGitScripts()
--turn off the standard update command. So user will not attempt to run it while
--it is running. Also leave it off so user can not process an update when one
--is not required.
disableAlias(GitUpdate.aliasName)
GitUpdate.downloadError = false --in case of previous download error.
--check if an installation is in progress.
if GitUpdate.installationInProgress then
echo("An update is currently processing. Please wait for it to complete.\n"
.."Once the update is done you will need to check if an update is still "
.."required by running: ")
cechoLink("<:"..GitUpdate.cmdHighlight..">"..GitUpdate.updateCheckAlias,
[[DownloadGitReleaseJSON()]],
"Check for updates", true)
return
end
GitUpdate.installationInProgress = true --notify Parthia an update is in progress
--if GitUpdate.trackedURLs has been initialized.
if type(GitUpdate.trackedURLs[1]) == "string" then
trackDownloads(GitUpdate.trackedURLs) --initialize trackDownloads
else --GitUpdate.trackedURLs was not initialized throw error.
errorFound = "function DownloadGitScripts, trackedURLs was not initialized."
tecErrorNotification(errorFound)
GitUpdate.installationInProgress = false --notify Parthia installation not running.
return --stop because we can not proceed.
end --if GitUpdate.trackedURLs is not nil.
--download the files required.
for index, trackedDownload in ipairs(GitUpdate.trackedURLs) do
debugToDisplay("function DownloadGitScripts, downloading "
..trackedDownload.."\n\tto "
..GitUpdate.localRespitory..trackedDownloads.files[index])
--download file
downloadFile(GitUpdate.localRespitory..trackedDownloads.files[index], trackedDownload)
end --for GitUpdate.trackedURLs
--[[
--this code can be used to test trackedDownloads without using sysDownloadDone function
for index, trackedDownload in ipairs(GitUpdate.trackedURLs) do
debugToDisplay("function GitUpdate.downloadScripts downloading "
..trackedDownload.."\n\tto "
..GitUpdate.localFileStore..trackedDownloads.files[index])
boolOrErrorMessage = trackDownloads(trackedDownloads.files[index])
local tmpString = GitUpdate.localFileStore..trackedDownloads.files[index]
cecho("File name: "..tmpString:match(GitUpdate.filePattern).."\n")
cecho("fileList is: "..trackedDownloads.fileList.."\n")
cecho("Found match in fileList for file downloaded: "..
trackedDownloads.fileList:match(tmpString:match(GitUpdate.filePattern)).."\n")
if boolOrErrorMessage then
debugToDisplay("Downloads completed!!!")
end
end --for GitUpdate.trackedURLs
]]--
end --function GitUpdate.downloadScripts()
--After all files have been downloaded GitUpdateEventHandler will call InstallGitUpdates
local function InstallGitUpdates()
if GitUpdate.downloadError then --if a download error occured.
cecho("Download error occured. Update can not be processed.\n")
GitUpdate.downloadError = false --Reset now that we have caught the error.
end --if GitUpdate.downloadError
local localSourceDirectory = GitUpdate.localRespitory --Keep required data outside of GitUpdate
for index, fileName in ipairs(trackedDownloads.files) do --loop through scripts, and install them
local packageName = fileName:match("(.*)%.") --remove extension from filename
local packageTypeList = {"alias", "trigger", "timer", "keybind", "script",
"Alias", "Trigger", "Timer", "Keybind", "Script",
"KeyBind"}
for index, packageTypeName in ipairs(packageTypeList) do
packageType = packageName:match(packageTypeName) --find packageType in the package name
if packageType then --package name contains a package type. Use it to error check.
debugToDisplay("function InstallGitUpdates: Package type found, "
..packageType..". Error checking will be processed for" ..packageName)
break --packageType found. Contining this would would nil packageType
end --if packageType
end --for ipairs(packageTypeList)
--if this package is installed as a module. Do not install it.
if getModulePath(packageName) then
local errorFound = packageName..", is installed as a module. Having one script installed as "
.."both a module and a package is not supported."
tecWarningNotification("function InstallGitUpdates, "..errorFound)
cecho(errorFound.." If you are not a developer player installation instructions "
.."can be found ")
cechoLink("<:"..GitUpdate.cmdHighlight..">here",
[[openUrl("]]..GitUpdate.installationURL..[[")]],
"Player installation site", true)
cecho("\n")
else --script is not installed as a module already proceed with instalation as package
uninstallPackage(packageName) --remove old package
--comment out uninstallPackage and uncomment raiseEvent to test without uninstalling package
--raiseEvent("sysUninstallPackage", packageName)
if packageType then --package name contains a package type. Use it to error check.
if 0 ~= exists(packageName, packageType) then --if packagename appears in mudlet
debugToDisplay("<yellow:>Warning function InstallGitUpdates: appearance of the package "
..packageName.." in the "..packageType.." section unexpected.")
end --if 0 ~= exists(packageName, packageType)
end --if packageType
installPackage(localSourceDirectory..fileName) --install new package
--comment out installPackage and uncomment raiseEvent to test without installing package
--raiseEvent("sysInstallPackage", packageName, localSourceDirectory..fileName)
if packageType then --package name contains a package type. Use it to error check.
if 0 == exists(packageName, packageType) then --if packageName does not exist in mudlet
local errorFound = "function InstallGitUpdates: "..packageName.." was not found in "
.." the "..packageType.." section. After package installation."
tecErrorNotification(errorFound) --display error.
GitUpdate.installationError = true --Notify InstallGitUpdates there is an error
end --if 0 ~= exists(packageName, packageType)
end --if packageType
end --if getModulePath(packageName)
end --for InstallGitUpdates
if GitUpdate.installationError then --there were errors during installation.
cecho("Errors during installation. Please report issues using the report issues button "
.."in the settings window.\n")
GitUpdate.installationInProgress = false --notify Parthia installation not running.
--if events were previously created, kill them.
if GitUpdate.downloadDoneID then
killAnonymousEventHandler(GitUpdate.downloadDoneID)
end --if GitUpdate.downloadDoneID
if GitUpdate.downloadErrorID then
killAnonymousEventHandler(GitUpdate.downloadErrorID)
end --if GitUpdate.downloadErrorID
if GitUpdate.installPackageID then
killAnonymousEventHandler(GitUpdate.installPackageID)
end --if GitUpdate.installPackageID
if GitUpdate.uninstallPackageID then
killAnonymousEventHandler(GitUpdate.uninstallPackageID)
end --if GitUpdate.downloadDoneID
return --stop update process
end --if GitUpdate.installationError
--go through list of unwanted packages and modules remove them. GitUpdate.removeModules
for _, removeScriptsTable in pairs({GitUpdate.removePackages, GitUpdate.removeModules}) do
for _, packageToRemove in ipairs(removeScriptsTable) do
uninstallPackage(packageToRemove) --uninstall unwanted packages.
--check for a folder that shares a name with an unwanted package in each section type
for _, packageType in ipairs( {"alias", "trigger", "timer", "keybind", "script"}) do
--if the a folder exists with the name of an unwanted package
if (exists(packageToRemove, packageType) > 0) then
tecWarningNotification("function InstallGitUpdates, package "
..packageToRemove.." was removed but a folder for it still exits "
.."in the "..packageType.." section.")
end --if exists(packageToRemove)
end --for ipairs( "alias", "trigger", "timer", "keybind", "script")
end --for ipairs(GitUpdate.removePackages)
end --for pairs(GitUpdate.removePackages, GitUpdate.removeModules)
--resetProfile() --reset to profile so UI will properly reset.
--cecho("Loading display please wait.\n")
--UIManagerSetTheme("PlayersTheme", false) --reset the display
debugToDisplay("Updates completed.\n")
cecho("Updates completed. You may need to restart.\n")
GitUpdate.installationInProgress = false --notify Parthia installation not running.
--if events were previously created, kill them.
if GitUpdate.downloadDoneID then
killAnonymousEventHandler(GitUpdate.downloadDoneID)
end --if GitUpdate.downloadDoneID
if GitUpdate.downloadErrorID then
killAnonymousEventHandler(GitUpdate.downloadErrorID)
end --if GitUpdate.downloadErrorID
if GitUpdate.installPackageID then
killAnonymousEventHandler(GitUpdate.installPackageID)
end --if GitUpdate.installPackageID
if GitUpdate.uninstallPackageID then
killAnonymousEventHandler(GitUpdate.uninstallPackageID)
end --if GitUpdate.downloadDoneID
end --function InstallGitUpdates
function GitUpdateEventHandler(event, ...)
if event == "sysDownloadDone" then --if it is a downloadDone event.
--arg[1] is full file including directory
--ReplaceStringMagicChar puts ecscape % before lua magic characters
local file = ReplaceStringMagicChar(arg[1])
debugToDisplay("function GitUpdateEventHandler, file downloaded post magic "
.."character replacement it is:\n\t"..file)
if GitUpdate.gitReleaseURLJSONFile:match(file:match(GitUpdate.filePattern)) then --download is version check file
debugToDisplay("function GitUpdateEventHandler, Download: "..file
.."\n\tcompareVersions() called.")
compareVersions() --Use downloaded JSON file to check if latest version is installed
--if the name of the file being downloaded is in trackedDownloads.fileList
elseif trackedDownloads.fileList:match(file:match(GitUpdate.filePattern)) then
local boolOrErrorMessage = trackDownloads(file:match(GitUpdate.filePattern))
if boolOrErrorMessage then --if true, all files have downloaded.
debugToDisplay("function GitUpdateEventHandler, all downloads completed. "
.."Running function InstallGitUpdates()")
InstallGitUpdates() --install the downloaded scripts
elseif type(boolOrErrorMessage) == "string" then --if error found
tecErrorNotification(boolOrErrorMessage) --notify player of error
else --all downloads are not completed.
debugToDisplay("function GitUpdateEventHandler, "..file.." completed downloading. Not all tracked files downloaded yet.")
end --if boolOrErrorMessage
else
debugToDisplay("function GitUpdateEventHandler, Downloaded file: "..file
.."\n\tWas NOT caught by event handler. If this SHOULD be a tracked download, system "
.."attempted to track: "..file:match(GitUpdate.filePattern))
end --elseif file downloaded is new script
elseif event == "sysDownloadError" then --if there is a download error.
local errorFound = arg[1] --sysDownloadError only argument is error message.
local erroredURL = arg[1]:match(".*(https:%/%/%S+)") --retreive URL in error message
--debugc("Errored URL: "..erroredURL)
--if then error download's URL matches downloads for this update engine
if trackedDownloads.urlList:match(erroredURL) or GitUpdate.gitReleaseURL == erroredURL then
tecErrorNotification("fuction GitUpdate.downloadErrorEventHandler, "..errorFound)
GitUpdate.downloadError = true --notify InstallGitUpdates not to proceed.
else --for any other download errors.
debugToDisplay("fuction GitUpdate.downloadErrorEventHandler, "..errorFound)
end --if trackedDownloads.urlList:match(erroredURL)
elseif event == "sysInstallPackage" then --after a package has installed.
local localInstalledPackageName = arg[1] --notify
local localInstalledPackageFileName = arg[2]
debugToDisplay("function GitUpdateEventHandler: "..localInstalledPackageName.." package installed from file: "
..localInstalledPackageFileName)
elseif event == "sysUninstallPackage" then --after a package has installed.
local tecUninstalledPackage = arg[1]
debugToDisplay("function GitUpdateEventHandler: "..tecUninstalledPackage.." package uninstalled.")
end --if event name
end --function tecUpdate.eventHandler()