· last year · May 10, 2024, 11:40 PM
1--The startup which checks for updates and whether it's using OpenOS or MineOS
2local status, compat = pcall(require,"Compat")
3if not status then --auto assume system is OpenOS because MineOS should autoinstall it
4 print("Installing Compatability layer")
5 os.execute("wget -f https://raw.githubusercontent.com/cadergator10/Opencomputers-serpentine/main/database/Compat.lua Compat.lua")
6 compat = require("Compat")
7end
8local mainPage = "https://cadespc.com/servertine/modules/"
9local download = mainPage .. "getservertine" --URL used by boot for servertine stuff
10local aRD = compat.isMine and compat.fs.path(compat.system.getCurrentScript()) or "" --path of program
11local config = compat.loadTable(aRD .. "bootconfig.txt") --boot configuration
12local term = not compat.isMine and require("term") or nil --nil if MineOS, is term API if OpenOS
13--openOSReq are library files for GUI and GUI API + JSON
14local openOSReq = {["JSON.lua"]="https://github.com/IgorTimofeev/MineOS/raw/master/Libraries/JSON.lua",["GUI.lua"]="https://raw.githubusercontent.com/cadergator10/Opencomputers-serpentine/main/database/GUI.lua",["advancedLua.lua"]="https://github.com/IgorTimofeev/AdvancedLua/raw/master/AdvancedLua.lua",["color.lua"]="https://github.com/IgorTimofeev/Color/raw/master/Color.lua",["doubleBuffering.lua"]="https://github.com/IgorTimofeev/DoubleBuffering/raw/master/DoubleBuffering.lua",["image.lua"]="https://github.com/IgorTimofeev/Image/raw/master/Image.lua",["OCIF.lua"]="https://github.com/IgorTimofeev/Image/raw/master/OCIF.lua"}
15
16if not compat.isMine then --Should, if OpenOS, install all dependencies.
17 local status, _ = pcall(require,"GUI") --Check if GUI API exists. Otherwise, download it.
18 if not status then
19 for key,value in pairs(openOSReq) do
20 print("Installing " .. key)
21 compat.internet.download(value,"/lib/" .. key)
22 --os.execute("wget -f " .. value .. " /lib/" .. key) --(getting rid of wget execute in favor of actual compat downloader)
23 end
24 os.execute("mkdir /lib/FormatModules")
25 print("Installing OCIF in FormatModules folder") --OCIF must be in this folder for Image library to work.
26 compat.internet.download("https://github.com/IgorTimofeev/Image/raw/master/OCIF.lua","/lib/FormatModules/OCIF.lua")
27 end
28end
29
30local GUI = require("GUI")
31local JSON = require("JSON")
32
33--libs that get filled in future
34local errHan
35
36local didError = false --If error handler detects error, then clearScreen() doesn't clear the screen
37
38local arg = ...
39if arg ~= nil then --If someone inputs args, it prints it out.
40 print(arg)
41end
42
43local function split(s, delimiter) --splits string ("hello,world,yeah") into table {"hello","world","yeah"}
44 local result = {}
45 for match in (s..delimiter):gmatch("(.-)"..delimiter) do
46 table.insert(result, match)
47 end
48 return result
49 end
50
51local function installer(version, bootver) --asks user input and stuff, plus installs all files from my website
52 local install = false
53 local saveBoot = true
54 local isConfig = config == nil
55 if config == nil then --create boot config.
56 config = {["version"] = -1,["bootver"] = -1,["checkVersion"]=true,["lang"]="English",["shutdownonexit"]=true,["startupParams"]={},["anonymousReport"]=true}--startupParams are one-time keys to do stuff, usually done by the database itself.
57 saveBoot = true
58 install = true
59 GUI.alert("By default, anonymous reporting is enabled. If enabled it will automatically send any crashes or errors caused by the system or a module to the developer/owner. You can change this in bootconfig.txt file")
60 elseif config.bootver == nil then
61 config.bootver = -1
62 saveBoot = true
63 install = true
64 end
65 local style = {bottomButton = 0xFFFFFF, bottomText = 0x555555, bottomSelectButton = 0x880000, bottomSelectText = 0xFFFFFF}
66 if compat.isMine then --is MineOS
67 --TODO: Debug if OpenOS version works, then create MineOS one
68 --compat.system.addWindow(0xE1E1E1)
69 if isConfig then
70 GUI.alert("New system: Installing servertine") --Force install of system. Doesn't ask whether to install
71 elseif config.bootver == -1 then
72 GUI.alert("Boot files prepping install")
73 else
74 install = -2 --makes sure it waits until user inputs something
75 local workspace = GUI.workspace()
76 local container = GUI.addBackgroundContainer(workspace, true, true, "New version available:" )
77 if version ~= config.version then container.layout:addChild(GUI.label(80,5,16,1, style.bottomText, "Servertine: " .. tostring(config.version) .. " -> " .. tostring(version))) end
78 if bootver ~= config.bootver then container.layout:addChild(GUI.label(80,5,16,1, style.bottomText, "Boot Version: " .. tostring(config.bootver) .. " -> " .. tostring(bootver))) end
79 container.layout:addChild(GUI.button(80,5,16,1,style.bottomButton, style.bottomText, style.bottomSelectButton, style.bottomSelectText, "Install")).onTouch = function()
80 install = true --Install all stuff
81 container:remove()
82 workspace:draw(true)
83 workspace:stop()
84 end
85 container.layout:addChild(GUI.button(80,5,16,1,style.bottomButton, style.bottomText, style.bottomSelectButton, style.bottomSelectText, "Don't Install")).onTouch = function()
86 install = false --don't install
87 container:remove()
88 workspace:draw(true)
89 workspace:stop()
90 end
91 container.layout:addChild(GUI.button(80,5,16,1,style.bottomButton, style.bottomText, style.bottomSelectButton, style.bottomSelectText, "Don't ask again")).onTouch = function()
92 config.checkVersion = false --don't install and don't version check anymore
93 compat.saveTable(config,aRD .. "bootconfig.txt")
94 install = false
95 container:remove()
96 workspace:draw(true)
97 workspace:stop()
98 end
99 container.panel.onTouch = function() --Always install if panel clicked
100 install = true --Install all stuff
101 container:remove()
102 workspace:draw(true)
103 workspace:stop()
104 end
105 workspace:draw(true)
106 workspace:start()
107 end
108 while install == -2 do --repeat until user presses button. TEST: Not tested yet
109 --os.sleep() --may require restart if os.sleep()
110 end
111 if install then
112 local worked, errored = compat.internet.request(download .. "files",nil,{["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36"}) --get file urls from server
113 if worked then --if successful request
114 local tempTable = JSON.decode(worked) --decode JSON to table
115 local aRD = compat.fs.path(compat.system.getCurrentScript()) --get file location
116 local workspace = GUI.workspace()
117 --main stuff
118 local container = GUI.addBackgroundContainer(workspace, true, true, "Setting up folders")
119 workspace:draw(true)
120 local folders = split(tempTable.folders,",") --prep folders? TODO: Fix what's wrong here WHY
121 for _,value in pairs(folders) do
122 if compat.fs.isDirectory(aRD .. value) then --if dir exists, delete it. Then it makes a directory again
123 compat.fs.remove(aRD .. value)
124 end
125 compat.fs.makeDirectory(aRD .. value)
126 end
127 --doing boot stuff first
128 if(bootver ~= config.bootver) then --TODO: Fix version checker if broken & make sure it doesnt use openOSReq when downloading the files
129 --[[if not (compat.isMine) then
130 for key,value in pairs(openOSReq) do --install
131 print("Installing " .. key)
132 compat.internet.download(value,"/lib/" .. key)
133 --os.execute("wget -f " .. value .. " /lib/" .. key) --(getting rid of wget execute in favor of actual compat downloader)
134 end
135 end]] --commented since clearly mineos
136 if compat.fs.isDirectory(aRD .. "BootFiles") then
137 compat.fs.remove(aRD .. "BootFiles")
138 end
139 compat.fs.makeDirectory(aRD .. "BootFiles")
140 for _, value in pairs(tempTable.boot) do
141 if value.type == "boot" and value.noMine == false then
142 container.label.text = "Installing boot file to " .. value.path .. " file from URL: " .. value.url
143 workspace:draw(true)
144 compat.internet.download(value.url,string.sub(value.path,1,1) == "~" and aRD .. string.sub(value.path,2,-1) or value.path)
145 end --Shouldn't need itself overwritten since not OpenOS.
146 end --WHAT AM I THINKING?!? MINEOS HAS ALL BOOT FILES (apart from error checking) TODO: fix the website so it can determine what is only OpenOS and what is for both
147 end
148 --other stuff
149 if(version ~= config.version) then
150
151 for _, value in pairs(tempTable.files) do
152 if value.type == "db" then --Download the required files in all locations
153 container.label.text = "Installing to " .. value.path .. " file from URL: " .. value.url
154 workspace:draw(true)
155 compat.internet.download(value.url,aRD .. value.path)
156 end
157 end
158 end
159 container:remove()
160 workspace:draw(true)
161 config.version = tempTable.version
162 config.bootver = tempTable.bootVer
163 compat.saveTable(config,aRD .. "bootconfig.txt") --update version for version checker
164 loc = compat.system.getLocalization(compat.fs.path(compat.system.getCurrentScript()) .. "Localizations/") --Retrieve localizations in boot loader so 1. available in boot file, and 2. Enabled by default.
165 else
166 error("Failed to download files. Server may be down")
167 end
168 --perform install
169 return true
170 elseif not isConfig then
171 return true
172 else
173 return false
174 end
175 else --OpenOS version
176 term.clear()
177 if isConfig then
178 print("New system: Installing servertine") --force install
179 elseif arg == "--install" then
180 print("Install command received. Reinstalling everything") --if they run the boot and input --install after it, it will install regardless of version check
181 install = true
182 else
183 print("New version for the Servertine Database is available!") --let them choose whether to install
184 if version ~= config.version then print("Database: " .. tostring(config.version) .. " -> " .. tostring(version)) end
185 if bootver ~= config.bootver then print("Boot Files: " .. tostring(config.bootver) .. " -> " .. tostring(bootver)) end
186 print("Would you like to install this version? yes or no\nSome modules may require the new version")
187 local text = term.read():sub(1,-2)
188 while text ~= "yes" and text ~= "no" do
189 print("Invalid input")
190 text = term.read():sub(1,-2)
191 end
192 if text == "yes" then --install new version
193 install = true
194 else --don't
195 print("Do you want the system to remember your decision?")
196 local text = term.read():sub(1,-2)
197 while text ~= "yes" and text ~= "no" do
198 print("Invalid input")
199 text = term.read():sub(1,-2)
200 end
201 if text == "yes" then --skip version checking in future
202 config.checkVersion = false
203 compat.saveTable(config,aRD .. "bootconfig.txt")
204 end
205 end
206 end
207 if install then
208 local worked, errored = compat.internet.request(download .. "files",nil,{["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36"})
209 if worked then
210 local tempTable = JSON.decode(worked) --TODO: Make sure this matches json sent by the server
211 local aRD = compat.fs.path(compat.system.getCurrentScript())
212
213 local folders = split(tempTable.folders,",") --prep folders?
214 for _,value in pairs(folders) do
215 if compat.fs.isDirectory(aRD .. value) then
216 compat.fs.remove(aRD .. value)
217 end --setup folders
218 compat.fs.makeDirectory(aRD .. value)
219 end
220 --doing boot stuff first
221 if(bootver ~= config.bootver) then
222 --[[for key,value in pairs(openOSReq) do --install
223 print("Installing " .. key)
224 compat.internet.download(value,"/lib/" .. key)
225 --os.execute("wget -f " .. value .. " /lib/" .. key) --(getting rid of wget execute in favor of actual compat downloader)
226 end]] --commented out to see if fix
227 if compat.fs.isDirectory(aRD .. "BootFiles") then
228 compat.fs.remove(aRD .. "BootFiles")
229 end
230 compat.fs.makeDirectory(aRD .. "BootFiles")
231 local mainF = null
232 for _, value in pairs(tempTable.boot) do
233 if value.type == "boot" then
234 print("Installing boot file to " .. value.path .. " file from URL: " .. value.url)
235 compat.internet.download(value.url,string.sub(value.path,1,1) == "~" and aRD .. string.sub(value.path,2,-1) or value.path) --Make sure that a "~" allows it to use the local folder rather than global
236 elseif value.type == "bootmain" then
237 mainF = value
238 end
239 end
240 if mainF ~= null then
241 print("Installing main boot program")
242 compat.internet.download(mainF.url, aRD .. "boot.lua")
243 end
244 end
245 --other stuff
246 for _, value in pairs(tempTable.files) do --install files
247 if value.type == "db" then
248 print("Installing to " .. value.path .. " file from URL: " .. value.url)
249 compat.internet.download(value.url,aRD .. value.path)
250 end
251 end
252 config.version = tempTable.version --change version for version checker
253 local goodBoot = bootver ~= config.bootver
254 config.bootver = tempTable.bootVer
255 compat.saveTable(config,aRD .. "bootconfig.txt")
256 if(goodBoot or arg == "--install") then --make sure computer restarts on boot.
257 print("Please restart computer to run new boot")
258 os.sleep(2)
259 os.execute("shutdown")
260 end
261 loc = compat.system.getLocalization(compat.fs.path(compat.system.getCurrentScript()) .. "Localizations/") --Retrieve localizations in boot loader so 1. available in boot file, and 2. Enabled by default.
262 else
263 error("Failed to download files. Server may be down") --failed to connect to server
264 end
265 --perform install
266 return true --true means can run file
267 elseif not isConfig then
268 return true
269 else
270 return false --false means can't run file (not installed likely)
271 end
272 end
273 if saveBoot then --at end in case install fails
274 compat.saveTable(config,aRD .. "bootconfig.txt")
275 end
276end
277
278local function clearScreen() --If OpenOS, clear screen to make better after closing.
279 if not compat.isMine and not didError then
280 if compat.workspace ~= nil then --remove all GUI stuff to see if this fixes bad background
281 compat.window:remove()
282 compat.workspace:draw(true)
283 compat.workspace:stop()
284 compat.window, compat.workspace = nil, nil
285 end
286 term = require("Term")
287 term.clear()
288 if config.shutdownonexit then
289 os.sleep(1) --wait 1 sec
290 os.execute("shutdown")
291 end
292 end
293end
294
295
296if config == nil or arg == "--install" or config.bootver == nil then
297 installer() --If no config or --install key passed after running boot, it runs installer
298elseif arg == "--lib" then
299 for key,value in pairs(openOSReq) do
300 print("Installing " .. key)
301 compat.internet.download(value,"/lib/" .. key)
302 --os.execute("wget -f " .. value .. " /lib/" .. key) --(getting rid of wget execute in favor of actual compat downloader)
303 end
304elseif arg == "--delcompat" then
305 compat.fs.remove(aRD .. "Compat.lua")
306 print("Compat library removed! Can be reinstalled after rebooting pc")
307 os.sleep(3)
308 os.execute("shutdown")
309end
310
311errHan = require("BootFiles/errorhandler")
312local notif = require("BootFiles/notification")
313if config.getNotif == nil then
314 config.getNotif = true
315 compat.saveTable(config,aRD .. "bootconfig.txt")
316end
317errHan.setup(config)
318notif.setup(config)
319
320compat.lang = config.lang --set compat lang file to whatever is in bootconfig (for OpenOS, since no localization stuff works with it.)
321local status, loc = pcall(compat.system.getLocalization(compat.fs.path(compat.system.getCurrentScript()) .. "Localizations/")) --Retrieve localizations in boot loader so 1. available in boot file, and 2. Enabled by default.
322local result, reason = loadfile(compat.fs.path(compat.system.getCurrentScript()) .. "/Database.lua") --check for database program
323if result then --file exists
324 result = compat.fs.path(compat.system.getCurrentScript()) .. "/Database.lua" --set path for dofile()
325 if config.checkVersion then --If version checking is enabled
326 local worked, errored = compat.internet.request(download .. "version",nil,{["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36"})
327 if worked then --If got info from website
328 local tempTable = JSON.decode(worked)
329 if tempTable.success == true and (tempTable.version ~= config.version or tempTable.bootver ~= config.bootver) then --success checking version and version is not the same as one on web (bad version or update to system)
330 local goodToRun = installer(tempTable.version, tempTable.bootver) --run installer
331 if goodToRun then --run program
332 notif.getNotifications() --popup alerts
333 local success, result = pcall(dofile,result)
334 if not success then
335 errHan.erHandle(result)
336 didError = true
337 end
338 clearScreen()
339 end
340 else
341 notif.getNotifications() --popup alerts
342 local success, result = pcall(dofile,result)
343 if not success then
344 errHan.erHandle(result)
345 didError = true
346 end
347 clearScreen()
348 end
349 else --failed to connect to web: run database anyway
350 GUI.alert("Error getting version from website")
351 notif.getNotifications() --popup alerts
352 local success, result = pcall(dofile,result)
353 if not success then
354 errHan.erHandle(result)
355 didError = true
356 end
357 clearScreen()
358 end
359 else --no version checking: only run program
360 notif.getNotifications() --popup alerts
361 local success, result = pcall(dofile,result)
362 if not success then
363 errHan.erHandle(result)
364 didError = true
365 end
366 clearScreen()
367 end
368else --try running installer since db file doesn't exist
369 local goodToRun = installer()
370 if goodToRun then --file should exist now
371 result, reason = loadfile(compat.fs.path(compat.system.getCurrentScript()) .. "/Database.lua")
372 if result then --is loaded, so now can run
373 result = compat.fs.path(compat.system.getCurrentScript()) .. "/Database.lua"
374 notif.getNotifications() --popup alerts
375 local success, result = pcall(dofile,result)
376 if not success then
377 errHan.erHandle(result)
378 didError = true
379 end
380 clearScreen()
381 else --still doesn't exist?
382 error("Failed to run installed program. It'sa makea no sensea")
383 end
384 end
385end