From 9bba0dbe59beb616195c0ca49590aca60b52de8e Mon Sep 17 00:00:00 2001 From: Bommels05 <69975756+Bommels05@users.noreply.github.com> Date: Thu, 23 Oct 2025 00:21:18 +0200 Subject: [PATCH] Rework installers --- installer/installer.lua | 125 ++---------- mini-installer.lua | 29 +++ real_startup.lua | 268 +++----------------------- stage2-install.lua | 413 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 485 insertions(+), 350 deletions(-) create mode 100644 mini-installer.lua create mode 100644 stage2-install.lua diff --git a/installer/installer.lua b/installer/installer.lua index 1e5aefe..f82dd81 100644 --- a/installer/installer.lua +++ b/installer/installer.lua @@ -1,4 +1,7 @@ local function dothething() +fs.move("tmp/bigfont", "bigfont") +_G.bigfont = loadfile("bigfont",_ENV)() + local function wordwrap(str) local x,y = term.getCursorPos() local tW,tH = term.getSize() @@ -13,7 +16,10 @@ local function wordwrap(str) end end --local ico = lUtils.asset.load("User/Cloud/Images/New_Loading.limg") -- replace with actual filepath later -local f = http.post("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode("LevelOS/assets/loading.limg").."&code="..textutils.urlEncode("lSlb8kZq"),nil).readAll() +fs.move("tmp/LevelOS/assets/loading.limg", "LevelOS/assets/loading.limg") +local file = fs.open("LevelOS/assets/loading.limg") +local f = file.readAll() +file.close() local ico = textutils.unserialize(f) for t=1,#ico do for l=1,#ico[t] do @@ -36,10 +42,6 @@ local function progress() renderIco(frame) term.setCursorPos(icoX+5,icoY+1) term.write(math.floor(prog + 0.5).."% complete") - if badConn then - term.setCursorPos(x, icoY+5) - print("Having trouble connecting, please hang on...") - end os.sleep(0.1) frame = frame+1 if frame > #ico then @@ -64,7 +66,6 @@ local function fwrite(file,content) end -local badConn = false local function render() term.setBackgroundColor(colors.cyan) term.setTextColor(colors.white) @@ -75,7 +76,7 @@ local function render() x = math.floor(x+((w-51)/4)) end term.setCursorPos(x,3) - wordwrap("Installing LevelOS") + wordwrap("Installing BefatorOS") bigfont.bigPrint(" ") local x1,y1 = term.getCursorPos() term.setCursorPos(x,y1+2) @@ -95,114 +96,12 @@ local function events() end end -local hpost = function(...) -while true do -local ret = table.pack(http.post(...)) -if not ret[1] then -badConn = true -render() -os.sleep(0.5) -else -badConn = false -return table.unpack(ret, 1, ret.n) -end -end -end - -local function getField(thing,fieldname) - if string.find(thing,"<"..fieldname..">",1,true) ~= nil and string.find(thing,"",1,true) ~= nil then - begin = nil - ending = nil - trash,begin = string.find(thing,"<"..fieldname..">",1,true) - ending,ending2 = string.find(thing,"",begin+1,true) - if begin ~= nil and ending ~= nil then - return string.sub(thing,begin+1,ending-1),string.sub(thing,1,trash-1)..string.sub(thing,ending2+1,string.len(thing)) - end - end - return nil -end - -local function download(pth) - local f = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode(pth).."&code="..textutils.urlEncode("lSlb8kZq"),{Cookie=userID}).readAll() - if f ~= "409" and f ~= "403" and f ~= "401" then - fwrite(pth,f) - return true - else - return false - end -end - local function downloader() - local package = shapescape.getSlides().package - - local tFiles = 0 - local pack = package.name - if fs.exists("LevelOS/data/settings.lconf") then - local set = textutils.unserialize(fread("LevelOS/data/settings.lconf")) - if set.package then - pack = set.package - end + for i=1,100 do + os.sleep(math.random()) + prog = i end - - local tree = {} - local folders = {} - local function searchFolder(folder) - --print("Searching folder root/"..folder) - local f = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode(folder).."&code="..textutils.urlEncode("lSlb8kZq"),nil).readAll() - --print(f) - local f2 = f - while true do - local file = nil - file,f = getField(f,"file") - if not file then - break - else - local name = getField(file,"name") - local timestamp = getField(file,"timestamp") - timestamp = tonumber(timestamp) - if pack == "Full" or fs.exists(fs.combine(folder,name)) then - tree[fs.combine(folder,name)] = {timestamp=timestamp} - tFiles = tFiles+1 - end - --print("Found "..fs.combine(folder,name)) - end - end - f = f2 - while true do - local file = nil - file,f = getField(f,"folder") - if not file then - break - else - local name = getField(file,"name") - if not fs.exists(fs.combine(folder,name)) then - fs.makeDir(fs.combine(folder,name)) - end - folders[fs.combine(folder,name)] = "" - searchFolder(fs.combine(folder,name)) - end - end - return true - end - - if not searchFolder("") then return false end - - if pack == "Full" then - for k,v in pairs(tree) do - table.insert(package,k) - end - end - - -- check if name is full, if it is then first list the dir then add all the files to the package - for p=1,#package do - prog = ((p-1)/#package)*100 - download(package[p]) - prog = ((p)/#package)*100 - end - local temp = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode("").."&code="..textutils.urlEncode("lSlb8kZq"),{Cookie=userID}).readAll() - local ver = getField(temp,"version") - fwrite("LevelOS/data/version.txt",ver) - fwrite("LevelOS/data/settings.lconf",textutils.serialize({package=pack})) + fs.move("tmp/stage2-install.lua", "real_startup.lua") os.sleep(2) os.reboot() end diff --git a/mini-installer.lua b/mini-installer.lua new file mode 100644 index 0000000..dcebe4d --- /dev/null +++ b/mini-installer.lua @@ -0,0 +1,29 @@ +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/installer/installer.lua tmp/installer.lua") +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/stage2-install.lua tmp/stage2-install.lua") +--Kernel +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/real_startup.lua tmp/real_startup.lua") +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/bigfont tmp/bigfont") +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/assets/loading.limg tmp/LevelOS/assets/loading.limg") +--Core System +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/system.lua tmp/LevelOS/system.lua") +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/startup/lUtils.lua tmp/LevelOS/startup/lUtils.lua") +--Core UI +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/SystemUI.lua tmp/LevelOS/SystemUI.lua") --Sonst Black Screen +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/assets/Compact_Icons.limg tmp/LevelOS/assets/Compact_Icons.limg") --Sonst Crash +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/Login_screen.sgui tmp/LevelOS/Login_screen.sgui") --Sonst freeze beim starten wenn es einen account gibt +--Desktop UI +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/desktop.lua tmp/LevelOS/desktop.lua") --Sonst crash beim anklicken von Uhr oder Start MenĂ¼ +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/assets/Desktop_Icons.limg tmp/LevelOS/assets/Desktop_Icons.limg") --Sonst Crash wie vorher +shell.execute("mkdir Program_Files") --Sonst crash wie vorher +--Core Builtin Programs +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/Task_Manager.lua tmp/LevelOS/Task_Manager.lua") --Sonst freeze beim Task Manager starten +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/LevelOS/Clock.lua tmp/LevelOS/Clock.lua") --Sonst error popup beim klicken auf die Uhr +--Core Applications +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Explorer/main.lua tmp/Program_Files/LevelOS/Explorer/main.lua") --Sonst error popup biem klicken auf My PC +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/blittle tmp/blittle") --Sonst errors im Explorer Window +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Explorer/icon.limg tmp/Program_Files/LevelOS/Explorer/icon.limg") --Sonst kein Explore Shortcut Icon +--Main Applications +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Notepad/main.lua tmp/Program_Files/LevelOS/Notepad/main.lua") --Sonst kein Notepad +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Notepad/icon.limg tmp/Program_Files/LevelOS/Notepad/icon.limg") --Sonst kein Notepad Shortcut Icon +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Lua/main.lua tmp/Program_Files/LevelOS/Lua/main.lua") --Sonst kein Lua +shell.execute("wget https://git.befatorinc.de/Befator-Computing-Systems/ClientOS/raw/branch/main/Program_Files/LevelOS/Lua/icon.limg tmp/Program_Files/LevelOS/Lua/icon.limg") --Sonst kein Lua Shortcut Icon diff --git a/real_startup.lua b/real_startup.lua index f04ffb0..f0869d5 100644 --- a/real_startup.lua +++ b/real_startup.lua @@ -330,7 +330,7 @@ local function bootscreen() elseif fs.exists("LevelOS/assets/logo_pride.limg") then render(textutils.unserialize(fread("LevelOS/assets/logo_pride.limg"))[1],math.ceil(w/2)-4,h/2-8) else - bigfont.writeOn(term.current(),2,"L",nil,h/2-8) + bigfont.writeOn(term.current(),2,"B",nil,h/2-8) end else if fs.exists("LevelOS/assets/logo_christmas.limg") and os.date("%m") == "12" then @@ -338,7 +338,7 @@ local function bootscreen() elseif fs.exists("LevelOS/assets/logo_pride.limg") then render(textutils.unserialize(fread("LevelOS/assets/logo_pride.limg"))[1],math.ceil(w/2)-4,h/2-5) else - bigfont.writeOn(term.current(),2,"L",nil,h/2-5) + bigfont.writeOn(term.current(),2,"B",nil,h/2-5) end end while true do @@ -397,266 +397,60 @@ local function loadIco() end end -local hpost = function(...) - while true do - local ret = table.pack(http.post(...)) - if not ret[1] then - os.sleep(0.5) - else - badConn = false - return table.unpack(ret, 1, ret.n) - end - end -end - -local function getField(thing,fieldname) - if string.find(thing,"<"..fieldname..">",1,true) ~= nil and string.find(thing,"",1,true) ~= nil then - local begin = nil - local ending = nil - local trash,begin = string.find(thing,"<"..fieldname..">",1,true) - local ending,ending2 = string.find(thing,"",begin+1,true) - if begin ~= nil and ending ~= nil then - return string.sub(thing,begin+1,ending-1),string.sub(thing,1,trash-1)..string.sub(thing,ending2+1,string.len(thing)) - end - end - return nil -end - local function download(pth) - local f = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode(pth).."&code="..textutils.urlEncode("lSlb8kZq"),{Cookie=userID}).readAll() - if f ~= "409" and f ~= "403" and f ~= "401" then - if pth == "startup.lua" and f ~= fread(shell.getRunningProgram()) then - fwrite(shell.getRunningProgram(),f) - os.sleep(1) - os.reboot() - end - if pth ~= "startup.lua" then - fwrite(pth,f) - end - return true - else - return false + if fs.getDir(path) ~= "" then + fs.makeDir(fs.getDir(path)) end + + fs.move("tmp/" .. pth, pth) + os.sleep(fs.getSize(pth) / 10000) end local step = 0.05 local function update() bootText = "Connecting to server" os.sleep(step) - local opost = http.post - local ping = http.get("https://os.leveloper.cc/ping.php") - if not ping then - bootText = "Trying HTTP" - os.sleep(step) - local ping2 = http.get("http://os.leveloper.cc/ping.php") - if not ping2 then - bootText = "Starting in offline" - os.sleep(step) - -- no internet - return - end - function http.post(...) - local args = table.pack(...) - local r = table.pack(opost(...)) - if not r[1] and string.find(args[1],"https://",nil,true) == 1 then - args[1] = "http"..string.sub(args[1],6,#args[1]) - return opost(table.unpack(args)) - else - return table.unpack(r) - end - end - local oget = http.get - function http.get(...) - local args = table.pack(...) - local r = table.pack(oget(...)) - if not r[1] and string.find(args[1],"https://",nil,true) == 1 then - args[1] = "http"..string.sub(args[1],6,#args[1]) - return oget(table.unpack(args)) - else - return table.unpack(r) - end - end - hpost = http.post - end - bootText = "Checking client version" os.sleep(step) - local servertimestamp - local clienttimestamp - if fs.exists("LevelOS/data/version.txt") then - clienttimestamp = tonumber(fread("LevelOS/data/version.txt")) - end - if not clienttimestamp then - clienttimestamp = 0 - end bootText = "Looking for updates" os.sleep(step) - local response,err = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode("").."&code="..textutils.urlEncode("lSlb8kZq")) - local res2,err2 - if fs.exists("LevelOS/startup/LevelCloud.lua") then - res2,err2 = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode("").."&code="..textutils.urlEncode("Sm0f1bwQ")) - end - if res2 then - bootText = "Updating LevelCloud" - os.sleep(step) - local f = res2.readAll() - local sTS = tonumber((getField(f,"version"))) or math.huge - local cTS = fs.attributes("LevelOS/startup/LevelCloud.lua").modification or fs.attributes("LevelOS/startup/LevelCloud.lua").modified or 0 - if sTS > cTS then - local f = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode("LevelCloud.lua").."&code="..textutils.urlEncode("Sm0f1bwQ")) - if f then - fwrite("LevelOS/startup/LevelCloud.lua",f.readAll()) - end - end - end bootText = "Processing" os.sleep(step) - if not response then - -- could not connect - --os.sleep(0.5) - -- put "starting in offline mode" - return - end - local f = response.readAll() - servertimestamp = tonumber((getField(f,"version"))) - local tFiles = 0 - local pack = "Full" - if fs.exists("LevelOS/data/settings.lconf") then - local set = textutils.unserialize(fread("LevelOS/data/settings.lconf")) - if set.package then - pack = set.package - end - end - - local tree = {} - local folders = {} - local function searchFolder(folder) - --print("Searching folder root/"..folder) - local f = hpost("https://os.leveloper.cc/sGet.php","path="..textutils.urlEncode(folder).."&code="..textutils.urlEncode("lSlb8kZq")).readAll() - --print(f) - local f2 = f - while true do - local file = nil - file,f = getField(f,"file") - if not file then - break - else - local name = getField(file,"name") - local timestamp = getField(file,"timestamp") - timestamp = tonumber(timestamp) - if pack == "Full" or fs.exists(fs.combine(folder,name)) or folder == "LevelOS/assets" or fs.combine(folder,name) == "startup.lua" then - tree[fs.combine(folder,name)] = {timestamp=timestamp} - tFiles = tFiles+1 - end - --print("Found "..fs.combine(folder,name)) - end - end - f = f2 - while true do - local file = nil - file,f = getField(f,"folder") - if not file then - break - else - local name = getField(file,"name") - if not fs.exists(fs.combine(folder,name)) then - fs.makeDir(fs.combine(folder,name)) - end - folders[fs.combine(folder,name)] = "" - searchFolder(fs.combine(folder,name)) - end - end - return true - end - if servertimestamp > clienttimestamp then - doUpdate = true - local deleteFiles = { - "LevelOS/explorer.lua", - "LevelOS/Pigeon.lua", - "LevelOS/LevelCloud.lua", - "LevelOS/notepad.lua", - "LevelOS/Register.lua", - } - if fs.exists("LevelOS/data/nativelog.txt") then - fs.move("LevelOS/data/nativelog.txt","LevelOS/data/nativelog.lconf") - end - for f=1,#deleteFiles do - if fs.exists(deleteFiles[f]) then - fs.delete(deleteFiles[f]) - end - end - else - bootText = "Checking file integrity" - os.sleep(step) - local icheck = { - --"startup.lua", - "bigfont", - "blittle", - "LevelOS", - "LevelOS/system.lua", - "LevelOS/startup", - "LevelOS/startup/lUtils.lua", - "LevelOS/assets", - "LevelOS/assets/Circle_Symbols.limg", - "LevelOS/assets/circProgress.limg", - "LevelOS/assets/Compact_Icons.limg", - "LevelOS/assets/Desktop_Icons.limg", - "LevelOS/assets/loading.limg", - "LevelOS/assets/logo_pride.limg", - "LevelOS/assets/QR_Code.limg", - "LevelOS/assets/wifi.limg", - "LevelOS/login.lua", - "LevelOS/Changelog.lua", - "LevelOS/lStore.lua", - "LevelOS/SystemUI.lua", - "LevelOS/Task_Manager.lua", - } - local aFiles = {} -- absent files - for f=1,#icheck do - if not fs.exists(icheck[f]) then - table.insert(aFiles,icheck[f]) - end - end - if #aFiles > 0 then - bootText = "Integrity compromised" - os.sleep(0.5) - bootText = "Restoring files" - if not searchFolder("") then return false end - - for f=1,#aFiles do - while not download(aFiles[f]) do - end - end - bootText = "Restarting" - os.sleep(1) - os.reboot() - end - end - if doUpdate then - if not searchFolder("") then return false end + local tree = {} + local timestamp = 0 + tree["LevelOS/system.lua"] = {timestamp=timestamp} + tree["LevelOS/startup/lUtils.lua"] = {timestamp=timestamp} + tree["LevelOS/SystemUI.lua"] = {timestamp=timestamp} + tree["LevelOS/assets/Compact_Icons.limg"] = {timestamp=timestamp} + tree["LevelOS/Login_screen.sgui"] = {timestamp=timestamp} + tree["LevelOS/desktop.lua"] = {timestamp=timestamp} + tree["LevelOS/assets/Desktop_Icons.limg"] = {timestamp=timestamp} + tree["LevelOS/Task_Manager.lua"] = {timestamp=timestamp} + tree["LevelOS/Clock.lua"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Explorer/main.lua"] = {timestamp=timestamp} + tree["blittle"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Explorer/icon.limg"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Notepad/main.lua"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Notepad/icon.limg"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Lua/main.lua"] = {timestamp=timestamp} + tree["Program_Files/LevelOS/Lua/icon.limg"] = {timestamp=timestamp} + local tFiles = #tree - if tree["startup.lua"] then - download("startup.lua") - end + + if not fs.exists("LevelOS/data/version.txt") then + if not searchFolder("") then return false end for k,v in pairs(tree) do if download(k,root,v.timestamp) == true then progress = progress+(100/tFiles) end end - fwrite("LevelOS/data/version.txt",tostring(servertimestamp)) + fwrite("LevelOS/data/version.txt", "Befator Inc") + fs.delete("tmp") os.sleep(1) os.reboot() end - if not fs.exists("LevelOS/assets/wifi.limg") then - folders["LevelOS/assets"] = "" - if not searchFolder("LevelOS/assets") then return false end - for k,v in pairs(tree) do - if download(k) == true then - end - end - end bootText = "Loading system" os.sleep(step) end diff --git a/stage2-install.lua b/stage2-install.lua new file mode 100644 index 0000000..b35626f --- /dev/null +++ b/stage2-install.lua @@ -0,0 +1,413 @@ +-- LevelOS + +term.clear() +term.setCursorPos(1,1) + +if not fs.exists("LevelOS") then + --Let the bios know the system is broken + fs.delete("/real_startup.lua") + os.reboot() + return +end +for k,v in pairs(colors) do + if type(v) == "number" then + term.setPaletteColor(v,term.native().getPaletteColor(v)) + end +end + +if lOS then + error("LevelOS is already running, silly!") +end + +_G.lOS = {} +lOS.path = shell.getRunningProgram() + + +local chunkSize = 32768 +if jit then + chunkSize = 4092 +end + +local function encodeUTF8(asciiText) + local utf8Text = "" + + for i=1, #asciiText, chunkSize do + utf8Text = utf8Text..utf8.char(string.byte(asciiText, i, math.min(i + (chunkSize-1), #asciiText))) + end + + return utf8Text +end + +local function decodeUTF8(utf8Text) + local asciiText = "" + + local ok, t = pcall(function() + return string.char(utf8.codepoint(utf8Text, 1, #utf8Text)) + end) + + if ok then + asciiText = t + else + local ok2, err = pcall(function() + for _, codepoint in utf8.codes(utf8Text) do + if codepoint < 256 then + asciiText = asciiText .. string.char(codepoint) + else + asciiText = asciiText .. "?" + end + end + end) + + if not ok2 then + _G.debugCurrentText = asciiText + _G.debugTextInput = utf8Text + + error(err, 2) + end + end + + return asciiText +end + + +local function encodeAll(...) + local tbl = table.pack(...) + for k,v in pairs(tbl) do + if type(v) == "string" and not utf8.len(v) then + tbl[k] = encodeUTF8(v) + end + end + + return table.unpack(tbl, 1, tbl.n) +end + +local function decodeAll(...) + local tbl = table.pack(...) + for k,v in pairs(tbl) do + if type(v) == "string" then + tbl[k] = decodeUTF8(v) + end + end + + return table.unpack(tbl, 1, tbl.n) +end + +lOS.utf8 = { + decode = decodeUTF8, + encode = encodeUTF8, + decodeAll = decodeAll, + encodeAll = encodeAll, +} + +local function extractVersion(str) + local version = str:match("ComputerCraft (%d+%.%d+%.%d+)") + return version +end + +local function isVersionAbove(version1, version2) + local function splitVersion(version) + local parts = {} + for part in version:gmatch("(%d+)") do + table.insert(parts, tonumber(part)) + end + return parts + end + + local v1Parts = splitVersion(version1) + local v2Parts = splitVersion(version2) + + for i = 1, math.max(#v1Parts, #v2Parts) do + local v1 = v1Parts[i] or 0 + local v2 = v2Parts[i] or 0 + if v1 > v2 then + return true + elseif v1 < v2 then + return false + end + end + + return true -- They are equal if all parts are equal +end + +if isVersionAbove(extractVersion(_HOST), "1.109") then + local fopen = fs.open + + function fs.open(path, mode) + local f = fopen(path, mode) + if not f then return nil end + + local customHandle = {} + + for k,v in pairs(f) do + if mode:find("b") then + customHandle[k] = function(...) return v(...) end + else + customHandle[k] = function(...) return decodeAll(v(encodeAll(...))) end + end + end + + return customHandle + end +end + + +--enable mouse if no color +if not rtype then + _G.rtype = type + _G.type = function(obj) + local mt = getmetatable(obj) + if rtype(mt) == "table" and mt.__type then + if rtype(mt.__type) == "string" then + return mt.__type + elseif rtype(mt.__type) == "function" then + return mt.__type(obj) + end + else + return rtype(obj) + end + end +end + +function _G.pairs(t) + local mt = getmetatable(t) + if mt and type(mt.__pairs) == "function" then + return mt.__pairs(t) + else + return next, t, nil + end +end + +if not hardreboot then + _G.hardreboot = os.reboot +end + +if fs.combine("a","b","c") == fs.combine("a","b") then + local ocombine = fs.combine + function fs.combine(path,...) + local parts = {...} + for p=1,#parts do + path = ocombine(path,parts[p]) + end + return path + end +end + +local w,h = term.getSize() +if h < 19 then return end +local newwin = false + +local therealOGterm = term.current() +local function tokenise( ... ) + local sLine = table.concat( { ... }, " " ) + local tWords = {} + local bQuoted = false + for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do + if bQuoted then + table.insert( tWords, match ) + else + for m in string.gmatch( match, "[^ \t]+" ) do + table.insert( tWords, m ) + end + end + bQuoted = not bQuoted + end + return tWords +end + +if fs.exists("AppData") == false then + fs.makeDir("AppData") +end + +if fs.exists("User") == false then + fs.makeDir("User") + fs.makeDir("User/Documents") + fs.makeDir("User/Images") + fs.makeDir("User/Scripts") + fs.makeDir("User/Downloads") +end + +if not fs.exists("bigfont") then + --Let the bios know the system is broken + fs.delete("/real_startup.lua") + os.reboot() + return +end + +local to_colors, to_blit = {}, {} +for i = 1, 16 do + to_blit[2^(i-1)] = ("0123456789abcdef"):sub(i, i) + to_colors[("0123456789abcdef"):sub(i, i)] = 2^(i-1) +end + + + +local function toColor(theblit) + return to_colors[theblit] or nil +end + + + +local function toBlit(thecolor) + return to_blit[thecolor] or nil +end + +local function render(spr,x,y) + local format = "lImg" + if format == "lImg" then + local sW,sH = #spr[1][1],#spr + local w,h = term.getSize() + for l=1,#spr do + if not y then + term.setCursorPos(math.ceil(w/2)-math.floor(sW/2),(math.ceil(h/2)-math.floor(sH/2)+(l-1))+x) + else + term.setCursorPos(x,y+(l-1)) + end + local bl = {} + bl[1] = spr[l][1] + bl[2] = string.gsub(spr[l][2],"T",toBlit(term.getBackgroundColor())) + bl[3] = string.gsub(spr[l][3],"T",toBlit(term.getBackgroundColor())) + term.blit(unpack(bl)) + end + elseif format == "nfp" or format == "nfg" then + local b,e = string.find(spr,"\n") + local sW,sH + local w,h = term.getSize() + local lines,sW = getLines(spr) + sH = #lines + for l=1,sH do + term.setCursorPos(math.ceil(w/2)-math.floor(sW/2),math.ceil(h/2)-math.floor(sH/2)+(l-1)) + term.blit(string.rep(" ",#lines[l]),lines[l],lines[l]) + end + end +end + + +local function fread(file) + local f = fs.open(file,"r") + local o = f.readAll() + f.close() + return o +end + +local function fwrite(file,content) + local f = fs.open(file,"w") + f.write(content) + f.close() + return true +end + +local loadingico = textutils.unserialize(fread("LevelOS/assets/loading.limg")) + + +_G.bigfont = loadfile("bigfont",_ENV)() + + +local progress = 0 + +local function centerText(text,customY,customLen) -- i tried to put indentation but pastebin is being stupid for some reason + local x,y = term.getSize() + local x2,y2 = term.getCursorPos() + if customY then y2 = customY end + local len = customLen or text:len() + term.setCursorPos((math.ceil(x / 2) - math.floor(len / 2)), y2) + term.write(text) + term.setCursorPos(x2,y2+1) +end + +local doUpdate +local bootText = "Initializing" +local dots = 1 +local frame = 1 + +local function bootscreen() + term.setBackgroundColor(colors.black) + term.setTextColor(colors.cyan) + term.clear() + local w,h = term.getSize() + if h > 19 then + if fs.exists("LevelOS/assets/logo_christmas.limg") and os.date("%m") == "12" then + render(textutils.unserialize(fread("LevelOS/assets/logo_christmas.limg"))[1],math.ceil(w/2)-4,h/2-8) + elseif fs.exists("LevelOS/assets/logo_pride.limg") then + render(textutils.unserialize(fread("LevelOS/assets/logo_pride.limg"))[1],math.ceil(w/2)-4,h/2-8) + else + bigfont.writeOn(term.current(),2,"B",nil,h/2-8) + end + else + if fs.exists("LevelOS/assets/logo_christmas.limg") and os.date("%m") == "12" then + render(textutils.unserialize(fread("LevelOS/assets/logo_christmas.limg"))[1],math.ceil(w/2)-4,h/2-5) + elseif fs.exists("LevelOS/assets/logo_pride.limg") then + render(textutils.unserialize(fread("LevelOS/assets/logo_pride.limg"))[1],math.ceil(w/2)-4,h/2-5) + else + bigfont.writeOn(term.current(),2,"B",nil,h/2-5) + end + end + while true do + if doUpdate then + term.setBackgroundColor(colors.blue) + term.setTextColor(colors.white) + term.clear() + local w,h = term.getSize() + term.setCursorPos(1,math.ceil(h/2)) + centerText("Getting ready for updates") + centerText("Do not turn off your computer") + local init = false + while true do + render(loadingico[frame],-5) + if progress > 0 then + if not init then + term.setBackgroundColor(colors.blue) + term.setTextColor(colors.white) + term.clear() + render(loadingico[frame],-5) + init = true + end + term.setCursorPos(1,math.ceil(h/2)) + centerText("Working on updates") + centerText(math.floor(progress + 0.5).."% complete") + centerText("Do not turn off your computer") + end + frame = frame+1 + if frame > #loadingico then + frame = 1 + end + os.sleep(0.1) + end + end + if h > 19 then + render(loadingico[frame],10) + if bootText then + centerText(" "..bootText..string.rep(".",dots).." ",h/2+14,#(" "..bootText.." ")) + end + else + render(loadingico[frame],7) + end + os.pullEvent() + end +end + +local function loadIco() + while true do + frame = frame+1 + if frame > #loadingico then + frame = 1 + end + dots = dots+0.5 + if dots > 3 then dots = 0 end + os.sleep(0.1) + end +end + +local function update() + os.sleep(2) + doUpdate = true + os.sleep(5) + download("startup.lua") + fs.delete("real_startup.lua") + fs.move("tmp/real_startup.lua", "real_startup.lua") + fs.move("LevelOS/startup/lUtils.lua", "tmp/LevelOS/startup/lUtils.lua") + os.sleep(1) + os.reboot() +end + + +parallel.waitForAny(update,bootscreen,loadIco) \ No newline at end of file