Advertisement
HangMan23

Untitled

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