Advertisement
hunters2020

MiniatureCraft Installer

Feb 21st, 2015
7,806
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. if not http then error("HTTP API must be enabled.") end
  2. if not term.isColor() then error("An Advanced Computer is required to play this game.") end
  3.  
  4. ------------------------------------------------------------------ utils
  5.  
  6. local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
  7. local whites = {['\n']=true; ['\r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
  8. local function removeWhite(str)
  9.     while whites[str:sub(1, 1)] do
  10.         str = str:sub(2)
  11.     end
  12.     return str
  13. end
  14.  
  15. ------------------------------------------------------------------ decoding
  16.  
  17. local parseBoolean, parseNull, parseNumber, parseString, parseArray, parseMember, parseObject, parseValue
  18. local decodeControls = {}
  19. for k,v in pairs(controls) do
  20.     decodeControls[v] = k
  21. end
  22.  
  23. parseBoolean = function(str)
  24.     if str:sub(1, 4) == "true" then
  25.         return true, removeWhite(str:sub(5))
  26.     else
  27.         return false, removeWhite(str:sub(6))
  28.     end
  29. end
  30.  
  31. parseNull = function(str)
  32.     return nil, removeWhite(str:sub(5))
  33. end
  34.  
  35. local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
  36. parseNumber = function(str)
  37.     local i = 1; while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do i = i + 1 end
  38.     return tonumber(str:sub(1, i - 1)), removeWhite(str:sub(i))
  39. end
  40.  
  41. parseString = function(str)
  42.     str = str:sub(2)
  43.     local s = ""
  44.     while str:sub(1,1) ~= "\"" do
  45.         local next = str:sub(1,1)
  46.         str = str:sub(2)
  47.         assert(next ~= "\n", "Unclosed string")
  48.  
  49.         if next == "\\" then
  50.             local escape = str:sub(1,1)
  51.             str = str:sub(2)
  52.  
  53.             next = assert(decodeControls[next..escape], "Invalid escape character")
  54.         end
  55.  
  56.         s = s .. next
  57.     end
  58.     return s, removeWhite(str:sub(2))
  59. end
  60.  
  61. parseArray = function(str)
  62.     str = removeWhite(str:sub(2))
  63.  
  64.     local val = {}
  65.     local i = 1
  66.     while str:sub(1, 1) ~= "]" do
  67.         local v = nil
  68.         v, str = parseValue(str)
  69.         val[i] = v
  70.         i = i + 1
  71.         str = removeWhite(str)
  72.     end
  73.     return val, removeWhite(str:sub(2))
  74. end
  75.  
  76. parseMember = function(str)
  77.     local k, str = parseValue(str)
  78.     local val, str = parseValue(str)
  79.     return k, val, str
  80. end
  81.  
  82. parseObject = function(str)
  83.     str = removeWhite(str:sub(2))
  84.  
  85.     local val = {}
  86.     while str:sub(1, 1) ~= "}" do
  87.         local k, v = nil, nil
  88.         k, v, str = parseMember(str)
  89.         val[k] = v
  90.         str = removeWhite(str)
  91.     end
  92.     return val, removeWhite(str:sub(2))
  93. end
  94.  
  95. parseValue = function(str)
  96.     local fchar = str:sub(1, 1)
  97.     if fchar == "{" then
  98.         return parseObject(str)
  99.     elseif fchar == "[" then
  100.         return parseArray(str)
  101.     elseif tonumber(fchar) ~= nil or numChars[fchar] then
  102.         return parseNumber(str)
  103.     elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
  104.         return parseBoolean(str)
  105.     elseif fchar == "\"" then
  106.         return parseString(str)
  107.     elseif str:sub(1, 4) == "null" then
  108.         return parseNull(str)
  109.     end
  110. end
  111.  
  112. local function decode(str)
  113.     return parseValue(removeWhite(str))
  114. end
  115.  
  116. ------------------------------------------------------------------ main code
  117.  
  118. local blacklist = {".gitattributes", ".gitignore", "LICENSE", "README.md"}
  119. local tArgs = {...}; local sx, sy = term.getSize()
  120.  
  121. local function save(data, file, p)
  122.     local p = p or ""
  123.     local file = shell.resolve(file)
  124.     if not (fs.exists(string.sub(file,1,#file - #fs.getName(file))) and fs.isDir(string.sub(file,1,#file - #fs.getName(file)))) then
  125.         if fs.exists(string.sub(file,1,#file - #fs.getName(file))) then fs.delete(string.sub(file,1,#file - #fs.getName(file))) end
  126.         fs.makeDir(string.sub(file,1,#file - #fs.getName(file)))
  127.     end
  128.     local f = fs.open(file, "w")
  129.     f.write(data); f.close()
  130. end
  131.  
  132. local function download(url, file, p) save(http.get(url).readAll(), file, p) end
  133.  
  134. local function allowed(str)
  135.     for i = 1, #blacklist do
  136.         if blacklist[i] == str then return end
  137.     end; return true
  138. end
  139.  
  140. if not tArgs[1] then
  141.     term.setBackgroundColor(colors.white)
  142.     term.setTextColor(colors.lightGray)
  143.     term.clear()
  144.     term.setCursorPos(1, sy - 1)
  145.     term.write("Credits to apemanzilla for their Gitget program")
  146.     term.setCursorPos(1, sy)
  147.     term.write("Credits to ElvishJerricco's for their JSON API")
  148.  
  149.     term.setTextColor(colors.cyan)
  150.     term.setCursorPos((sx / 2) - 12, 3)
  151.     term.write("MiniatureCraft Installer")
  152.     term.setTextColor(colors.blue)
  153.     term.setCursorPos((sx / 2) - 9, 6)
  154.     term.write("Path to install to:")
  155.     term.setCursorPos((sx / 2) - 21, 10)
  156.     term.write("Leave blank for default folder, '/' for root.")
  157.     paintutils.drawLine(sx / 4, 8, (sx / 4) * 3, 8, colors.gray)
  158.     term.setCursorPos(sx / 4, 8)
  159.     term.setTextColor(colors.yellow)
  160.     path = read(); if path == "" then path = "MC/" end
  161.  
  162.     term.setTextColor(colors.blue)
  163.     paintutils.drawLine(sx / 4, 6, (sx / 4) * 3, 6, colors.white)
  164.     term.setCursorPos((sx / 2) - 7, 6)
  165.     term.write("Installing...")
  166. end
  167.  
  168. local branch = tArgs[2] and "Alpha" or "master"
  169. local data = decode(http.get("https://api.github.com/repos/DetectiveSmith/MiniatureCraft/git/trees/"..branch.."?recursive=1").readAll())
  170. if data.message and data.message == "Not found" then error("Could not find files.", 2) end
  171.  
  172. if not tArgs[1] then
  173.     totalBar, currentPart = #data.tree - #blacklist, 0
  174.     paintutils.drawLine(sx / 4, 8, (sx / 4) * 3, 8, colors.white)
  175.     paintutils.drawLine((sx / 2) - (totalBar / 2), 8, (sx / 2) + (totalBar / 2), 8, colors.gray)
  176. end
  177.  
  178. local path = path or tArgs[1]
  179. term.setTextColor(colors.green)
  180. for k, v in pairs(data.tree) do -- Create Directories
  181.     if v.type == "tree" then
  182.         fs.makeDir(fs.combine(path, v.path))
  183.         if not tArgs[1] then
  184.             paintutils.drawPixel((sx / 2) - (#data.tree / 2) + currentPart, 8, colors.lime)
  185.             paintutils.drawLine(1, 10, sx, 10, colors.white)
  186.             local str = "Creating Directory " ..fs.combine(path, v.path)
  187.             term.setCursorPos((sx / 2) - (#str / 2), 10)
  188.             print(str)
  189.             currentPart = currentPart + 1
  190.         end
  191.     end
  192. end
  193.  
  194. term.setTextColor(colors.yellow)
  195. for k,v in pairs(data.tree) do -- Download Files
  196.     if v.type == "blob" then
  197.         if allowed(v.path) then
  198.             download("https://raw.github.com/DetectiveSmith/MiniatureCraft/"..branch.."/"..v.path, fs.combine(path, v.path), path)
  199.             if not tArgs[1] then
  200.                 paintutils.drawPixel((sx / 2) - (#data.tree / 2) + currentPart, 8, colors.lime)
  201.                 paintutils.drawLine(1, 10, sx, 10, colors.white)
  202.                 local fulltext = "Downloading File " ..path.. "" ..v.path
  203.                 term.setCursorPos((sx / 2) - (#fulltext / 2), 10)
  204.                 term.write(fulltext)
  205.                 currentPart = currentPart + 1
  206.             end
  207.         end
  208.     end
  209. end
  210.  
  211. if not tArgs[1] then
  212.     term.setTextColor(colors.blue)
  213.     term.setBackgroundColor(colors.black)
  214.     term.clear()
  215.     term.setCursorPos(1, 1)
  216.     print()
  217.     if string.find(path, "/") then print("Installation Complete. Run " ..path.. "mc to play.")
  218.     else print("Installation Complete. Run " ..path.. "/mc to play.") end
  219.     print()
  220.     term.setTextColor(colors.white)
  221. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement