Advertisement
npexception

CC AutoUpdater

Mar 8th, 2014
2,818
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.46 KB | None | 0 0
  1. local version = 4.5
  2. -- version must be first line and must be a number
  3. -- the name of this variable does not matter, the updater just checks
  4. -- for the equals sign in the first line.
  5.  
  6. -- wait threshold before calling pastebin.
  7. -- you can set this to 0 if you want,
  8. -- but if more than 600 requests are sent to pastebin
  9. -- within 10 minutes, your MC server IP will be banned on pastebin.
  10. local pastebinwait = 10
  11.  
  12. --[[
  13.   If you want to be able to use the
  14.   "doAutoUpdate" function for your programs,
  15.   just run this script before you
  16.   run a program in which you want
  17.   to use the method.
  18.  
  19.   If you run this script with the
  20.   command line parameter "nocheck",
  21.   it will not check for updates for
  22.   itself
  23.  
  24.   The command line parameter "nocolor" will
  25.   turn the coloring of terminal outputs off.
  26.   You can also change this during runtime by
  27.   setting "updater.useColoredOutput" to true or false
  28. ]]--
  29.  
  30. if not http then
  31.     printError( "The updater requires http API" )
  32.     printError( "Set http_enable to true in ComputerCraft.cfg" )
  33.     return
  34. end
  35.  
  36. local _args = {...}
  37.  
  38. local updater = {
  39.   useColoredOutput = true
  40. }
  41. _G.updater = updater
  42. _G._UD = updater
  43.  
  44. for k,v in pairs(_args) do
  45.   if v == "nocolor" then
  46.     updater.useColoredOutput = false
  47.   end
  48. end
  49.  
  50.  
  51. local function startswith(text, piece)
  52.   return string.sub(text, 1, string.len(piece)) == piece
  53. end
  54.  
  55. local function isParamListValid(params, paramTypes)
  56.   for i,types in ipairs(paramTypes) do
  57.     if type(types) ~= "table" then
  58.       types = {types}
  59.     end
  60.     local okay = false
  61.     for _,typ in ipairs(types) do
  62.       if type(params[i]) == typ then
  63.         okay = true
  64.       end
  65.     end
  66.     if not okay then
  67.       return false
  68.     end
  69.   end
  70.   return true
  71. end
  72.  
  73.  
  74. local function update( usedVersion, pastebinkeyOrURL, cArgs, silent, onlyExplicitUpdate, wait )
  75.   local updateParam = "--updatecheck"
  76.   local noUpdateParam = "--noupdatecheck"
  77.  
  78.   local performUpdate = not onlyExplicitUpdate
  79.  
  80.   -- first check if the update check should be skipped
  81.   if cArgs then
  82.     for _,v in ipairs(cArgs) do
  83.       if v == noUpdateParam then
  84.         return false
  85.       elseif v == updateParam then
  86.         performUpdate = true
  87.       end
  88.     end
  89.     -- insert the noupdate parameter into the command line argument table
  90.     table.insert(cArgs, noUpdateParam)
  91.   end
  92.  
  93.   if not performUpdate then
  94.     return false
  95.   end
  96.  
  97.   local extractVersionFromLine = function(line)
  98.     local equalsIndex = string.find(line,"=")
  99.     if not equalsIndex then
  100.       equalsIndex = 0
  101.     end
  102.     return tonumber( string.sub( line, equalsIndex+1) )
  103.   end
  104.  
  105.   local useColoredOutput = updater.useColoredOutput
  106.  
  107.   -- do update check --
  108.   local currentprogram = shell.getRunningProgram()
  109.  
  110.   if not usedVersion then
  111.     local file = fs.open(currentprogram, "r")
  112.     usedVersion = extractVersionFromLine(file.readLine())
  113.     file.close()
  114.   end
  115.  
  116.   if not usedVersion then
  117.     if not silent then
  118.       if useColoredOutput and term.isColor() then
  119.         term.setTextColor(colors.red)
  120.       end
  121.       print("First line of local file does not contain a number!")
  122.       if useColoredOutput and term.isColor() then
  123.         term.setTextColor(colors.white)
  124.       end
  125.     end
  126.     return false
  127.   end
  128.  
  129.   if not silent then
  130.     if useColoredOutput and term.isColor() then
  131.       term.setTextColor(colors.yellow)
  132.     end
  133.     print("Checking version for \""..currentprogram.."\"")
  134.     if useColoredOutput and term.isColor() then
  135.       term.setTextColor(colors.white)
  136.     end
  137.   end
  138.  
  139.   local url
  140.   if startswith(pastebinkeyOrURL,"http://") or startswith(pastebinkeyOrURL,"https://") then
  141.     url = pastebinkeyOrURL
  142.   else
  143.     url = "http://pastebin.com/raw/"..textutils.urlEncode( pastebinkeyOrURL )
  144.     wait = wait or pastebinwait    
  145.     if wait and wait > 0 then
  146.       while wait > 0 do
  147.         if not silent then
  148.           if useColoredOutput and term.isColor() then
  149.             term.setTextColor(colors.orange)
  150.           end
  151.           local x,y = term.getCursorPos()
  152.           term.setCursorPos(1,y)
  153.           term.clearLine()
  154.           term.write("Pastebin spam protect: ")
  155.           if useColoredOutput and term.isColor() then
  156.             term.setTextColor(colors.white)
  157.           end
  158.           term.write(tostring(wait))
  159.         end
  160.         sleep(1)
  161.         wait = wait - 1
  162.       end
  163.       if not silent then
  164.         local x,y = term.getCursorPos()
  165.         term.setCursorPos(1,y)
  166.         term.clearLine()
  167.       end
  168.     end
  169.   end
  170.  
  171.   if not silent then
  172.     term.write("Fetching latest from pastebin.com")
  173.   end
  174.  
  175.   local response = http.get(url)
  176.  
  177.   if not silent then
  178.     local x,y = term.getCursorPos()
  179.     term.setCursorPos(1,y)
  180.     term.clearLine()
  181.   end
  182.  
  183.   if response and response.getResponseCode() == 200 then
  184.     local versionline = response.readLine()
  185.     local content = response.readAll()
  186.    
  187.     local fileversion = extractVersionFromLine(versionline)
  188.     if not fileversion then
  189.       if not silent then
  190.         if useColoredOutput and term.isColor() then
  191.           term.setTextColor(colors.orange)
  192.         end
  193.         print("First line of online file does not contain a number!")
  194.         if useColoredOutput and term.isColor() then
  195.           term.setTextColor(colors.white)
  196.         end
  197.       end
  198.       return false
  199.     end
  200.     if (fileversion > usedVersion) then
  201.       local file = fs.open(currentprogram, "w")
  202.       file.writeLine(versionline)
  203.       file.write(content)
  204.       file.close()
  205.      
  206.       if not silent then
  207.         if useColoredOutput and term.isColor() then
  208.           term.setTextColor(colors.lime)
  209.         end
  210.         print("Updated from version "..tostring(usedVersion).." to "..tostring(fileversion).."!")
  211.         if useColoredOutput and term.isColor() then
  212.           term.setTextColor(colors.white)
  213.         end
  214.       end
  215.      
  216.       -- if this is not nil, pass the contained arguments to the updated program
  217.       if cArgs ~= nil then
  218.         for _,v in ipairs(cArgs) do
  219.           currentprogram = currentprogram.." "..v
  220.         end
  221.         -- run updated program
  222.         shell.run(currentprogram)
  223.       end
  224.      
  225.       return true
  226.     elseif fileversion == usedVersion and not silent then
  227.       if useColoredOutput and term.isColor() then
  228.         term.setTextColor(colors.lightBlue)
  229.       end
  230.       print("You already have the current version")
  231.     elseif not silent then
  232.       if useColoredOutput and term.isColor() then
  233.         term.setTextColor(colors.magenta)
  234.       end
  235.       print("You even have a newer version! o.O")
  236.     end
  237.   elseif not silent then
  238.     if useColoredOutput and term.isColor() then
  239.       term.setTextColor(colors.orange)
  240.     end
  241.     print("Version check failed!")
  242.   end
  243.  
  244.   if not silent and useColoredOutput and term.isColor() then
  245.     term.setTextColor(colors.white)
  246.   end
  247.   -- nothing updated, nothing happened
  248.   return false
  249. end
  250.  
  251. --[[
  252.   If a newer version than the given one
  253.   was found, the updated program will be executed by this
  254.   method (depending on "cArgs") and it will return true afterwards.
  255.   Otherwise it will return false.
  256.   So if this method returns true, you should immediately
  257.   exit your program.
  258.   Parameters:
  259.     usedVersion = The version currently used. can be nil
  260.     pastebinkey = The key on PasteBin for the file
  261.                   of which the version should be checked
  262.     cArgs = The command line arguments (table) of the current executing program.
  263.             This is optional and is used to pass command line arguments
  264.             to the udated program. If you hand in nil here, the updated program
  265.             will NOT be automatically run. So if you want it to be run without
  266.             parameters, just pass an empty table.
  267. ]]--
  268. function updater.autoUpdate( par1, par2, par3, par4, par5, par6 )
  269.   local params = {par1, par2, par3, par4, par5, par6}
  270.  
  271.   if isParamListValid(params,{ {"number","nil"}, "string", "table", {"boolean","nil"}, {"boolean","nil"}, {"number","nil"} }) then
  272.     return update(par1, par2, par3, par4, par5, par6)
  273.   elseif isParamListValid(params,{ "string", "table", {"boolean","nil"}, {"boolean","nil"}, {"number","nil"} }) then
  274.     return update(nil, par1, par2, par3, par4, par5)
  275.   end
  276. end
  277.  
  278. --[[
  279.   This method will call "updater.autoUpdate", but wraps it into a
  280.   protected call. This prevents a program from failing
  281.   just because an error occured during the update process.
  282. ]]--
  283. function updater.safeAutoUpdate( par1, par2, par3, par4, par5, par6 )
  284.     local useColoredOutput = updater.useColoredOutput
  285.     -- try updating
  286.     local success, result = pcall( updater.autoUpdate, par1, par2, par3, par4, par5, par6 )
  287.    
  288.     if not success then
  289.       if useColoredOutput and term.isColor() then
  290.         term.setBackgroundColor(colors.black)
  291.         term.setTextColor(colors.red)
  292.       end
  293.       print("Error occured in update check:")
  294.       if useColoredOutput and term.isColor() then
  295.         term.setTextColor(colors.orange)
  296.       end
  297.       print(" > "..result)
  298.       if useColoredOutput and term.isColor() then
  299.         term.setTextColor(colors.white)
  300.       end
  301.       print("Continuing in 5 seconds...")
  302.       sleep(5)
  303.       return false
  304.     else
  305.       return result
  306.     end
  307. end
  308.  
  309.  
  310. -- alias short function names
  311. updater.u  = updater.autoUpdate
  312. updater.su = updater.safeAutoUpdate
  313.  
  314. -- check for updates
  315. if updater.safeAutoUpdate( "HF7vwabd", _args) then
  316.   return
  317. end
  318.  
  319. print("Using AutoUpdater version "..tostring(version))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement