Advertisement
Ewgeniy

MainOS?

Aug 30th, 2021 (edited)
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.92 KB | None | 0 0
  1. -- Checking for required components
  2. local function getComponentAddress(name)
  3.     return component.list(name)() or error("Required " .. name .. " component is missing")
  4. end
  5.  
  6. local function getComponentProxy(name)
  7.     return component.proxy(getComponentAddress(name))
  8. end
  9.  
  10. local EEPROMProxy, internetProxy, GPUProxy =
  11.     getComponentProxy("eeprom"),
  12.     getComponentProxy("internet"),
  13.     getComponentProxy("gpu")
  14.  
  15. -- Binding GPU to screen in case it's not done yet
  16. GPUProxy.bind(getComponentAddress("screen"))
  17. local screenWidth, screenHeight = GPUProxy.getResolution()
  18.  
  19. local repositoryURL = "https://raw.githubusercontent.com/IgorTimofeev/MineOS/master/"
  20. local installerURL = "Installer/"
  21. local EFIURL = "EFI/Minified.lua"
  22.  
  23. local installerPath = "/MineOS installer/"
  24. local installerPicturesPath = installerPath .. "Installer/Pictures/"
  25. local OSPath = "/"
  26.  
  27. local temporaryFilesystemProxy, selectedFilesystemProxy
  28.  
  29. --------------------------------------------------------------------------------
  30.  
  31. -- Working with components directly before system libraries are downloaded & initialized
  32. local function centrize(width)
  33.     return math.floor(screenWidth / 2 - width / 2)
  34. end
  35.  
  36. local function centrizedText(y, color, text)
  37.     GPUProxy.fill(1, y, screenWidth, 1, " ")
  38.     GPUProxy.setForeground(color)
  39.     GPUProxy.set(centrize(#text), y, text)
  40. end
  41.  
  42. local function title()
  43.     local y = math.floor(screenHeight / 2 - 1)
  44.     centrizedText(y, 0x2D2D2D, "MineOS")
  45.  
  46.     return y + 2
  47. end
  48.  
  49. local function status(text, needWait)
  50.     centrizedText(title(), 0x878787, text)
  51.  
  52.     if needWait then
  53.         repeat
  54.             needWait = computer.pullSignal()
  55.         until needWait == "key_down" or needWait == "touch"
  56.     end
  57. end
  58.  
  59. local function progress(value)
  60.     local width = 26
  61.     local x, y, part = centrize(width), title(), math.ceil(width * value)
  62.    
  63.     GPUProxy.setForeground(0x878787)
  64.     GPUProxy.set(x, y, string.rep("─", part))
  65.     GPUProxy.setForeground(0xC3C3C3)
  66.     GPUProxy.set(x + part, y, string.rep("─", width - part))
  67. end
  68.  
  69. local function filesystemPath(path)
  70.     return path:match("^(.+%/).") or ""
  71. end
  72.  
  73. local function filesystemName(path)
  74.     return path:match("%/?([^%/]+%/?)$")
  75. end
  76.  
  77. local function filesystemHideExtension(path)
  78.     return path:match("(.+)%..+") or path
  79. end
  80.  
  81. local function rawRequest(url, chunkHandler)
  82.     local internetHandle, reason = internetProxy.request(repositoryURL .. url:gsub("([^%w%-%_%.%~])", function(char)
  83.         return string.format("%%%02X", string.byte(char))
  84.     end))
  85.  
  86.     if internetHandle then
  87.         local chunk, reason
  88.         while true do
  89.             chunk, reason = internetHandle.read(math.huge) 
  90.            
  91.             if chunk then
  92.                 chunkHandler(chunk)
  93.             else
  94.                 if reason then
  95.                     error("Internet request failed: " .. tostring(reason))
  96.                 end
  97.  
  98.                 break
  99.             end
  100.         end
  101.  
  102.         internetHandle.close()
  103.     else
  104.         error("Connection failed: " .. url)
  105.     end
  106. end
  107.  
  108. local function request(url)
  109.     local data = ""
  110.    
  111.     rawRequest(url, function(chunk)
  112.         data = data .. chunk
  113.     end)
  114.  
  115.     return data
  116. end
  117.  
  118. local function download(url, path)
  119.     selectedFilesystemProxy.makeDirectory(filesystemPath(path))
  120.  
  121.     local fileHandle, reason = selectedFilesystemProxy.open(path, "wb")
  122.     if fileHandle then 
  123.         rawRequest(url, function(chunk)
  124.             selectedFilesystemProxy.write(fileHandle, chunk)
  125.         end)
  126.  
  127.         selectedFilesystemProxy.close(fileHandle)
  128.     else
  129.         error("File opening failed: " .. tostring(reason))
  130.     end
  131. end
  132.  
  133. local function deserialize(text)
  134.     local result, reason = load("return " .. text, "=string")
  135.     if result then
  136.         return result()
  137.     else
  138.         error(reason)
  139.     end
  140. end
  141.  
  142. -- Clearing screen
  143. GPUProxy.setBackground(0xE1E1E1)
  144. GPUProxy.fill(1, 1, screenWidth, screenHeight, " ")
  145.  
  146. -- Searching for appropriate temporary filesystem for storing libraries, images, etc
  147. for address in component.list("filesystem") do
  148.     local proxy = component.proxy(address)
  149.     if proxy.spaceTotal() >= 2 * 1024 * 1024 then
  150.         temporaryFilesystemProxy, selectedFilesystemProxy = proxy, proxy
  151.         break
  152.     end
  153. end
  154.  
  155. -- If there's no suitable HDDs found - then meow
  156. if not temporaryFilesystemProxy then
  157.     status("No appropriate filesystem found", true)
  158.     return
  159. end
  160.  
  161. -- First, we need a big ass file list with localizations, applications, wallpapers
  162. progress(0)
  163. local files = deserialize(request(installerURL .. "Files.cfg"))
  164.  
  165. -- After that we could download required libraries for installer from it
  166. for i = 1, #files.installerFiles do
  167.     progress(i / #files.installerFiles)
  168.     download(files.installerFiles[i], installerPath .. files.installerFiles[i])
  169. end
  170.  
  171. -- Initializing simple package system for loading system libraries
  172. package = {loading = {}, loaded = {}}
  173.  
  174. function require(module)
  175.     if package.loaded[module] then
  176.         return package.loaded[module]
  177.     elseif package.loading[module] then
  178.         error("already loading " .. module .. ": " .. debug.traceback())
  179.     else
  180.         package.loading[module] = true
  181.  
  182.         local handle, reason = temporaryFilesystemProxy.open(installerPath .. "Libraries/" .. module .. ".lua", "rb")
  183.         if handle then
  184.             local data, chunk = ""
  185.             repeat
  186.                 chunk = temporaryFilesystemProxy.read(handle, math.huge)
  187.                 data = data .. (chunk or "")
  188.             until not chunk
  189.  
  190.             temporaryFilesystemProxy.close(handle)
  191.            
  192.             local result, reason = load(data, "=" .. module)
  193.             if result then
  194.                 package.loaded[module] = result() or true
  195.             else
  196.                 error(reason)
  197.             end
  198.         else
  199.             error("File opening failed: " .. tostring(reason))
  200.         end
  201.  
  202.         package.loading[module] = nil
  203.  
  204.         return package.loaded[module]
  205.     end
  206. end
  207.  
  208. -- Initializing system libraries
  209. local filesystem = require("Filesystem")
  210. filesystem.setProxy(temporaryFilesystemProxy)
  211.  
  212. bit32 = bit32 or require("Bit32")
  213. local image = require("Image")
  214. local text = require("Text")
  215. local number = require("Number")
  216.  
  217. local screen = require("Screen")
  218. screen.setGPUProxy(GPUProxy)
  219.  
  220. local GUI = require("GUI")
  221. local system = require("System")
  222. local paths = require("Paths")
  223.  
  224. --------------------------------------------------------------------------------
  225.  
  226. -- Creating main UI workspace
  227. local workspace = GUI.workspace()
  228. workspace:addChild(GUI.panel(1, 1, workspace.width, workspace.height, 0x1E1E1E))
  229.  
  230. -- Main installer window
  231. local window = workspace:addChild(GUI.window(1, 1, 80, 24))
  232. window.localX, window.localY = math.ceil(workspace.width / 2 - window.width / 2), math.ceil(workspace.height / 2 - window.height / 2)
  233. window:addChild(GUI.panel(1, 1, window.width, window.height, 0xE1E1E1))
  234.  
  235. -- Top menu
  236. local menu = workspace:addChild(GUI.menu(1, 1, workspace.width, 0xF0F0F0, 0x787878, 0x3366CC, 0xE1E1E1))
  237. local installerMenu = menu:addContextMenuItem("MineOS", 0x2D2D2D)
  238. installerMenu:addItem("Shutdown").onTouch = function()
  239.     computer.shutdown()
  240. end
  241. installerMenu:addItem("Reboot").onTouch = function()
  242.     computer.shutdown(true)
  243. end
  244. installerMenu:addSeparator()
  245. installerMenu:addItem("Exit").onTouch = function()
  246.     workspace:stop()
  247. end
  248.  
  249. -- Main vertical layout
  250. local layout = window:addChild(GUI.layout(1, 1, window.width, window.height - 2, 1, 1))
  251.  
  252. local stageButtonsLayout = window:addChild(GUI.layout(1, window.height - 1, window.width, 1, 1, 1))
  253. stageButtonsLayout:setDirection(1, 1, GUI.DIRECTION_HORIZONTAL)
  254. stageButtonsLayout:setSpacing(1, 1, 3)
  255.  
  256. local function loadImage(name)
  257.     return image.load(installerPicturesPath .. name .. ".pic")
  258. end
  259.  
  260. local function newInput(...)
  261.     return GUI.input(1, 1, 26, 1, 0xF0F0F0, 0x787878, 0xC3C3C3, 0xF0F0F0, 0x878787, "", ...)
  262. end
  263.  
  264. local function newSwitchAndLabel(width, color, text, state)
  265.     return GUI.switchAndLabel(1, 1, width, 6, color, 0xD2D2D2, 0xF0F0F0, 0xA5A5A5, text .. ":", state)
  266. end
  267.  
  268. local function addTitle(color, text)
  269.     return layout:addChild(GUI.text(1, 1, color, text))
  270. end
  271.  
  272. local function addImage(before, after, name)
  273.     if before > 0 then
  274.         layout:addChild(GUI.object(1, 1, 1, before))
  275.     end
  276.  
  277.     local picture = layout:addChild(GUI.image(1, 1, loadImage(name)))
  278.     picture.height = picture.height + after
  279.  
  280.     return picture
  281. end
  282.  
  283. local function addStageButton(text)
  284.     local button = stageButtonsLayout:addChild(GUI.adaptiveRoundedButton(1, 1, 2, 0, 0xC3C3C3, 0x878787, 0xA5A5A5, 0x696969, text))
  285.     button.colors.disabled.background = 0xD2D2D2
  286.     button.colors.disabled.text = 0xB4B4B4
  287.  
  288.     return button
  289. end
  290.  
  291. local prevButton = addStageButton("<")
  292. local nextButton = addStageButton(">")
  293.  
  294. local localization
  295. local stage = 1
  296. local stages = {}
  297.  
  298. local usernameInput = newInput("")
  299. local passwordInput = newInput("", false, "•")
  300. local passwordSubmitInput = newInput("", false, "•")
  301. local usernamePasswordText = GUI.text(1, 1, 0xCC0040, "")
  302. local passwordSwitchAndLabel = newSwitchAndLabel(26, 0x66DB80, "", false)
  303.  
  304. local wallpapersSwitchAndLabel = newSwitchAndLabel(30, 0xFF4980, "", true)
  305. local screensaversSwitchAndLabel = newSwitchAndLabel(30, 0xFFB600, "", true)
  306. local applicationsSwitchAndLabel = newSwitchAndLabel(30, 0x33DB80, "", true)
  307. local localizationsSwitchAndLabel = newSwitchAndLabel(30, 0x33B6FF, "", true)
  308.  
  309. local acceptSwitchAndLabel = newSwitchAndLabel(30, 0x9949FF, "", false)
  310.  
  311. local localizationComboBox = GUI.comboBox(1, 1, 22, 1, 0xF0F0F0, 0x969696, 0xD2D2D2, 0xB4B4B4)
  312. for i = 1, #files.localizations do
  313.     localizationComboBox:addItem(filesystemHideExtension(filesystemName(files.localizations[i]))).onTouch = function()
  314.         -- Obtaining localization table
  315.         localization = deserialize(request(installerURL .. files.localizations[i]))
  316.  
  317.         -- Filling widgets with selected localization data
  318.         usernameInput.placeholderText = localization.username
  319.         passwordInput.placeholderText = localization.password
  320.         passwordSubmitInput.placeholderText = localization.submitPassword
  321.         passwordSwitchAndLabel.label.text = localization.withoutPassword
  322.         wallpapersSwitchAndLabel.label.text = localization.wallpapers
  323.         screensaversSwitchAndLabel.label.text = localization.screensavers
  324.         applicationsSwitchAndLabel.label.text = localization.applications
  325.         localizationsSwitchAndLabel.label.text = localization.languages
  326.         acceptSwitchAndLabel.label.text = localization.accept
  327.     end
  328. end
  329.  
  330. local function addStage(onTouch)
  331.     table.insert(stages, function()
  332.         layout:removeChildren()
  333.         onTouch()
  334.         workspace:draw()
  335.     end)
  336. end
  337.  
  338. local function loadStage()
  339.     if stage < 1 then
  340.         stage = 1
  341.     elseif stage > #stages then
  342.         stage = #stages
  343.     end
  344.  
  345.     stages[stage]()
  346. end
  347.  
  348. local function checkUserInputs()
  349.     local nameEmpty = #usernameInput.text == 0
  350.     local nameVaild = usernameInput.text:match("^%w[%w%s_]+$")
  351.     local passValid = passwordSwitchAndLabel.switch.state or #passwordInput.text == 0 or #passwordSubmitInput.text == 0 or passwordInput.text == passwordSubmitInput.text
  352.  
  353.     if (nameEmpty or nameVaild) and passValid then
  354.         usernamePasswordText.hidden = true
  355.         nextButton.disabled = nameEmpty or not nameVaild or not passValid
  356.     else
  357.         usernamePasswordText.hidden = false
  358.         nextButton.disabled = true
  359.  
  360.         if nameVaild then
  361.             usernamePasswordText.text = localization.passwordsArentEqual
  362.         else
  363.             usernamePasswordText.text = localization.usernameInvalid
  364.         end
  365.     end
  366. end
  367.  
  368. local function checkLicense()
  369.     nextButton.disabled = not acceptSwitchAndLabel.switch.state
  370. end
  371.  
  372. prevButton.onTouch = function()
  373.     stage = stage - 1
  374.     loadStage()
  375. end
  376.  
  377. nextButton.onTouch = function()
  378.     stage = stage + 1
  379.     loadStage()
  380. end
  381.  
  382. acceptSwitchAndLabel.switch.onStateChanged = function()
  383.     checkLicense()
  384.     workspace:draw()
  385. end
  386.  
  387. passwordSwitchAndLabel.switch.onStateChanged = function()
  388.     passwordInput.hidden = passwordSwitchAndLabel.switch.state
  389.     passwordSubmitInput.hidden = passwordSwitchAndLabel.switch.state
  390.     checkUserInputs()
  391.  
  392.     workspace:draw()
  393. end
  394.  
  395. usernameInput.onInputFinished = function()
  396.     checkUserInputs()
  397.     workspace:draw()
  398. end
  399.  
  400. passwordInput.onInputFinished = usernameInput.onInputFinished
  401. passwordSubmitInput.onInputFinished = usernameInput.onInputFinished
  402.  
  403. -- Localization selection stage
  404. addStage(function()
  405.     prevButton.disabled = true
  406.  
  407.     addImage(0, 1, "Languages")
  408.     layout:addChild(localizationComboBox)
  409.  
  410.     workspace:draw()
  411.     localizationComboBox:getItem(1).onTouch()
  412. end)
  413.  
  414. -- Filesystem selection stage
  415. addStage(function()
  416.     prevButton.disabled = false
  417.     nextButton.disabled = false
  418.  
  419.     layout:addChild(GUI.object(1, 1, 1, 1))
  420.     addTitle(0x696969, localization.select)
  421.    
  422.     local diskLayout = layout:addChild(GUI.layout(1, 1, layout.width, 11, 1, 1))
  423.     diskLayout:setDirection(1, 1, GUI.DIRECTION_HORIZONTAL)
  424.     diskLayout:setSpacing(1, 1, 0)
  425.  
  426.     local HDDImage = loadImage("HDD")
  427.  
  428.     local function select(proxy)
  429.         selectedFilesystemProxy = proxy
  430.  
  431.         for i = 1, #diskLayout.children do
  432.             diskLayout.children[i].children[1].hidden = diskLayout.children[i].proxy ~= selectedFilesystemProxy
  433.         end
  434.     end
  435.  
  436.     local function updateDisks()
  437.         local function diskEventHandler(workspace, disk, e1)
  438.             if e1 == "touch" then
  439.                 select(disk.proxy)
  440.                 workspace:draw()
  441.             end
  442.         end
  443.  
  444.         local function addDisk(proxy, picture, disabled)
  445.             local disk = diskLayout:addChild(GUI.container(1, 1, 14, diskLayout.height))
  446.  
  447.             local formatContainer = disk:addChild(GUI.container(1, 1, disk.width, disk.height))
  448.             formatContainer:addChild(GUI.panel(1, 1, formatContainer.width, formatContainer.height, 0xD2D2D2))
  449.             formatContainer:addChild(GUI.button(1, formatContainer.height, formatContainer.width, 1, 0xCC4940, 0xE1E1E1, 0x990000, 0xE1E1E1, localization.erase)).onTouch = function()
  450.                 local list, path = proxy.list("/")
  451.                 for i = 1, #list do
  452.                     path = "/" .. list[i]
  453.  
  454.                     if proxy.address ~= temporaryFilesystemProxy.address or path ~= installerPath then
  455.                         proxy.remove(path)
  456.                     end
  457.                 end
  458.  
  459.                 updateDisks()
  460.             end
  461.  
  462.             if disabled then
  463.                 picture = image.blend(picture, 0xFFFFFF, 0.4)
  464.                 disk.disabled = true
  465.             end
  466.  
  467.             disk:addChild(GUI.image(4, 2, picture))
  468.             disk:addChild(GUI.label(2, 7, disk.width - 2, 1, disabled and 0x969696 or 0x696969, text.limit(proxy.getLabel() or proxy.address, disk.width - 2))):setAlignment(GUI.ALIGNMENT_HORIZONTAL_CENTER, GUI.ALIGNMENT_VERTICAL_TOP)
  469.             disk:addChild(GUI.progressBar(2, 8, disk.width - 2, disabled and 0xCCDBFF or 0x66B6FF, disabled and 0xD2D2D2 or 0xC3C3C3, disabled and 0xC3C3C3 or 0xA5A5A5, math.floor(proxy.spaceUsed() / proxy.spaceTotal() * 100), true, true, "", "% " .. localization.used))
  470.  
  471.             disk.eventHandler = diskEventHandler
  472.             disk.proxy = proxy
  473.         end
  474.  
  475.         diskLayout:removeChildren()
  476.        
  477.         for address in component.list("filesystem") do
  478.             local proxy = component.proxy(address)
  479.             if proxy.spaceTotal() >= 1 * 1024 * 1024 then
  480.                 addDisk(
  481.                     proxy,
  482.                     proxy.spaceTotal() < 1 * 1024 * 1024 and floppyImage or HDDImage,
  483.                     proxy.isReadOnly() or proxy.spaceTotal() < 2 * 1024 * 1024
  484.                 )
  485.             end
  486.         end
  487.  
  488.         select(selectedFilesystemProxy)
  489.     end
  490.    
  491.     updateDisks()
  492. end)
  493.  
  494. -- User profile setup stage
  495. addStage(function()
  496.     checkUserInputs()
  497.  
  498.     addImage(0, 0, "User")
  499.     addTitle(0x696969, localization.setup)
  500.  
  501.     layout:addChild(usernameInput)
  502.     layout:addChild(passwordInput)
  503.     layout:addChild(passwordSubmitInput)
  504.     layout:addChild(usernamePasswordText)
  505.     layout:addChild(passwordSwitchAndLabel)
  506. end)
  507.  
  508. -- Downloads customization stage
  509. addStage(function()
  510.     nextButton.disabled = false
  511.  
  512.     addImage(0, 0, "Settings")
  513.     addTitle(0x696969, localization.customize)
  514.  
  515.     layout:addChild(wallpapersSwitchAndLabel)
  516.     layout:addChild(screensaversSwitchAndLabel)
  517.     layout:addChild(applicationsSwitchAndLabel)
  518.     layout:addChild(localizationsSwitchAndLabel)
  519. end)
  520.  
  521. -- License acception stage
  522. addStage(function()
  523.     checkLicense()
  524.  
  525.     local lines = text.wrap({request("LICENSE")}, layout.width - 2)
  526.     local textBox = layout:addChild(GUI.textBox(1, 1, layout.width, layout.height - 3, 0xF0F0F0, 0x696969, lines, 1, 1, 1))
  527.  
  528.     layout:addChild(acceptSwitchAndLabel)
  529. end)
  530.  
  531. -- Downloading stage
  532. addStage(function()
  533.     stageButtonsLayout:removeChildren()
  534.    
  535.     -- Creating user profile
  536.     layout:removeChildren()
  537.     addImage(1, 1, "User")
  538.     addTitle(0x969696, localization.creating)
  539.     workspace:draw()
  540.  
  541.     -- Renaming if possible
  542.     if not selectedFilesystemProxy.getLabel() then
  543.         selectedFilesystemProxy.setLabel("MineOS HDD")
  544.     end
  545.  
  546.     local function switchProxy(runnable)
  547.         filesystem.setProxy(selectedFilesystemProxy)
  548.         runnable()
  549.         filesystem.setProxy(temporaryFilesystemProxy)
  550.     end
  551.  
  552.     -- Creating system paths
  553.     local userSettings, userPaths
  554.     switchProxy(function()
  555.         paths.create(paths.system)
  556.         userSettings, userPaths = system.createUser(
  557.             usernameInput.text,
  558.             localizationComboBox:getItem(localizationComboBox.selectedItem).text,
  559.             not passwordSwitchAndLabel.switch.state and passwordInput.text,
  560.             wallpapersSwitchAndLabel.switch.state,
  561.             screensaversSwitchAndLabel.switch.state
  562.         )
  563.     end)
  564.  
  565.     -- Flashing EEPROM
  566.     layout:removeChildren()
  567.     addImage(1, 1, "EEPROM")
  568.     addTitle(0x969696, localization.flashing)
  569.     workspace:draw()
  570.    
  571.     EEPROMProxy.set(request(EFIURL))
  572.     EEPROMProxy.setLabel("MineOS EFI")
  573.     EEPROMProxy.setData(selectedFilesystemProxy.address)
  574.  
  575.     -- Downloading files
  576.     layout:removeChildren()
  577.     addImage(3, 2, "Downloading")
  578.  
  579.     local container = layout:addChild(GUI.container(1, 1, layout.width - 20, 2))
  580.     local progressBar = container:addChild(GUI.progressBar(1, 1, container.width, 0x66B6FF, 0xD2D2D2, 0xA5A5A5, 0, true, false))
  581.     local cyka = container:addChild(GUI.label(1, 2, container.width, 1, 0x969696, "")):setAlignment(GUI.ALIGNMENT_HORIZONTAL_CENTER, GUI.ALIGNMENT_VERTICAL_TOP)
  582.  
  583.     -- Creating final filelist of things to download
  584.     local downloadList = {}
  585.  
  586.     local function getData(item)
  587.         if type(item) == "table" then
  588.             return item.path, item.id, item.version, item.shortcut
  589.         else
  590.             return item
  591.         end
  592.     end
  593.  
  594.     local function addToList(state, key)
  595.         if state then
  596.             local selectedLocalization, path, localizationName = localizationComboBox:getItem(localizationComboBox.selectedItem).text
  597.            
  598.             for i = 1, #files[key] do
  599.                 path = getData(files[key][i])
  600.  
  601.                 if filesystem.extension(path) == ".lang" then
  602.                     localizationName = filesystem.hideExtension(filesystem.name(path))
  603.  
  604.                     if
  605.                         -- If ALL loacalizations need to be downloaded
  606.                         localizationsSwitchAndLabel.switch.state or
  607.                         -- If it's required localization file
  608.                         localizationName == selectedLocalization or
  609.                         -- Downloading English "just in case" for non-english localizations
  610.                         selectedLocalization ~= "English" and localizationName == "English"
  611.                     then
  612.                         table.insert(downloadList, files[key][i])
  613.                     end
  614.                 else
  615.                     table.insert(downloadList, files[key][i])
  616.                 end
  617.             end
  618.         end
  619.     end
  620.  
  621.     addToList(true, "required")
  622.     addToList(true, "localizations")
  623.     addToList(applicationsSwitchAndLabel.switch.state, "optional")
  624.     addToList(wallpapersSwitchAndLabel.switch.state, "wallpapers")
  625.     addToList(screensaversSwitchAndLabel.switch.state, "screensavers")
  626.  
  627.     -- Downloading files from created list
  628.     local versions, path, id, version, shortcut = {}
  629.     for i = 1, #downloadList do
  630.         path, id, version, shortcut = getData(downloadList[i])
  631.  
  632.         cyka.text = text.limit(localization.installing .. " \"" .. path .. "\"", container.width, "center")
  633.         workspace:draw()
  634.  
  635.         -- Download file
  636.         download(path, OSPath .. path)
  637.  
  638.         -- Adding system versions data
  639.         if id then
  640.             versions[id] = {
  641.                 path = OSPath .. path,
  642.                 version = version or 1,
  643.             }
  644.         end
  645.  
  646.         -- Create shortcut if possible
  647.         if shortcut then
  648.             switchProxy(function()
  649.                 system.createShortcut(
  650.                     userPaths.desktop .. filesystem.hideExtension(filesystem.name(filesystem.path(path))),
  651.                     OSPath .. filesystem.path(path)
  652.                 )
  653.             end)
  654.         end
  655.  
  656.         progressBar.value = math.floor(i / #downloadList * 100)
  657.         workspace:draw()
  658.     end
  659.  
  660.     -- Saving system versions
  661.     switchProxy(function()
  662.         filesystem.writeTable(paths.system.versions, versions, true)
  663.     end)
  664.  
  665.     -- Done info
  666.     layout:removeChildren()
  667.     addImage(1, 1, "Done")
  668.     addTitle(0x969696, localization.installed)
  669.     addStageButton(localization.reboot).onTouch = function()
  670.         computer.shutdown(true)
  671.     end
  672.     workspace:draw()
  673.  
  674.     -- Removing temporary installer directory
  675.     temporaryFilesystemProxy.remove(installerPath)
  676. end)
  677.  
  678. --------------------------------------------------------------------------------
  679.  
  680. loadStage()
  681. workspace:start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement