e
This commit is contained in:
89
AceVM/components/Venv.lua
Normal file
89
AceVM/components/Venv.lua
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
local function deepcopy(orig, copies)
|
||||||
|
copies = copies or {}
|
||||||
|
|
||||||
|
if type(orig) ~= 'table' then
|
||||||
|
return orig
|
||||||
|
elseif copies[orig] then
|
||||||
|
return copies[orig]
|
||||||
|
end
|
||||||
|
|
||||||
|
local copy = {}
|
||||||
|
copies[orig] = copy
|
||||||
|
|
||||||
|
for k, v in next, orig, nil do
|
||||||
|
local copied_key = deepcopy(k, copies)
|
||||||
|
local copied_val = deepcopy(v, copies)
|
||||||
|
copy[copied_key] = copied_val
|
||||||
|
end
|
||||||
|
|
||||||
|
return copy
|
||||||
|
end
|
||||||
|
|
||||||
|
local _VG=deepcopy(_G)
|
||||||
|
local lua = {
|
||||||
|
coroutine = true,
|
||||||
|
debug = true,
|
||||||
|
_HOST = true,
|
||||||
|
_VERSION = true,
|
||||||
|
assert = true,
|
||||||
|
collectgarbage = true,
|
||||||
|
error = true,
|
||||||
|
gcinfo = true,
|
||||||
|
getfenv = true,
|
||||||
|
getmetatable = true,
|
||||||
|
ipairs = true,
|
||||||
|
__inext = true,
|
||||||
|
load = true,
|
||||||
|
math = true,
|
||||||
|
next = true,
|
||||||
|
pairs = true,
|
||||||
|
pcall = true,
|
||||||
|
rawequal = true,
|
||||||
|
rawget = true,
|
||||||
|
rawlen = true,
|
||||||
|
rawset = true,
|
||||||
|
select = true,
|
||||||
|
setfenv = true,
|
||||||
|
setmetatable = true,
|
||||||
|
string = true,
|
||||||
|
table = true,
|
||||||
|
tonumber = true,
|
||||||
|
tostring = true,
|
||||||
|
type = true,
|
||||||
|
xpcall = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for i,v in pairs(_VG) do
|
||||||
|
if not lua[i] then
|
||||||
|
_VG[i]=nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_VG._G=_VG
|
||||||
|
|
||||||
|
_VG.component={}
|
||||||
|
function _VG.component.list()
|
||||||
|
local i = 0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
if aceVM.INTERNAL_COMPONENT_REGESTRY[i] then
|
||||||
|
return aceVM.INTERNAL_COMPONENT_REGESTRY[i]["type"], aceVM.INTERNAL_COMPONENT_REGESTRY[i]["object"]
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function _VG.component.getFirst(type)
|
||||||
|
local object={}
|
||||||
|
for i,v in pairs(aceVM.INTERNAL_COMPONENT_REGESTRY) do
|
||||||
|
if aceVM.INTERNAL_COMPONENT_REGESTRY[i].type == type then
|
||||||
|
object=aceVM.INTERNAL_COMPONENT_REGESTRY[i]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return object["object"]
|
||||||
|
end
|
||||||
|
|
||||||
|
function aceVM.initVenv()
|
||||||
|
aceVM._VG = deepcopy(_VG)
|
||||||
|
end
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
local object = {}
|
local object = {}
|
||||||
local file = fs.open("/computers/0/bios.lua", "r")
|
local bios = ""
|
||||||
local bios = file.readAll()
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
function object.getData()
|
function object.getData()
|
||||||
return bios
|
return bios
|
||||||
@@ -12,8 +10,14 @@ function object.setData(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function object.saveData()
|
function object.saveData()
|
||||||
local file=fs.open("/bios.lua", "w")
|
local file=fs.open("/AceVM/computers/"..tostring(aceVM.id).."/bios.lua", "w")
|
||||||
file.write(bios)
|
file.write(bios)
|
||||||
|
file.close()
|
||||||
end
|
end
|
||||||
|
|
||||||
newComponent("bios", object)
|
function aceVM.components.bios(id)
|
||||||
|
local file = fs.open("/AceVM/computers/"..tostring(id).."/bios.lua", "r")
|
||||||
|
bios = file.readAll()
|
||||||
|
file.close()
|
||||||
|
aceVM.newComponent("bios", object)
|
||||||
|
end
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
local object = {}
|
local object = {}
|
||||||
local file = fs.open("/computers/0/nvram.dat", "r")
|
local nvram = {}
|
||||||
local nvram = string.split(file.readAll(), "\n")
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
function object.getMachineEvent()
|
function object.getMachineEvent()
|
||||||
if INTERNAL_EVENT_QUEUE[1]==nil then
|
if INTERNAL_EVENT_QUEUE[1]==nil then
|
||||||
@@ -30,7 +28,7 @@ function object.setData(addr, data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function object.saveData()
|
function object.saveData()
|
||||||
local file=fs.open("/nvram.dat", "w")
|
local file=fs.open("/AceVM/computers/"..tostring(aceVM.id).."/nvram.dat", "w")
|
||||||
file.write(table.concat(nvram,"\n"))
|
file.write(table.concat(nvram,"\n"))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,4 +37,9 @@ object.shutdown=os.shutdown
|
|||||||
|
|
||||||
function object.beep() end -- IDK how i should implement this
|
function object.beep() end -- IDK how i should implement this
|
||||||
|
|
||||||
newComponent("computer", object)
|
function aceVM.components.computer(id)
|
||||||
|
local file = fs.open("/AceVM/computers/"..tostring(id).."/nvram.dat", "r")
|
||||||
|
nvram = string.split(file.readAll(), "\n")
|
||||||
|
file.close()
|
||||||
|
aceVM.newComponent("computer", object)
|
||||||
|
end
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
local fss = {}
|
local fss = {}
|
||||||
local object = {}
|
local object = {}
|
||||||
local uObject = {}
|
local uObject = {}
|
||||||
@@ -119,42 +120,37 @@ function uObject:getSize()
|
|||||||
return #data
|
return #data
|
||||||
end
|
end
|
||||||
|
|
||||||
local function findDisks(tble)
|
function aceVM.initDisks(tble)
|
||||||
for i,v in ipairs(tble) do
|
for i,v in ipairs(tble) do
|
||||||
if fs.exists("/disks/"..tostring(v).."h") then
|
if fs.exists("/AceVM/disks/"..tostring(v).."h") then
|
||||||
local obj = deepcopy(object)
|
local obj = deepcopy(object)
|
||||||
obj.__UDATA_id=v
|
obj.__UDATA_id=v
|
||||||
obj.id="disk_"..tostring(v)
|
obj.id="disk_"..tostring(v)
|
||||||
obj.type="hdd"
|
obj.type="hdd"
|
||||||
newComponent("disk", obj)
|
aceVM.newComponent("disk", obj)
|
||||||
fss[tostring(v)]="/disks/"..tostring(v).."h/"
|
fss[tostring(v)]="/AceVM/disks/"..tostring(v).."h/"
|
||||||
elseif fs.exists("/disks/"..tostring(v).."f") then
|
elseif fs.exists("/AceVM/disks/"..tostring(v).."f") then
|
||||||
local obj = deepcopy(object)
|
local obj = deepcopy(object)
|
||||||
obj.__UDATA_id=v
|
obj.__UDATA_id=v
|
||||||
obj.id="disk_"..tostring(v)
|
obj.id="disk_"..tostring(v)
|
||||||
obj.type="fdd"
|
obj.type="fdd"
|
||||||
newComponent("disk", obj)
|
aceVM.newComponent("disk", obj)
|
||||||
fss[tostring(v)]="/disks/"..tostring(v).."f/"
|
fss[tostring(v)]="/AceVM/disks/"..tostring(v).."f/"
|
||||||
elseif fs.exists("/disks/"..tostring(v).."u") then
|
elseif fs.exists("/AceVM/disks/"..tostring(v).."u") then
|
||||||
local obj = deepcopy(uObject)
|
local obj = deepcopy(uObject)
|
||||||
obj.__UDATA_id=v
|
obj.__UDATA_id=v
|
||||||
obj.id="disk_"..tostring(v)
|
obj.id="disk_"..tostring(v)
|
||||||
obj.type="udd"
|
obj.type="udd"
|
||||||
newComponent("disk", obj)
|
aceVM.newComponent("disk", obj)
|
||||||
fss[tostring(v)]="/disks/"..tostring(v).."u"
|
fss[tostring(v)]="/AceVM/disks/"..tostring(v).."u"
|
||||||
else
|
else
|
||||||
fs.makeDir("/disks/"..tostring(v).."f/")
|
fs.makeDir("/AceVM/disks/"..tostring(v).."f/")
|
||||||
local obj = deepcopy(object)
|
local obj = deepcopy(object)
|
||||||
obj.__UDATA_id=v
|
obj.__UDATA_id=v
|
||||||
obj.id="disk_"..tostring(v)
|
obj.id="disk_"..tostring(v)
|
||||||
obj.type="fdd"
|
obj.type="fdd"
|
||||||
newComponent("disk", obj)
|
aceVM.newComponent("disk", obj)
|
||||||
fss[tostring(v)]="/disks/"..tostring(v).."f/"
|
fss[tostring(v)]="/AceVM/disks/"..tostring(v).."f/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local file = fs.open("/computers/0/computer.ltable", "r")
|
|
||||||
local config = load("return "..file.readAll())()
|
|
||||||
file.close()
|
|
||||||
findDisks(config.disks)
|
|
||||||
@@ -1,28 +1,7 @@
|
|||||||
local internet = {}
|
local internet = {}
|
||||||
|
|
||||||
local function wrap_request(_url, ...)
|
function internet.get(url) return http.get(url).readAll() end
|
||||||
local ok, err = http.request(...)
|
|
||||||
if ok then
|
|
||||||
while true do
|
|
||||||
local event, param1, param2, param3 = coroutine.yield()
|
|
||||||
if event == "http_success" and param1 == _url then
|
|
||||||
return param2
|
|
||||||
elseif event == "http_failure" and param1 == _url then
|
|
||||||
return nil, param2, param3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get(_url)
|
function aceVM.components.internet(id)
|
||||||
if type(_url) ~= "string" then
|
aceVM.newComponent("internet", internet)
|
||||||
error("URL must be a string")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return wrap_request(_url, _url)
|
|
||||||
end
|
|
||||||
|
|
||||||
function internet.get(url) return get(url).readAll() end
|
|
||||||
|
|
||||||
newComponent("internet", internet)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
akeys = {}
|
|
||||||
akeys[keys.enter] = "\n"
|
|
||||||
akeys[keys.tab] = "\t"
|
|
||||||
akeys[keys.backspace] = "\b"
|
|
||||||
@@ -1,90 +1,13 @@
|
|||||||
local screen = {}
|
local screen = {}
|
||||||
|
|
||||||
function write(sText)
|
function screen.printInline(...)
|
||||||
local w, h = term.getSize()
|
term.write(table.concat({...}, " "))
|
||||||
local x, y = term.getCursorPos()
|
|
||||||
|
|
||||||
local nLinesPrinted = 0
|
|
||||||
local function newLine()
|
|
||||||
if y + 1 <= h then
|
|
||||||
term.setCursorPos(1, y + 1)
|
|
||||||
else
|
|
||||||
term.setCursorPos(1, h)
|
|
||||||
term.scroll(1)
|
|
||||||
end
|
|
||||||
x, y = term.getCursorPos()
|
|
||||||
nLinesPrinted = nLinesPrinted + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
sText = tostring(sText)
|
|
||||||
while #sText > 0 do
|
|
||||||
local whitespace = string.match(sText, "^[ \t]+")
|
|
||||||
if whitespace then
|
|
||||||
term.write(whitespace)
|
|
||||||
x, y = term.getCursorPos()
|
|
||||||
sText = string.sub(sText, #whitespace + 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
local newline = string.match(sText, "^\n")
|
|
||||||
if newline then
|
|
||||||
newLine()
|
|
||||||
sText = string.sub(sText, 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
local text = string.match(sText, "^[^ \t\n]+")
|
|
||||||
if text then
|
|
||||||
sText = string.sub(sText, #text + 1)
|
|
||||||
if #text > w then
|
|
||||||
while #text > 0 do
|
|
||||||
if x > w then
|
|
||||||
newLine()
|
|
||||||
end
|
|
||||||
term.write(text)
|
|
||||||
text = string.sub(text, w - x + 2)
|
|
||||||
x, y = term.getCursorPos()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if x + #text - 1 > w then
|
|
||||||
newLine()
|
|
||||||
end
|
|
||||||
term.write(text)
|
|
||||||
x, y = term.getCursorPos()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nLinesPrinted
|
|
||||||
end
|
|
||||||
|
|
||||||
function print(...)
|
|
||||||
local nLinesPrinted = 0
|
|
||||||
local nLimit = select("#", ...)
|
|
||||||
for n = 1, nLimit do
|
|
||||||
local s = tostring(select(n, ...))
|
|
||||||
if n < nLimit then
|
|
||||||
s = s .. "\t"
|
|
||||||
end
|
|
||||||
nLinesPrinted = nLinesPrinted + write(s)
|
|
||||||
end
|
|
||||||
nLinesPrinted = nLinesPrinted + write("\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function screen.print(...)
|
function screen.print(...)
|
||||||
print(...)
|
print(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function printInline(...)
|
|
||||||
local nLinesPrinted = 0
|
|
||||||
local nLimit = select("#", ...)
|
|
||||||
for n = 1, nLimit do
|
|
||||||
local s = tostring(select(n, ...))
|
|
||||||
nLinesPrinted = nLinesPrinted + write(s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function screen.printInline(...)
|
|
||||||
printInline(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function screen.clear()
|
function screen.clear()
|
||||||
term.setCursorPos(1,1)
|
term.setCursorPos(1,1)
|
||||||
term.clear()
|
term.clear()
|
||||||
@@ -93,4 +16,6 @@ end
|
|||||||
screen.id = "screen_1"
|
screen.id = "screen_1"
|
||||||
screen.__UDATA_ID = 1
|
screen.__UDATA_ID = 1
|
||||||
|
|
||||||
newComponent("screen", screen)
|
function aceVM.components.screen(id)
|
||||||
|
aceVM.newComponent("screen", screen)
|
||||||
|
end
|
||||||
183
AceVM/computers/0/bios.lua
Normal file
183
AceVM/computers/0/bios.lua
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
local computer = component.getFirst("computer")
|
||||||
|
local screen=component.getFirst("screen")
|
||||||
|
|
||||||
|
if not screen then
|
||||||
|
local function e(...)end
|
||||||
|
screen = {
|
||||||
|
print=e,
|
||||||
|
printInline=e,
|
||||||
|
clear=e
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok,err = xpcall(function()
|
||||||
|
-- Init components
|
||||||
|
_G._DEVELOPMENT=true
|
||||||
|
_G.component=component
|
||||||
|
|
||||||
|
local printed=""
|
||||||
|
local print=function(text)
|
||||||
|
printed=printed..text.."\n"
|
||||||
|
screen.print(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get CFG
|
||||||
|
local biosCfg = {}
|
||||||
|
local i=1
|
||||||
|
while i<=256 do
|
||||||
|
biosCfg[i]=computer.getData(i) or ""
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
-- Difine functions
|
||||||
|
local function copy(tabl)
|
||||||
|
local out = {}
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
local t=type(v)
|
||||||
|
if t=="table" then
|
||||||
|
if i == "_G" then
|
||||||
|
out._G=out
|
||||||
|
else
|
||||||
|
out[i]=copy(v)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
out[i]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function save(table)
|
||||||
|
while i<=256 do
|
||||||
|
computer.setData(i, table[i] or nil)
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function hasKey(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if i==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Start boot seq
|
||||||
|
local disks={}
|
||||||
|
for i,v in component.list() do
|
||||||
|
if i=="disk" then
|
||||||
|
disks[v.id]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local idx = 1
|
||||||
|
local bootOption=1
|
||||||
|
while true do
|
||||||
|
if biosCfg[idx]=="$EOF" then break end
|
||||||
|
print("Atempting boot option "..tostring(bootOption).." labled \""..biosCfg[idx].."\".")
|
||||||
|
bootOption=bootOption+1
|
||||||
|
local drive={}
|
||||||
|
idx=idx+1
|
||||||
|
if not hasKey(disks,biosCfg[idx]) then
|
||||||
|
print("└─ Drive not found.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+3
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
drive=disks[biosCfg[idx] ]
|
||||||
|
print("├─ Drive found with id of \""..drive.id.."\"")
|
||||||
|
end
|
||||||
|
idx=idx+1
|
||||||
|
local path
|
||||||
|
local code
|
||||||
|
if drive.type=="udd" then
|
||||||
|
print("├─ Drive is Unmanaged, looking for MBR...")
|
||||||
|
sleep(0.02)
|
||||||
|
print("├─ Reading MBR...")
|
||||||
|
local tmp = drive.readBytes(0,512)
|
||||||
|
print("├─ MBR found, compiling bootloader...")
|
||||||
|
code = table.concat(tmp)
|
||||||
|
else
|
||||||
|
if not drive:fileExists(biosCfg[idx]) then
|
||||||
|
print("└─ Path not found.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+2
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
print("├─ Kernel exists at path \""..biosCfg[idx].."\"")
|
||||||
|
path=biosCfg[idx]
|
||||||
|
end
|
||||||
|
code = drive:open(path).read()
|
||||||
|
end
|
||||||
|
idx=idx+1
|
||||||
|
local _VG=copy(_G)
|
||||||
|
_VG._G=_VG
|
||||||
|
print("├─ Created virtual ENV.")
|
||||||
|
local _,func = pcall(load,code,drive.id.." | "..path,nil,_VG)
|
||||||
|
if not func then
|
||||||
|
print("└─ Compilation failure.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+1
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
print("├─ Executing.")
|
||||||
|
end
|
||||||
|
local cmd=biosCfg[idx] or ""
|
||||||
|
idx=idx+1
|
||||||
|
local biosData = {}
|
||||||
|
biosData.bootDrive=drive
|
||||||
|
biosData.term=screen
|
||||||
|
screen.clear()
|
||||||
|
local ok, err = xpcall(func, debug.traceback, biosData, cmd)
|
||||||
|
screen.clear()
|
||||||
|
screen.print(printed)
|
||||||
|
if not ok then
|
||||||
|
print("└─ OS exited with error: "..err)
|
||||||
|
print(" ")
|
||||||
|
else
|
||||||
|
print("└─ OS exited.")
|
||||||
|
print(" ")
|
||||||
|
end
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
::invalid_boot::
|
||||||
|
end
|
||||||
|
computer.beep(400,0.4)
|
||||||
|
print("No boot options available")
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, debug.traceback)
|
||||||
|
if not ok then
|
||||||
|
screen.clear()
|
||||||
|
screen.print("BIOS PANIC: "..err)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
250
AceVM/computers/0/nvram.dat
Normal file
250
AceVM/computers/0/nvram.dat
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
HyperionOS
|
||||||
|
disk_1
|
||||||
|
/boot/Hyprkrnl.sys
|
||||||
|
|
||||||
|
$EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
AceVM/config.ltable
Normal file
1
AceVM/config.ltable
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{["computer"]=0,["disks"]={1}}
|
||||||
2
AceVM/disks/1h/bin_/beep
Normal file
2
AceVM/disks/1h/bin_/beep
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local computer=component.getFirst("computer")
|
||||||
|
computer.beep(800, 0.2, 1)
|
||||||
2
AceVM/disks/1h/bin_/clear
Normal file
2
AceVM/disks/1h/bin_/clear
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local term=component.getFirst("screen")
|
||||||
|
term.clear()
|
||||||
17
AceVM/disks/1h/bin_/debug
Normal file
17
AceVM/disks/1h/bin_/debug
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
local args={...}
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
local hpv=require("hypervisor")
|
||||||
|
local fs=require("filesystem")
|
||||||
|
if not (fs.exists("/bin/"..args[1]) and (not fs.isDir("/bin/"..args[1]))) then error("not a file") end
|
||||||
|
local handle = hpv.createProcessFromFile("/bin/"..args[1], args[1], table.unpack(args, 2))
|
||||||
|
local pid=handle.getID()
|
||||||
|
local debugger=hpv.attachDebugger(handle)
|
||||||
|
debugger.addEvent("threadReturn", function(...)
|
||||||
|
term.print("threadReturn", ...)
|
||||||
|
end)
|
||||||
|
debugger.addEvent("threadError", function(...)
|
||||||
|
term.print("threadError", ...)
|
||||||
|
end)
|
||||||
|
while hpv.isrunning(pid) do
|
||||||
|
sleep(0.5)
|
||||||
|
end
|
||||||
0
AceVM/disks/1h/bin_/ls
Normal file
0
AceVM/disks/1h/bin_/ls
Normal file
24
AceVM/disks/1h/bin_/neofetch
Normal file
24
AceVM/disks/1h/bin_/neofetch
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
local term=component.getFirst("screen")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | root@hyperion ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ------------- ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | OS: Hyperion AC ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Host: $Computer_id ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Kernel: Hyprkrnl 1.0.0 ")
|
||||||
|
term.print("⠀⢷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡞⠀ | Uptime: 2:00 ")
|
||||||
|
term.print("⠀⠈⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⠁⠀ | Packages: 204 ")
|
||||||
|
term.print("⠀⠀⠘⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⠃⠀⠀ | Shell: DoomieShell ")
|
||||||
|
term.print("⠀⠀⠀⢹⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⡏⠀⠀⠀ | Resolution: $monitor_size ")
|
||||||
|
term.print("⠀⠀⠀⠀⢻⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⡟⠀⠀⠀⠀ | DE: ComputeX ")
|
||||||
|
term.print("⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀ | WM: HWMS ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⡿⠋⠁⠀⠀⠀⠀⠀ | WM Theme: Standard dark ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣦⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⣠⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀ | Theme: Standard dark ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⢠⣀⠀⠀⠈⠛⢿⣿⣿⣷⣄⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⣠⣾⣿⣿⡿⠛⠁⠀⠀⣀⡄⠀⠀⠀⠀⠀⠀⠀ | Icons: Standard ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⣶⣤⣀⠀⠈⠛⢿⣿⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⣿⡿⠛⠁⠀⣀⣤⣶⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀ | Terminal: Goterm ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣶⡄⢸⣿⠀⠀⠸⣿⣿⣿⣿⡏⠀⠀⣿⡇⢠⣶⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠿⠿⠿⠟⠛⠃⢸⣿⠀⠀⠀⠹⣿⣿⡟⠀⠀⠀⣿⡇⠘⠛⠻⠿⠿⠿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⡄⢸⣿⡀⠀⠀⠀⢻⡿⠁⠀⠀⢀⣿⡇⢠⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⠇⠘⢿⣿⣦⡀⠀⠀⠁⠀⢀⣴⣿⡿⠃⠸⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡿⠋⠀⠀⠀⠀⠙⣿⣿⣦⡀⢀⣴⣿⡿⠋⠀⠀⠀⠈⠙⠿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
13
AceVM/disks/1h/bin_/pge
Normal file
13
AceVM/disks/1h/bin_/pge
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
local function func(tble,space)
|
||||||
|
space=space or ""
|
||||||
|
for i,v in pairs(tble) do
|
||||||
|
print(space..tostring(i).." | "..tostring(v))
|
||||||
|
if type(v) == "table" then
|
||||||
|
if i=="_G" then else
|
||||||
|
func(v,space.." ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
func(_G)
|
||||||
2
AceVM/disks/1h/bin_/reboot
Normal file
2
AceVM/disks/1h/bin_/reboot
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local computer=component.getFirst("computer")
|
||||||
|
computer.reboot()
|
||||||
52
AceVM/disks/1h/bin_/shell
Normal file
52
AceVM/disks/1h/bin_/shell
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
local stringBuffer=""
|
||||||
|
local hpv = require("hypervisor")
|
||||||
|
local fs = require("filesystem")
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
local captureInput=true
|
||||||
|
local exit=false
|
||||||
|
local function printPrefix()
|
||||||
|
term.printInline("root@testharness:/& ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tokenize(str)
|
||||||
|
return string.split(str, " ")
|
||||||
|
end
|
||||||
|
|
||||||
|
hpv.addEvent("keyTyped",function(...)
|
||||||
|
if not captureInput then return end
|
||||||
|
local char=({...})[1]
|
||||||
|
if char == "\n" then
|
||||||
|
captureInput=false
|
||||||
|
term.print("")
|
||||||
|
elseif char == "\b" then
|
||||||
|
if #stringBuffer > 0 then
|
||||||
|
stringBuffer=stringBuffer:sub(1,#stringBuffer-1)
|
||||||
|
term.printInline(char)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
stringBuffer=stringBuffer..char
|
||||||
|
term.printInline(char)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
printPrefix()
|
||||||
|
while not exit do
|
||||||
|
while captureInput do
|
||||||
|
sleep(1)
|
||||||
|
end
|
||||||
|
local token = tokenize(stringBuffer)
|
||||||
|
if token[1] == "exit" then
|
||||||
|
exit=true
|
||||||
|
elseif fs.exists("/bin/"..token[1]) and (not fs.isDir("/bin/"..token[1])) then
|
||||||
|
local handle = hpv.createProcessFromFile("/bin/"..token[1], token[1], table.unpack(token, 2))
|
||||||
|
local pid=handle.getID()
|
||||||
|
while hpv.isrunning(pid) do
|
||||||
|
sleep(0.5)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
term.print("Command not recognized")
|
||||||
|
end
|
||||||
|
stringBuffer=""
|
||||||
|
printPrefix()
|
||||||
|
captureInput=true
|
||||||
|
end
|
||||||
2
AceVM/disks/1h/bin_/t
Normal file
2
AceVM/disks/1h/bin_/t
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local print=component.getFirst("screen").print
|
||||||
|
print("test")
|
||||||
23
AceVM/disks/1h/bin_/top
Normal file
23
AceVM/disks/1h/bin_/top
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
local hpv=require("hypervisor")
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
|
||||||
|
term.clear()
|
||||||
|
local function m(str, m)
|
||||||
|
if #str>m then
|
||||||
|
return str:sub(1,m-1).."- "
|
||||||
|
else
|
||||||
|
while #str~=m do
|
||||||
|
str=str.." "
|
||||||
|
end
|
||||||
|
return str.." "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i in hpv.listProc() do
|
||||||
|
term.print(m(i.name, 15)..m(i.status, 7)..m(i.pid, 4))
|
||||||
|
for _,v in ipairs(i.threads) do
|
||||||
|
if v.name~="main" then
|
||||||
|
term.print(" "..m(v.name, 12)..m(v.status, 7))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
19
AceVM/disks/1h/bin_/unitest
Normal file
19
AceVM/disks/1h/bin_/unitest
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
local errors={}
|
||||||
|
local function tables_equal(t1, t2)
|
||||||
|
if #t1 ~= #t2 then return false end
|
||||||
|
for i = 1, #t1 do
|
||||||
|
if t1[i] ~= t2[i] then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run_test(name, test_func)
|
||||||
|
local status, err = pcall(test_func)
|
||||||
|
if status then
|
||||||
|
print("[PASS] " .. name)
|
||||||
|
else
|
||||||
|
print("[FAIL] " .. name .. ": " .. err)
|
||||||
|
errors[name]=err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
222
AceVM/disks/1h/boot/Hyprkrnl.sys
Normal file
222
AceVM/disks/1h/boot/Hyprkrnl.sys
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
local function rand()
|
||||||
|
if math.random(0,1)==0 then return true else return false end
|
||||||
|
end
|
||||||
|
function coroutine.resumeWithTimeout(CORO, TIME, ...)
|
||||||
|
return rand(), coroutine.resume(CORO, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
-- Get boot arguments
|
||||||
|
_G.component=component
|
||||||
|
local bootArgs=({...})[1]
|
||||||
|
local bootDrive=bootArgs.bootDrive
|
||||||
|
local LOG_TEXT=""
|
||||||
|
local log={}
|
||||||
|
local term
|
||||||
|
local bootData=load("return "..(bootDrive:open("var/log/kernel/bootData").read() or "{}"))()
|
||||||
|
local computer=component.getFirst("computer")
|
||||||
|
local startup=true
|
||||||
|
local osleep=sleep
|
||||||
|
local oldYield=coroutine.yield
|
||||||
|
|
||||||
|
function coroutine.yield(...)
|
||||||
|
if not startup then
|
||||||
|
if coroutine.isyieldable(coroutine.running()) then
|
||||||
|
oldYield(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find terminal(s)
|
||||||
|
local terminals={}
|
||||||
|
for i,v in component.list() do
|
||||||
|
if i == "screen" then
|
||||||
|
terminals[#terminals+1] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
term={
|
||||||
|
print=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.print(...)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
printInline=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.printInline(...)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
clear=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.clear(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
term.print("Welcome to Hyperion OS")
|
||||||
|
-- Difine logging lib
|
||||||
|
local function getPName(func)
|
||||||
|
if type(func) == "function" then
|
||||||
|
getPName=func
|
||||||
|
end
|
||||||
|
return "Hyprkrnl"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.log(text)
|
||||||
|
if startup then term.print("[ OK ] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[ OK ] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.error(text)
|
||||||
|
if startup then term.print("[FAILED] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[FAILED] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.warn(text)
|
||||||
|
if startup then term.print("[ WARN ] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[ WARN ] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.raw(text)
|
||||||
|
if startup then term.print(" "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.." "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.get()
|
||||||
|
return LOG_TEXT
|
||||||
|
end
|
||||||
|
|
||||||
|
local function t2t(table)
|
||||||
|
local output = "{"
|
||||||
|
for i,v in pairs(table) do
|
||||||
|
local coma=true
|
||||||
|
if type(i) == "string" then
|
||||||
|
output=output.."[\""..i.."\"]="
|
||||||
|
end
|
||||||
|
if type(v) == "table" then
|
||||||
|
if v == table then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
else
|
||||||
|
output=output..t2t(v)
|
||||||
|
end
|
||||||
|
elseif type(v) == "string" then
|
||||||
|
output=output.."[=["..v.."]=]"
|
||||||
|
elseif type(v) == "number" then
|
||||||
|
output=output..tostring(v)
|
||||||
|
elseif type(v) == "function" then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
end
|
||||||
|
if coma then
|
||||||
|
output=output..","
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #table>0 or string.sub(output,#output,#output) == "," then
|
||||||
|
output=string.sub(output,1,#output-1)
|
||||||
|
end
|
||||||
|
output=output.."}"
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- My favorite function
|
||||||
|
local function PANIC(err,lvl)
|
||||||
|
term.clear()
|
||||||
|
term.print(LOG_TEXT)
|
||||||
|
term.printInline("KERNEL PANIC: "..err)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
osleep(0.02)
|
||||||
|
if err==bootData.prevError then
|
||||||
|
bootData.errorCount=bootData.errorCount+1
|
||||||
|
else
|
||||||
|
bootData.prevError=err
|
||||||
|
bootData.errorCount=0
|
||||||
|
end
|
||||||
|
bootDrive:open("var/log/kernel/bootData").write(t2t(bootData))
|
||||||
|
if bootData.errorCount < 4 then
|
||||||
|
term.print("")
|
||||||
|
term.print("Atempting reboot...")
|
||||||
|
osleep(0.5)
|
||||||
|
computer.reboot()
|
||||||
|
elseif bootData.errorCount > 3 then
|
||||||
|
term.print("")
|
||||||
|
term.print("boot determined to be unrecoverable...")
|
||||||
|
osleep(0.5)
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
term.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function runAsKernel(path, args)
|
||||||
|
local ok,err,extra = pcall(load(bootDrive:open(path).read(), path, "t", _G), args)
|
||||||
|
if not ok then
|
||||||
|
PANIC(path.." failed to load/execute err:\n"..(err or ""))
|
||||||
|
end
|
||||||
|
return err,extra
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add libray modifications+
|
||||||
|
for _,v in ipairs(bootDrive:list("/sys/kernel/glib")) do
|
||||||
|
log.raw("running "..v)
|
||||||
|
runAsKernel("/sys/kernel/glib/"..v)
|
||||||
|
log.log("Loaded "..v)
|
||||||
|
end
|
||||||
|
log.log("Finished loading global librarys")
|
||||||
|
local sudoMaster={}
|
||||||
|
local auth=runAsKernel("sys/kernel/userManager.sys",{masterKey=sudoMaster,bootDrive=bootDrive})
|
||||||
|
log.log("Created UE Manager")
|
||||||
|
local fs=runAsKernel("sys/kernel/filesystem.sys",{bootDrive=bootDrive,auth=auth})
|
||||||
|
log.log("Initailized filesystem")
|
||||||
|
local io=runAsKernel("sys/kernel/ioManager.sys",{masterKey=sudoMaster})
|
||||||
|
log.log("Started ioManager")
|
||||||
|
local packages={filesystem=fs, auth=auth, logging=log, term=term}
|
||||||
|
local req=runAsKernel("sys/modules/require",{filesystem=fs,logging=log, preload=packages})
|
||||||
|
log.log("Loaded require")
|
||||||
|
local setRequire
|
||||||
|
local requ=req.makeRequire("lib/?;lib/?/init;sys/modules/?;sys/modules/?/init",packages)
|
||||||
|
_G.require, setRequire = requ.require, requ.load
|
||||||
|
setRequire("require",req)
|
||||||
|
log.log("Initailized require")
|
||||||
|
|
||||||
|
local code=fs.open("sbin/init","x")
|
||||||
|
|
||||||
|
if not code then
|
||||||
|
PANIC("System failed to load")
|
||||||
|
end
|
||||||
|
local ok, system=pcall(code, {masterKey=sudoMaster, setRequire=setRequire, pname=getPName})
|
||||||
|
if not ok then
|
||||||
|
PANIC("System failed to execute ERR:\n"..hypervisor)
|
||||||
|
end
|
||||||
|
log.log("Loaded sysinit")
|
||||||
|
log.raw("Making kernel process")
|
||||||
|
|
||||||
|
hypervisor(function()
|
||||||
|
local hpv=require("hypervisor")
|
||||||
|
local thread=require("thread")
|
||||||
|
log.log("Created kernel process")
|
||||||
|
hpv.createProcessFromFile("sys/os/init.lua", "systemd")
|
||||||
|
thread.create(function()
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == nil then
|
||||||
|
coroutine.yield()
|
||||||
|
else
|
||||||
|
hpv.triggerEvent("all", event[1], table.unpack(event,2))
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, "eventHandler")
|
||||||
|
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
term.print("Goodbye :)")
|
||||||
0
AceVM/disks/1h/etc/ast-ip/config.ini
Normal file
0
AceVM/disks/1h/etc/ast-ip/config.ini
Normal file
0
AceVM/disks/1h/etc/fstab
Normal file
0
AceVM/disks/1h/etc/fstab
Normal file
2
AceVM/disks/1h/etc/group
Normal file
2
AceVM/disks/1h/etc/group
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
root:0:root
|
||||||
|
sudo:1:root
|
||||||
1
AceVM/disks/1h/etc/passwd
Normal file
1
AceVM/disks/1h/etc/passwd
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root:x:0:0::/root:/bin/pshell
|
||||||
1
AceVM/disks/1h/etc/shadow
Normal file
1
AceVM/disks/1h/etc/shadow
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root:$5$9a7f8e2b4cd01ac18d7cbb4da74f5c1e$53326d6a24ef6a050b5ef88dbbe5906d4afbcf191725f9750e44a818ab22bd62:0
|
||||||
2
AceVM/disks/1h/etc/spm/repos
Normal file
2
AceVM/disks/1h/etc/spm/repos
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
https://git.astronand.dev/Hyperion-OS/packages/raw/branch/main/spm/
|
||||||
|
https://git.astronand.dev/Hyperion-OS/packages/raw/branch/main/ac/
|
||||||
1
AceVM/disks/1h/etc/sudoers
Normal file
1
AceVM/disks/1h/etc/sudoers
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root
|
||||||
0
AceVM/disks/1h/etc/sysinit/system/graphical.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/graphical.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/halt.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/halt.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/multi-user.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/multi-user.target
Normal file
5
AceVM/disks/1h/etc/sysinit/system/poweroff.target
Normal file
5
AceVM/disks/1h/etc/sysinit/system/poweroff.target
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Shutdown of system
|
||||||
|
Conflicts=reboot.target halt.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
0
AceVM/disks/1h/etc/sysinit/system/reboot.target
Normal file
0
AceVM/disks/1h/etc/sysinit/system/reboot.target
Normal file
111
AceVM/disks/1h/lib/config/ini
Normal file
111
AceVM/disks/1h/lib/config/ini
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local ini = {}
|
||||||
|
local fs=require("filesystem")
|
||||||
|
|
||||||
|
local function trim(s)
|
||||||
|
local i, j = 1, #s
|
||||||
|
while i <= j and (s:sub(i,i) == " " or s:sub(i,i) == "\t") do
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
while j >= i and (s:sub(j,j) == " " or s:sub(j,j) == "\t") do
|
||||||
|
j = j - 1
|
||||||
|
end
|
||||||
|
return s:sub(i, j)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parse(list)
|
||||||
|
local lines=function ()
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return list[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = {}
|
||||||
|
local section = data
|
||||||
|
for line in lines() do
|
||||||
|
line = trim(line)
|
||||||
|
|
||||||
|
if line ~= "" and line:sub(1,1) ~= ";" and line:sub(1,1) ~= "#" then
|
||||||
|
if line:sub(1,1) == "[" and line:sub(-1) == "]" then
|
||||||
|
local secName = trim(line:sub(2, -2))
|
||||||
|
if secName ~= "" then
|
||||||
|
data[secName] = data[secName] or {}
|
||||||
|
section = data[secName]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local eq
|
||||||
|
for i = 1, #line do
|
||||||
|
if line:sub(i,i) == "=" then
|
||||||
|
eq = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if eq then
|
||||||
|
local key = trim(line:sub(1, eq-1))
|
||||||
|
local value = trim(line:sub(eq+1))
|
||||||
|
|
||||||
|
local lower = value:lower()
|
||||||
|
if tonumber(value) then
|
||||||
|
value = tonumber(value)
|
||||||
|
elseif lower == "true" then
|
||||||
|
value = true
|
||||||
|
elseif lower == "false" then
|
||||||
|
value = false
|
||||||
|
end
|
||||||
|
section[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.read(path)
|
||||||
|
local file, err = fs.open(path, "r")
|
||||||
|
if not file then return nil, err end
|
||||||
|
local list={}
|
||||||
|
for i in file.lines() do
|
||||||
|
list[#list+1] = i
|
||||||
|
end
|
||||||
|
file.close()
|
||||||
|
return parse(list)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.get(text)
|
||||||
|
return parse(string.split(text, "\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function write(data)
|
||||||
|
local text=""
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if type(v) ~= "table" then
|
||||||
|
text=text..k .. " = " .. tostring(v) .. "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for sec, tbl in pairs(data) do
|
||||||
|
if type(tbl) == "table" then
|
||||||
|
text=text.."\n[" .. sec .. "]\n"
|
||||||
|
for k,v in pairs(tbl) do
|
||||||
|
text=text..k .. " = " .. tostring(v) .. "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.write(path, data)
|
||||||
|
local file=fs.open(path, "w")
|
||||||
|
file.write(write(data))
|
||||||
|
file.close()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.make(data)
|
||||||
|
return write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ini
|
||||||
193
AceVM/disks/1h/lib/crypto/sha256
Normal file
193
AceVM/disks/1h/lib/crypto/sha256
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
-- From http://pastebin.com/gsFrNjbt linked from http://www.computercraft.info/forums2/index.php?/topic/8169-sha-256-in-pure-lua/
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Adaptation of the Secure Hashing Algorithm (SHA-244/256)
|
||||||
|
-- Found Here: http://lua-users.org/wiki/SecureHashAlgorithm
|
||||||
|
--
|
||||||
|
-- Using an adapted version of the bit library
|
||||||
|
-- Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua
|
||||||
|
--
|
||||||
|
|
||||||
|
local MOD = 2^32
|
||||||
|
local MODM = MOD-1
|
||||||
|
|
||||||
|
local function memoize(f)
|
||||||
|
local mt = {}
|
||||||
|
local t = setmetatable({}, mt)
|
||||||
|
function mt:__index(k)
|
||||||
|
local v = f(k)
|
||||||
|
t[k] = v
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_bitop_uncached(t, m)
|
||||||
|
local function bitop(a, b)
|
||||||
|
local res,p = 0,1
|
||||||
|
while a ~= 0 and b ~= 0 do
|
||||||
|
local am, bm = a % m, b % m
|
||||||
|
res = res + t[am][bm] * p
|
||||||
|
a = (a - am) / m
|
||||||
|
b = (b - bm) / m
|
||||||
|
p = p*m
|
||||||
|
end
|
||||||
|
res = res + (a + b) * p
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
return bitop
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_bitop(t)
|
||||||
|
local op1 = make_bitop_uncached(t,2^1)
|
||||||
|
local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
|
||||||
|
return make_bitop_uncached(op2, 2 ^ (t.n or 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
|
||||||
|
|
||||||
|
local function bxor(a, b, c, ...)
|
||||||
|
local z = nil
|
||||||
|
if b then
|
||||||
|
a = a % MOD
|
||||||
|
b = b % MOD
|
||||||
|
z = bxor1(a, b)
|
||||||
|
if c then z = bxor(z, c, ...) end
|
||||||
|
return z
|
||||||
|
elseif a then return a % MOD
|
||||||
|
else return 0 end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function band(a, b, c, ...)
|
||||||
|
local z
|
||||||
|
if b then
|
||||||
|
a = a % MOD
|
||||||
|
b = b % MOD
|
||||||
|
z = ((a + b) - bxor1(a,b)) / 2
|
||||||
|
if c then z = bit32_band(z, c, ...) end
|
||||||
|
return z
|
||||||
|
elseif a then return a % MOD
|
||||||
|
else return MODM end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function bnot(x) return (-1 - x) % MOD end
|
||||||
|
|
||||||
|
local function rshift1(a, disp)
|
||||||
|
if disp < 0 then return lshift(a,-disp) end
|
||||||
|
return math.floor(a % 2 ^ 32 / 2 ^ disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rshift(x, disp)
|
||||||
|
if disp > 31 or disp < -31 then return 0 end
|
||||||
|
return rshift1(x % MOD, disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function lshift(a, disp)
|
||||||
|
if disp < 0 then return rshift(a,-disp) end
|
||||||
|
return (a * 2 ^ disp) % 2 ^ 32
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rrotate(x, disp)
|
||||||
|
x = x % MOD
|
||||||
|
disp = disp % 32
|
||||||
|
local low = band(x, 2 ^ disp - 1)
|
||||||
|
return rshift(x, disp) + lshift(low, 32 - disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local k = {
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||||
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||||
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||||
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||||
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function str2hexa(s)
|
||||||
|
return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function num2s(l, n)
|
||||||
|
local s = ""
|
||||||
|
for i = 1, n do
|
||||||
|
local rem = l % 256
|
||||||
|
s = string.char(rem) .. s
|
||||||
|
l = (l - rem) / 256
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
local function s232num(s, i)
|
||||||
|
local n = 0
|
||||||
|
for i = i, i + 3 do n = n*256 + string.byte(s, i) end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
|
||||||
|
local function preproc(msg, len)
|
||||||
|
local extra = 64 - ((len + 9) % 64)
|
||||||
|
len = num2s(8 * len, 8)
|
||||||
|
msg = msg .. "\128" .. string.rep("\0", extra) .. len
|
||||||
|
assert(#msg % 64 == 0)
|
||||||
|
return msg
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initH256(H)
|
||||||
|
H[1] = 0x6a09e667
|
||||||
|
H[2] = 0xbb67ae85
|
||||||
|
H[3] = 0x3c6ef372
|
||||||
|
H[4] = 0xa54ff53a
|
||||||
|
H[5] = 0x510e527f
|
||||||
|
H[6] = 0x9b05688c
|
||||||
|
H[7] = 0x1f83d9ab
|
||||||
|
H[8] = 0x5be0cd19
|
||||||
|
return H
|
||||||
|
end
|
||||||
|
|
||||||
|
local function digestblock(msg, i, H)
|
||||||
|
local w = {}
|
||||||
|
for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
|
||||||
|
for j = 17, 64 do
|
||||||
|
local v = w[j - 15]
|
||||||
|
local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
|
||||||
|
v = w[j - 2]
|
||||||
|
w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
|
||||||
|
end
|
||||||
|
|
||||||
|
local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
|
||||||
|
for i = 1, 64 do
|
||||||
|
local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
|
||||||
|
local maj = bxor(band(a, b), band(a, c), band(b, c))
|
||||||
|
local t2 = s0 + maj
|
||||||
|
local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
|
||||||
|
local ch = bxor (band(e, f), band(bnot(e), g))
|
||||||
|
local t1 = h + s1 + ch + k[i] + w[i]
|
||||||
|
h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
|
||||||
|
end
|
||||||
|
|
||||||
|
H[1] = band(H[1] + a)
|
||||||
|
H[2] = band(H[2] + b)
|
||||||
|
H[3] = band(H[3] + c)
|
||||||
|
H[4] = band(H[4] + d)
|
||||||
|
H[5] = band(H[5] + e)
|
||||||
|
H[6] = band(H[6] + f)
|
||||||
|
H[7] = band(H[7] + g)
|
||||||
|
H[8] = band(H[8] + h)
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(msg)
|
||||||
|
msg = preproc(msg, #msg)
|
||||||
|
local H = initH256({})
|
||||||
|
for i = 1, #msg, 64 do digestblock(msg, i, H) end
|
||||||
|
return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
|
||||||
|
num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
|
||||||
|
end
|
||||||
0
AceVM/disks/1h/lib/lua/lexer
Normal file
0
AceVM/disks/1h/lib/lua/lexer
Normal file
0
AceVM/disks/1h/lib/lua/minify
Normal file
0
AceVM/disks/1h/lib/lua/minify
Normal file
47
AceVM/disks/1h/sbin/spm.lua
Normal file
47
AceVM/disks/1h/sbin/spm.lua
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args = {...}
|
||||||
|
local os = require("system")
|
||||||
|
local fs=require("filesystem")
|
||||||
|
local term = os.getEnvar("term")
|
||||||
|
|
||||||
|
if args[1] == "help" or args[1] == "-h" then
|
||||||
|
term.print("SPM V1.0.0")
|
||||||
|
term.print("Usage:")
|
||||||
|
term.print(" install <package> : searches for package and installs it")
|
||||||
|
term.print(" add-repo <URL> : adds repo to search list appends package to end of URL")
|
||||||
|
term.print(" download <URL> : downloads package from URL")
|
||||||
|
term.print(" local <dir> : downloads package from file")
|
||||||
|
term.print(" get <dir> : executes commands from list")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function install(package)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function addRepo(url)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function download(url)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function localPackage(dir)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run(command)
|
||||||
|
local list = string.split(command, " ")
|
||||||
|
if list[1] == "install" then
|
||||||
|
install(list[2])
|
||||||
|
elseif list[1] == "add-repo" then
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if args[1] == "get" then
|
||||||
|
local list=string.split(fs.readAllText(args[2]), "\n")
|
||||||
|
for i, v in ipairs(list) do
|
||||||
|
|
||||||
|
end
|
||||||
|
else run(args) end
|
||||||
1
AceVM/disks/1h/sys/db/os.reg
Normal file
1
AceVM/disks/1h/sys/db/os.reg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
40
AceVM/disks/1h/sys/drivers/ac.disk.ko
Normal file
40
AceVM/disks/1h/sys/drivers/ac.disk.ko
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "fs"
|
||||||
|
driver.name = "Advanced Computers disk driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers disks"
|
||||||
|
driver.manifest = "ac.disk.ko"
|
||||||
|
|
||||||
|
driver.api = function(component)
|
||||||
|
return {
|
||||||
|
readAllText = function(dir)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
local file = drive.read()
|
||||||
|
drive = nil
|
||||||
|
return file
|
||||||
|
end,
|
||||||
|
writeAllText = function(dir, content)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
drive.write(content)
|
||||||
|
drive = nil
|
||||||
|
end,
|
||||||
|
appendAllText = function(dir, content)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
drive.append(content)
|
||||||
|
drive = nil
|
||||||
|
end,
|
||||||
|
list = function(dir)
|
||||||
|
return component:list(dir)
|
||||||
|
end,
|
||||||
|
mkFile = function(dir)
|
||||||
|
component:makeFile(dir)
|
||||||
|
end,
|
||||||
|
mkDir = function(dir)
|
||||||
|
component:makeDirectory(dir)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return driver
|
||||||
26
AceVM/disks/1h/sys/drivers/ac.screen.ko
Normal file
26
AceVM/disks/1h/sys/drivers/ac.screen.ko
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "terminal"
|
||||||
|
driver.name = "Advanced Computers screen driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers screens"
|
||||||
|
driver.manifest = "ac.screen.ko"
|
||||||
|
|
||||||
|
driver.api=function(component)
|
||||||
|
return {
|
||||||
|
write=function(...)
|
||||||
|
component.printInline(...)
|
||||||
|
end,
|
||||||
|
print=function(...)
|
||||||
|
component.print(...)
|
||||||
|
end,
|
||||||
|
printInline=function(...)
|
||||||
|
component.printInline(...)
|
||||||
|
end,
|
||||||
|
clear=function(...)
|
||||||
|
component.clear()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return driver
|
||||||
16
AceVM/disks/1h/sys/drivers/ac.udisk.ko
Normal file
16
AceVM/disks/1h/sys/drivers/ac.udisk.ko
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "ufs"
|
||||||
|
driver.name = "Advanced Computers unmanaged disk driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers unmanaged disks"
|
||||||
|
driver.manifest = "ac.udisk.ko"
|
||||||
|
|
||||||
|
driver.api = function(component)
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return driver
|
||||||
8
AceVM/disks/1h/sys/drivers/ac.wlan.ko
Normal file
8
AceVM/disks/1h/sys/drivers/ac.wlan.ko
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "wlan"
|
||||||
|
driver.name = "Advanced Computers http driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers http"
|
||||||
|
driver.manifest = "ac.wlan.ko"
|
||||||
245
AceVM/disks/1h/sys/kernel/filesystem.sys
Normal file
245
AceVM/disks/1h/sys/kernel/filesystem.sys
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
-- File open modes
|
||||||
|
-- M | H | D
|
||||||
|
-- rc | r | Read and close
|
||||||
|
-- r | r | Read
|
||||||
|
-- w | w | Write
|
||||||
|
-- o | w | Overite file
|
||||||
|
-- om | m | Overite and modify
|
||||||
|
-- rw | m | Read and write
|
||||||
|
-- x | f | get function
|
||||||
|
|
||||||
|
local args=({...})[1]
|
||||||
|
local fs={}
|
||||||
|
local disks={}
|
||||||
|
local mounts={}
|
||||||
|
local bootDrive=args.bootDrive
|
||||||
|
local auth=args.auth
|
||||||
|
local log=args.logging
|
||||||
|
|
||||||
|
for t, o in component.list() do
|
||||||
|
if t=="disk" then
|
||||||
|
if o.id==bootDrive.id then
|
||||||
|
else disks[o.id]=o end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function resolve(path)
|
||||||
|
if string.sub(path,1,1)~="/" then
|
||||||
|
path="/"..path
|
||||||
|
end
|
||||||
|
local drive=bootDrive
|
||||||
|
for i,v in pairs(mounts) do
|
||||||
|
if string.hasPrefix(path,v) then
|
||||||
|
drive=disks[i]
|
||||||
|
path=string.getSuffix(path,v)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return drive, path
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkPerms(path, mode)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getHandle(backing,typ,clear)
|
||||||
|
local ret={}
|
||||||
|
local close=false
|
||||||
|
ret.close=function()
|
||||||
|
close=true
|
||||||
|
end
|
||||||
|
if typ=="r" then
|
||||||
|
ret.read=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return backing.read()
|
||||||
|
end
|
||||||
|
ret.lines=function()
|
||||||
|
if close then error() end
|
||||||
|
local lines=string.split(backing.read(), "\n")
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return lines[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif typ=="w" then
|
||||||
|
ret.write=function(data)
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.append(data)
|
||||||
|
end
|
||||||
|
elseif typ=="m" then
|
||||||
|
ret.read=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return backing.read()
|
||||||
|
end
|
||||||
|
ret.lines=function()
|
||||||
|
if close then error() end
|
||||||
|
local lines=string.split(backing.read(), "\n")
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return lines[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ret.write=function(data)
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.append(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if clear then
|
||||||
|
ret.clear=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.write()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local function open(path, mode, arg, pc)
|
||||||
|
if pc then
|
||||||
|
checkPerms(path, mode)
|
||||||
|
end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
if drive:directoryExists(newPath) then error("Cannot open directory") end
|
||||||
|
if not drive:fileExists(newPath) then error("File does not exist") end
|
||||||
|
local backing=drive:open(newPath)
|
||||||
|
if mode=="rc" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return text
|
||||||
|
elseif mode=="r" then
|
||||||
|
return getHandle(backing,"r")
|
||||||
|
elseif mode=="w" then
|
||||||
|
return getHandle(backing,"w")
|
||||||
|
elseif mode=="o" then
|
||||||
|
local file=getHandle(backing,"w",true)
|
||||||
|
file.clear()
|
||||||
|
file.clear=nil
|
||||||
|
return file
|
||||||
|
elseif mode=="om" then
|
||||||
|
local file=getHandle(backing,"m",true)
|
||||||
|
file.clear()
|
||||||
|
file.clear=nil
|
||||||
|
return file
|
||||||
|
elseif mode=="rw" then
|
||||||
|
return getHandle(backing,"m")
|
||||||
|
elseif mode=="x" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return load(text, path, nil, table.deepcopy(_G))
|
||||||
|
elseif mode=="xe" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return load(text, path, nil, arg)
|
||||||
|
else
|
||||||
|
error("Invailid mode")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.open(path, mode, arg)
|
||||||
|
return open(path, mode, arg, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.copy(orig, dest)
|
||||||
|
local destFile = fs.open(dest,"o")
|
||||||
|
local origFile = fs.open(orig, "rc")
|
||||||
|
destFile.write(origFile)
|
||||||
|
destFile.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.move(orig, dest)
|
||||||
|
local destFile = fs.open(dest,"o")
|
||||||
|
local origFile = fs.open(orig, "rc")
|
||||||
|
destFile.write(origFile)
|
||||||
|
destFile.close()
|
||||||
|
fs.delete(orig)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This fixes the weirdest bug ever
|
||||||
|
local isDir = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "r") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:directoryExists(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
local exists = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "r") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return ((drive:directoryExists(newPath)) or (drive:fileExists(newPath)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local delete = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "w") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:delete(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
local list = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "w") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:list(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.list(path)
|
||||||
|
return list(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.isDir(path)
|
||||||
|
return isDir(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.exists(path)
|
||||||
|
return exists(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.delete(path)
|
||||||
|
return delete(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.getSudo(key)
|
||||||
|
if auth.sudo.isAproved(key) then
|
||||||
|
return {
|
||||||
|
createVirtDisk=function(virtualDiskName,virtualDiskObj)
|
||||||
|
disks[virtualDiskName]=virtualDiskObj
|
||||||
|
log.log("Created VirtIO disk named "..virtualDiskName)
|
||||||
|
end,
|
||||||
|
mount=function(hardwareDir,path)
|
||||||
|
mounts[hardwareDir]=path
|
||||||
|
log.log("Mounted disk ")
|
||||||
|
end,
|
||||||
|
unmount=function(hardwareDir)
|
||||||
|
mounts[hardwareDir]=nil
|
||||||
|
end,
|
||||||
|
eject=function(hardwareDir)
|
||||||
|
disks[hardwareDir]=nil
|
||||||
|
end,
|
||||||
|
sfs={
|
||||||
|
open=function(path, mode, arg)
|
||||||
|
return open(path, mode, arg)
|
||||||
|
end,
|
||||||
|
delete=function(path)
|
||||||
|
return delete(path)
|
||||||
|
end,
|
||||||
|
copy=fs.copy,
|
||||||
|
move=fs.move,
|
||||||
|
exists=function(path)
|
||||||
|
return exists(path)
|
||||||
|
end,
|
||||||
|
isDir=function(path)
|
||||||
|
return isDir(path)
|
||||||
|
end,
|
||||||
|
list=function(path)
|
||||||
|
return list(path)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error("sudo request denied")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return fs
|
||||||
50
AceVM/disks/1h/sys/kernel/glib/component.lua
Normal file
50
AceVM/disks/1h/sys/kernel/glib/component.lua
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
--local oldComponent = component
|
||||||
|
--_G.component={}
|
||||||
|
--local components={}
|
||||||
|
--local all={}
|
||||||
|
--local blacklisted={}
|
||||||
|
--
|
||||||
|
--function table.contains(tabl, query)
|
||||||
|
-- for i,v in ipairs(tabl) do
|
||||||
|
-- if v==query then
|
||||||
|
-- return true
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- return false
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--for i,v in oldComponent.list() do
|
||||||
|
-- if not components[i] then
|
||||||
|
-- components[i]={}
|
||||||
|
-- end
|
||||||
|
-- components[i][#components[i]+1]={typ=i,obj=v}
|
||||||
|
-- all[#all+1]={typ=i,obj=v}
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--function component.list(filter)
|
||||||
|
-- filter=filter or "all"
|
||||||
|
-- local filtered
|
||||||
|
-- if filter=="all" then
|
||||||
|
-- filtered=all
|
||||||
|
-- else
|
||||||
|
-- filtered=components[filter]
|
||||||
|
-- end
|
||||||
|
-- local i=0
|
||||||
|
-- return function()
|
||||||
|
-- while i<#filtered do
|
||||||
|
-- i=i+1
|
||||||
|
-- if not table.contains(blacklisted, v.typ) then
|
||||||
|
-- return v.typ, v.obj
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--function component.getSudo(key)
|
||||||
|
-- if key==masterKey then
|
||||||
|
-- return oldComponent
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--
|
||||||
53
AceVM/disks/1h/sys/kernel/glib/string.lua
Normal file
53
AceVM/disks/1h/sys/kernel/glib/string.lua
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
function string.hasSuffix(str, suffix)
|
||||||
|
return string.sub(str, #suffix+1) == suffix
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.hasPrefix(str, prefix)
|
||||||
|
return string.sub(str, 1, #prefix) == prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.getSuffix(str, prefix)
|
||||||
|
return string.sub(str, #prefix+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.getPrefix(str, suffix)
|
||||||
|
return string.sub(str, 1, #suffix)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.join(delim, ...)
|
||||||
|
return table.concat(table.pack(...), delim)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.split(str, delim, maxResultCountOrNil)
|
||||||
|
assert(#delim == 1, "only delim len 1 supported for now")
|
||||||
|
maxResultCountOrNil = (maxResultCountOrNil or 0)-1
|
||||||
|
local rv = {}
|
||||||
|
local buf = ""
|
||||||
|
for i = 1, #str do
|
||||||
|
local c = string.sub(str,i,i)
|
||||||
|
if #rv ~= maxResultCountOrNil and c == delim then
|
||||||
|
table.insert(rv, buf)
|
||||||
|
buf = ""
|
||||||
|
else
|
||||||
|
buf = buf..c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(rv, buf)
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.replace(str, search, replacement)
|
||||||
|
local rv = ""
|
||||||
|
local consumedLen = 1
|
||||||
|
local i = 1
|
||||||
|
while i<#str do
|
||||||
|
if string.sub(str, i, i+#search-1) == search then
|
||||||
|
rv = rv .. string.sub(str, consumedLen, i-1) .. replacement
|
||||||
|
i=i+#search
|
||||||
|
consumedLen = i
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
return rv .. string.sub(str, consumedLen)
|
||||||
|
end
|
||||||
39
AceVM/disks/1h/sys/kernel/glib/table.lua
Normal file
39
AceVM/disks/1h/sys/kernel/glib/table.lua
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
function table.deepcopy(orig, copies)
|
||||||
|
copies = copies or {}
|
||||||
|
|
||||||
|
if type(orig) ~= 'table' then
|
||||||
|
return orig
|
||||||
|
elseif copies[orig] then
|
||||||
|
return copies[orig]
|
||||||
|
end
|
||||||
|
|
||||||
|
local copy = {}
|
||||||
|
copies[orig] = copy
|
||||||
|
|
||||||
|
for k, v in next, orig, nil do
|
||||||
|
local copied_key = table.deepcopy(k, copies)
|
||||||
|
local copied_val = table.deepcopy(v, copies)
|
||||||
|
copy[copied_key] = copied_val
|
||||||
|
end
|
||||||
|
|
||||||
|
return copy
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.hasKey(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if i==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.hasVal(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if v==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
1
AceVM/disks/1h/sys/kernel/ioManager.sys
Normal file
1
AceVM/disks/1h/sys/kernel/ioManager.sys
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
29
AceVM/disks/1h/sys/kernel/userManager.sys
Normal file
29
AceVM/disks/1h/sys/kernel/userManager.sys
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local masterKey=args.masterKey
|
||||||
|
local disk=args.bootDrive
|
||||||
|
local auth={}
|
||||||
|
auth.sudo={}
|
||||||
|
local keys={}
|
||||||
|
local ok,sha256=pcall(load(disk:open("/lib/crypto/sha256").read()))
|
||||||
|
if not ok then
|
||||||
|
error("sha256 failed to load")
|
||||||
|
end
|
||||||
|
|
||||||
|
local users={}
|
||||||
|
local file=disk:open("/etc/passwd").read()
|
||||||
|
-- for p,i in ipairs(string.split(file,"\n")) do
|
||||||
|
-- for t,v in ipairs(string.split(v,":")) do
|
||||||
|
-- users[p][t]=v
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
function auth.sudo.isAproved(key)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function auth.sudo.elevatePerms(password)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return auth
|
||||||
14
AceVM/disks/1h/sys/modules/consumer
Normal file
14
AceVM/disks/1h/sys/modules/consumer
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local lib={}
|
||||||
|
|
||||||
|
function lib.create(def)
|
||||||
|
local function func(fun)
|
||||||
|
if type(fun)=="function" then
|
||||||
|
func=fun
|
||||||
|
end
|
||||||
|
return def
|
||||||
|
end
|
||||||
|
return func
|
||||||
|
end
|
||||||
|
|
||||||
|
return lib
|
||||||
6
AceVM/disks/1h/sys/modules/ipc
Normal file
6
AceVM/disks/1h/sys/modules/ipc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local pipes={}
|
||||||
|
local ports={}
|
||||||
|
local sharedObjects={}
|
||||||
|
local net=require("net")
|
||||||
|
|
||||||
86
AceVM/disks/1h/sys/modules/require
Normal file
86
AceVM/disks/1h/sys/modules/require
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local log=args.logging
|
||||||
|
local fs=args.filesystem
|
||||||
|
local loaded=args.preload or {}
|
||||||
|
local function dot_to_slash(name)
|
||||||
|
local parts = {}
|
||||||
|
local start = 1
|
||||||
|
for i = 1, #name do
|
||||||
|
if name:sub(i, i) == "." then
|
||||||
|
table.insert(parts, name:sub(start, i - 1))
|
||||||
|
start = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(parts, name:sub(start))
|
||||||
|
return table.concat(parts, "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function replace_question_mark(path, name_path)
|
||||||
|
local result = {}
|
||||||
|
local replaced = false
|
||||||
|
for i = 1, #path do
|
||||||
|
local ch = path:sub(i, i)
|
||||||
|
if ch == "?" and not replaced then
|
||||||
|
table.insert(result, name_path)
|
||||||
|
replaced = true
|
||||||
|
else
|
||||||
|
table.insert(result, ch)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function search_module(name,search_paths)
|
||||||
|
local name_path = dot_to_slash(name)
|
||||||
|
|
||||||
|
for _, path in ipairs(search_paths) do
|
||||||
|
local filename = replace_question_mark(path, name_path)
|
||||||
|
if fs.exists(filename) and not fs.isDir(filename) then
|
||||||
|
local code=fs.open(filename,"x")
|
||||||
|
if code then
|
||||||
|
return code, filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, "module not found: " .. name
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
makeRequire=function(search_paths)
|
||||||
|
local config=string.split(search_paths,";")
|
||||||
|
return {
|
||||||
|
require=function(query)
|
||||||
|
if loaded[query] then return table.deepcopy(loaded[query]) end
|
||||||
|
local code,file=search_module(query,config)
|
||||||
|
if code==nil then
|
||||||
|
error(file)
|
||||||
|
end
|
||||||
|
local ok,_,lib=pcall(pcall,code)
|
||||||
|
if ok then
|
||||||
|
log.log("Added: \""..query.."\" to require registry.")
|
||||||
|
loaded[query]=lib
|
||||||
|
return table.deepcopy(lib), file
|
||||||
|
else
|
||||||
|
log.warn("ERR in module "..file)
|
||||||
|
return nil, "ERR in module "..file.."."
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
load=function(query, lib)
|
||||||
|
loaded[query]=lib
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
list=function()
|
||||||
|
local list={}
|
||||||
|
for i,v in pairs(loaded) do
|
||||||
|
list[#list+1]={i=i,v=v}
|
||||||
|
end
|
||||||
|
local i=0
|
||||||
|
while i<#list do
|
||||||
|
i=i+1
|
||||||
|
return list[i].i, list[i].v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
0
AceVM/disks/1h/sys/system/sysinit.sys
Normal file
0
AceVM/disks/1h/sys/system/sysinit.sys
Normal file
152
AceVM/disks/1h/sys/system/system.sys
Normal file
152
AceVM/disks/1h/sys/system/system.sys
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local fs=require("filesystem")
|
||||||
|
--local sfs=fs.getSudo(args.masterKey)
|
||||||
|
local auth=require("auth")
|
||||||
|
local system={}
|
||||||
|
local uuid=-1
|
||||||
|
local computer=component.getFirst("computer")
|
||||||
|
local time=computer.time()
|
||||||
|
local tasks={}
|
||||||
|
local currentTask={}
|
||||||
|
|
||||||
|
system.version="1.0.0"
|
||||||
|
system.name="HyperionOS"
|
||||||
|
-- Task status
|
||||||
|
-- "R" | Runnable/Running
|
||||||
|
-- "S" | Sleeping/Waiting
|
||||||
|
-- "P" | Stopped/Paused
|
||||||
|
-- "Z" | Exited/Zombie
|
||||||
|
-- "E" | Errored
|
||||||
|
-- "T" | Terminate
|
||||||
|
-- "X" | Marked for GC
|
||||||
|
|
||||||
|
local function UUID()
|
||||||
|
uuid=uuid+1
|
||||||
|
return tostring(uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.createTaskFromFunc(func, name, ...)
|
||||||
|
local id=UUID()
|
||||||
|
local fargs={...}
|
||||||
|
local task={}
|
||||||
|
local handle={}
|
||||||
|
task={
|
||||||
|
sleep=0,
|
||||||
|
state="N",
|
||||||
|
thread=coroutine.create(function()
|
||||||
|
local ret={pcall(func, table.unpack(fargs))}
|
||||||
|
local ok, tret = ret[1], {table.unpack(ret,2)}
|
||||||
|
if not ok then
|
||||||
|
task.state="E"
|
||||||
|
task.exit_state=tret[1]
|
||||||
|
task.exit_code=1
|
||||||
|
else
|
||||||
|
if #tret>0 then
|
||||||
|
task.state="Z"
|
||||||
|
task.exit_state=tret
|
||||||
|
task.exit_code=0
|
||||||
|
else
|
||||||
|
task.state="X"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
PID=id,
|
||||||
|
name=name,
|
||||||
|
comm=string.sub(name, 1, 32),
|
||||||
|
parent=currentTask,
|
||||||
|
chlidren={},
|
||||||
|
sibling=currentTask.chlidren,
|
||||||
|
files={},
|
||||||
|
nvcsw=0,
|
||||||
|
nivcsw=0,
|
||||||
|
handle=handle,
|
||||||
|
start_time=computer.time()
|
||||||
|
}
|
||||||
|
tasks[id]=task
|
||||||
|
local close=false
|
||||||
|
function handle.exists()
|
||||||
|
return not close
|
||||||
|
end
|
||||||
|
function handle.kill()
|
||||||
|
close=true
|
||||||
|
task.state="T"
|
||||||
|
end
|
||||||
|
function handle.pause()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
if task.state=="R" then
|
||||||
|
task.state="P"
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function handle.resume()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
if task.state=="P" then
|
||||||
|
task.state="R"
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function handle.getPID()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.PID
|
||||||
|
end
|
||||||
|
function handle.getParent()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.parent.PID
|
||||||
|
end
|
||||||
|
function handle.getChildren()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.chlidren) do
|
||||||
|
ret[#ret+1] = v.PID
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
function handle.getState()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.state
|
||||||
|
end
|
||||||
|
return handle
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.createTaskFromFile(path, name, ...)
|
||||||
|
local file = fs.open(path, "x")
|
||||||
|
return system.createTaskFromFunc(file, name, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.getTaskInfo(pid)
|
||||||
|
local task = tasks[pid]
|
||||||
|
if task == nil then return "No task with id "..pid end
|
||||||
|
return {
|
||||||
|
PID=task.PID,
|
||||||
|
parent=task.parent.PID,
|
||||||
|
sibling=(function()
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.sibling) do
|
||||||
|
ret[#ret+1] = i
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end)(),
|
||||||
|
chlidren=(function()
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.chlidren) do
|
||||||
|
ret[#ret+1] = i
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end)(),
|
||||||
|
name=task.name,
|
||||||
|
state=task.state,
|
||||||
|
nvcsw=task.nvcsw,
|
||||||
|
nivcsw=task.nivcsw,
|
||||||
|
start_time=task.start_time
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.getCurrentTask()
|
||||||
|
return system.getTaskInfo(currentTask.PID)
|
||||||
|
end
|
||||||
|
|
||||||
1
AceVM/disks/1h/var/log/kernel/bootData
Normal file
1
AceVM/disks/1h/var/log/kernel/bootData
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{["errorCount"]=4,["prevError"]=[=[random panic for testing purposes]=],["mode"]=[=["CLI"]=]}
|
||||||
0
AceVM/disks/2f/burn.lua
Normal file
0
AceVM/disks/2f/burn.lua
Normal file
BIN
AceVM/disks/56u
Normal file
BIN
AceVM/disks/56u
Normal file
Binary file not shown.
153
AceVM/init
153
AceVM/init
@@ -1,25 +1,9 @@
|
|||||||
local function deepcopy(orig, copies)
|
aceVM = {}
|
||||||
copies = copies or {}
|
aceVM.components={}
|
||||||
|
aceVM.aceKeys={}
|
||||||
if type(orig) ~= 'table' then
|
aceVM.aceKeys[keys.enter]="\n"
|
||||||
return orig
|
aceVM.aceKeys[keys.backspace]="\b"
|
||||||
elseif copies[orig] then
|
aceVM.aceKeys[keys.tab]="\t"
|
||||||
return copies[orig]
|
|
||||||
end
|
|
||||||
|
|
||||||
local copy = {}
|
|
||||||
copies[orig] = copy
|
|
||||||
|
|
||||||
for k, v in next, orig, nil do
|
|
||||||
local copied_key = deepcopy(k, copies)
|
|
||||||
local copied_val = deepcopy(v, copies)
|
|
||||||
copy[copied_key] = copied_val
|
|
||||||
end
|
|
||||||
|
|
||||||
return copy
|
|
||||||
end
|
|
||||||
local _VG = deepcopy(_G)
|
|
||||||
_VG._G=_VG
|
|
||||||
|
|
||||||
function string.split(str, delim, maxResultCountOrNil)
|
function string.split(str, delim, maxResultCountOrNil)
|
||||||
assert(#delim == 1, "only delim len 1 supported for now")
|
assert(#delim == 1, "only delim len 1 supported for now")
|
||||||
@@ -39,64 +23,29 @@ function string.split(str, delim, maxResultCountOrNil)
|
|||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
function _VG.sleep(nTime)
|
aceVM.INTERNAL_EVENT_QUEUE={}
|
||||||
local timer = os.startTimer(nTime or 0)
|
aceVM.INTERNAL_COMPONENT_REGESTRY={}
|
||||||
repeat
|
aceVM.INTERNAL_RUNTIME_FUNCTIONS={}
|
||||||
local _, param = coroutine.yield("timer")
|
aceVM.BIOS_CORO=nil
|
||||||
until param == timer
|
|
||||||
|
function aceVM.addEventRaw(...)
|
||||||
|
aceVM.INTERNAL_EVENT_QUEUE[#aceVM.INTERNAL_EVENT_QUEUE+1] = {...}
|
||||||
end
|
end
|
||||||
|
|
||||||
INTERNAL_DISKS={}
|
function aceVM.newComponent(type, object)
|
||||||
INTERNAL_SCREENS={}
|
local id = #aceVM.INTERNAL_COMPONENT_REGESTRY+1
|
||||||
INTERNAL_NET={}
|
aceVM.INTERNAL_COMPONENT_REGESTRY[id] = {type=type, object=object}
|
||||||
INTERNAL_EVENT_QUEUE={}
|
aceVM.addEventRaw("componentAdded", type, object)
|
||||||
INTERNAL_COMPONENT_REGESTRY={}
|
|
||||||
INTERNAL_RUNTIME_FUNCTIONS={}
|
|
||||||
BIOS_CORO=nil
|
|
||||||
|
|
||||||
function addEventRaw(...)
|
|
||||||
INTERNAL_EVENT_QUEUE[#INTERNAL_EVENT_QUEUE+1] = {...}
|
|
||||||
end
|
|
||||||
|
|
||||||
function newComponent(type, object)
|
|
||||||
local id = #INTERNAL_COMPONENT_REGESTRY+1
|
|
||||||
INTERNAL_COMPONENT_REGESTRY[id] = {type=type, object=object}
|
|
||||||
addEventRaw("componentAdded", type, object)
|
|
||||||
return {
|
return {
|
||||||
remove=function()
|
remove=function()
|
||||||
INTERNAL_COMPONENT_REGESTRY[id]=nil
|
aceVM.INTERNAL_COMPONENT_REGESTRY[id]=nil
|
||||||
addEventRaw("componentRemoved", type)
|
aceVM.addEventRaw("componentRemoved", type)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function addRuntimeFunction(func)
|
function aceVM.addRuntimeFunction(func)
|
||||||
INTERNAL_RUNTIME_FUNCTIONS[#INTERNAL_RUNTIME_FUNCTIONS+1] = func
|
aceVM.INTERNAL_RUNTIME_FUNCTIONS[#aceVM.INTERNAL_RUNTIME_FUNCTIONS+1] = func
|
||||||
end
|
|
||||||
|
|
||||||
_VG.component={}
|
|
||||||
|
|
||||||
function _VG.component.list()
|
|
||||||
local i = 0
|
|
||||||
return function()
|
|
||||||
i=i+1
|
|
||||||
if INTERNAL_COMPONENT_REGESTRY[i] then
|
|
||||||
return INTERNAL_COMPONENT_REGESTRY[i]["type"], INTERNAL_COMPONENT_REGESTRY[i]["object"]
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function _VG.component.getFirst(type)
|
|
||||||
local object={}
|
|
||||||
for i,v in pairs(INTERNAL_COMPONENT_REGESTRY) do
|
|
||||||
if INTERNAL_COMPONENT_REGESTRY[i].type == type then
|
|
||||||
object=INTERNAL_COMPONENT_REGESTRY[i]
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return object["object"]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,v in ipairs(fs.list("/AceVM/components/")) do
|
for i,v in ipairs(fs.list("/AceVM/components/")) do
|
||||||
@@ -106,19 +55,46 @@ for i,v in ipairs(fs.list("/AceVM/components/")) do
|
|||||||
load(code)()
|
load(code)()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function aceVM.initComponents(id)
|
||||||
|
for i,v in pairs(aceVM.components) do
|
||||||
|
aceVM.components[i](id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local file=fs.open("/computers/0/bios.lua","r")
|
function aceVM.start(id, disks)
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1,1)
|
||||||
|
aceVM.INTERNAL_COMPONENT_REGESTRY={}
|
||||||
|
aceVM.BIOS_CORO=coroutine.create(function()end)
|
||||||
|
aceVM.INTERNAL_EVENT_QUEUE={}
|
||||||
|
aceVM.INTERNAL_RUNTIME_FUNCTIONS={}
|
||||||
|
print("reset internals")
|
||||||
|
aceVM.id=id
|
||||||
|
aceVM.initVenv()
|
||||||
|
print("created Venv")
|
||||||
|
aceVM.initDisks(disks)
|
||||||
|
print("added disks")
|
||||||
|
aceVM.initComponents(id)
|
||||||
|
print("added components")
|
||||||
|
local file=fs.open("/AceVM/computers/"..tostring(id).."/bios.lua","r")
|
||||||
local bios=file.readAll()
|
local bios=file.readAll()
|
||||||
file.close()
|
file.close()
|
||||||
file=nil
|
file=nil
|
||||||
local func = load(bios,"@bios",nil,_VG)
|
print("loaded bios")
|
||||||
|
local func = load(bios,"@bios",nil,aceVM._VG)
|
||||||
if not func then error("BIOS ERR") end
|
if not func then error("BIOS ERR") end
|
||||||
local BIOS_CORO = coroutine.create(func)
|
aceVM.BIOS_CORO = coroutine.create(func)
|
||||||
debug.sethook(BIOS_CORO, function() coroutine.yield("CC:TWEAKED", "CORO_TIMEOUT") end, "l", 20)
|
print("created coroutine")
|
||||||
while true do
|
debug.sethook(aceVM.BIOS_CORO, function() coroutine.yield("CC:TWEAKED", "CORO_TIMEOUT") end, "l", 30000000)
|
||||||
local ret = {coroutine.resume(BIOS_CORO)}
|
print("added hook")
|
||||||
|
print("starting VM")
|
||||||
|
sleep(0.3)
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1,1)
|
||||||
|
while not aceVM.exitVM do
|
||||||
|
local ret = {coroutine.resume(aceVM.BIOS_CORO)}
|
||||||
if ret[1] == false then
|
if ret[1] == false then
|
||||||
os.shutdown()
|
break
|
||||||
end
|
end
|
||||||
local timer = os.startTimer(0)
|
local timer = os.startTimer(0)
|
||||||
local exit = false
|
local exit = false
|
||||||
@@ -126,16 +102,23 @@ while true do
|
|||||||
local event = {coroutine.yield()}
|
local event = {coroutine.yield()}
|
||||||
if event[1] == "timer" and event[2]==timer then
|
if event[1] == "timer" and event[2]==timer then
|
||||||
exit=true
|
exit=true
|
||||||
elseif event[1]=="timer"or nil then
|
elseif event[1]==nil then
|
||||||
elseif event[1]=="key" then
|
elseif event[1]=="key" then
|
||||||
addEventRaw("keyPressed", 1, event[2])
|
aceVM.addEventRaw("keyPressed", 1, event[2])
|
||||||
if akeys[event[2]] then
|
if aceVM.aceKeys[event[2]] then
|
||||||
addEventRaw("keyTyped", 1, akeys[event[2]])
|
aceVM.addEventRaw("keyTyped", 1, aceVM.aceKeys[event[2]])
|
||||||
end
|
end
|
||||||
elseif event[1]=="char" then
|
elseif event[1]=="char" then
|
||||||
addEventRaw("keyTyped", 1, event[2])
|
aceVM.addEventRaw("keyTyped", 1, event[2])
|
||||||
elseif event[1]=="key_up" then
|
elseif event[1]=="key_up" then
|
||||||
addEventRaw("keyReleased", 1, event[2])
|
aceVM.addEventRaw("keyReleased", 1, event[2])
|
||||||
end
|
end
|
||||||
until exit
|
until exit
|
||||||
|
for i,v in ipairs(aceVM.INTERNAL_RUNTIME_FUNCTIONS) do
|
||||||
|
v()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
aceVM.exitVM = false
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1,1)
|
||||||
end
|
end
|
||||||
112
aceVM.lua
Normal file
112
aceVM.lua
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
local args = {...}
|
||||||
|
local file = fs.open("/AceVM/config.ltable", "r")
|
||||||
|
local config = load("return "..file.readAll())()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
local function t2t(table)
|
||||||
|
local output = "{"
|
||||||
|
for i,v in pairs(table) do
|
||||||
|
local coma=true
|
||||||
|
if type(i) == "string" then
|
||||||
|
output=output.."[\""..i.."\"]="
|
||||||
|
end
|
||||||
|
if type(v) == "table" then
|
||||||
|
if v == table then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
else
|
||||||
|
output=output..t2t(v)
|
||||||
|
end
|
||||||
|
elseif type(v) == "string" then
|
||||||
|
output=output.."[=["..v.."]=]"
|
||||||
|
elseif type(v) == "number" then
|
||||||
|
output=output..tostring(v)
|
||||||
|
elseif type(v) == "function" then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
end
|
||||||
|
if coma then
|
||||||
|
output=output..","
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #table>0 or string.sub(output,#output,#output) == "," then
|
||||||
|
output=string.sub(output,1,#output-1)
|
||||||
|
end
|
||||||
|
output=output.."}"
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
local function save()
|
||||||
|
local file = fs.open("/AceVM/config.ltable", "w")
|
||||||
|
file.write(t2t(config))
|
||||||
|
file.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function hasVal(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if v==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if args[1] == "start" then
|
||||||
|
aceVM.start(config.computer, config.disks)
|
||||||
|
elseif args[1] == "disk" then
|
||||||
|
if args[2] == "create" then
|
||||||
|
if args[3] == "udd" then
|
||||||
|
local file = fs.open("/AceVM/disks/"..args[4].."u", "w")
|
||||||
|
file.write(string.rep("\0", 102400))
|
||||||
|
file.close()
|
||||||
|
elseif args[3] == "hdd" then
|
||||||
|
fs.makeDir("/AceVM/disks/"..args[4].."h/")
|
||||||
|
elseif args[3] == "fdd" then
|
||||||
|
fs.makeDir("/AceVM/disks/"..args[4].."f/")
|
||||||
|
else
|
||||||
|
print("Invailid option: aceVM create [type] [diskID]")
|
||||||
|
print("Types:")
|
||||||
|
print(" hdd")
|
||||||
|
print(" fdd")
|
||||||
|
print(" udd")
|
||||||
|
end
|
||||||
|
elseif args[2] == "delete" then
|
||||||
|
if fs.exists("/AceVM/disks/"..args[3].."h") then
|
||||||
|
fs.delete("/AceVM/disks/"..args[3].."h")
|
||||||
|
elseif fs.exists("/AceVM/disks/"..args[3].."f") then
|
||||||
|
fs.delete("/AceVM/disks/"..args[3].."f")
|
||||||
|
elseif fs.exists("/AceVM/disks/"..args[3].."u") then
|
||||||
|
fs.delete("/AceVM/disks/"..args[3].."u")
|
||||||
|
else
|
||||||
|
print("Invailid option: aceVM delete [diskID]")
|
||||||
|
end
|
||||||
|
elseif args[2] == "enable" then
|
||||||
|
if fs.exists("/AceVM/disks/"..args[3].."h") then
|
||||||
|
if hasVal(config.disks, tonumber(args[3])) then
|
||||||
|
print("Disk is already enabled")
|
||||||
|
else
|
||||||
|
config.disks[#config.disks+1] = tonumber(args[3])
|
||||||
|
save()
|
||||||
|
print("enabled disk "..args[3])
|
||||||
|
end
|
||||||
|
elseif fs.exists("/AceVM/disks/"..args[3].."f") then
|
||||||
|
if hasVal(config.disks, tonumber(args[3])) then
|
||||||
|
print("Disk is already enabled")
|
||||||
|
else
|
||||||
|
config.disks[#config.disks+1] = tonumber(args[3])
|
||||||
|
save()
|
||||||
|
print("enabled disk "..args[3])
|
||||||
|
end
|
||||||
|
elseif fs.exists("/AceVM/disks/"..args[3].."u") then
|
||||||
|
if hasVal(config.disks, tonumber(args[3])) then
|
||||||
|
print("Disk is already enabled")
|
||||||
|
else
|
||||||
|
config.disks[#config.disks+1] = tonumber(args[3])
|
||||||
|
save()
|
||||||
|
print("enabled disk "..args[3])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Invailid option: aceVM enable [diskID]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
48
component_docs.txt
Normal file
48
component_docs.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
disk:
|
||||||
|
open(path).
|
||||||
|
read()
|
||||||
|
write(text)
|
||||||
|
append(text)
|
||||||
|
list(path)
|
||||||
|
fileExists(path)
|
||||||
|
directoryExists(path)
|
||||||
|
makeDirectory(path)
|
||||||
|
delete(path)
|
||||||
|
copy(path)
|
||||||
|
move(path)
|
||||||
|
getSize(path)
|
||||||
|
type -> "hdd" | "fdd" | "udd"
|
||||||
|
id -> "disk_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
|
|
||||||
|
computer.
|
||||||
|
time()
|
||||||
|
setData(address, data)
|
||||||
|
getData(address)
|
||||||
|
saveData()
|
||||||
|
beep(freq, length)
|
||||||
|
getMachineEvent()
|
||||||
|
shutdown()
|
||||||
|
rebbot()
|
||||||
|
|
||||||
|
screen.
|
||||||
|
print(...)
|
||||||
|
printInline(...)
|
||||||
|
clear()
|
||||||
|
id -> "screen_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
|
|
||||||
|
internet:
|
||||||
|
get(url)
|
||||||
|
|
||||||
|
bios.
|
||||||
|
getData()
|
||||||
|
setData(text)
|
||||||
|
id -> "bios"
|
||||||
|
|
||||||
|
uDisk: labeled disk
|
||||||
|
readBytes(start, length)
|
||||||
|
writeBytes(data)
|
||||||
|
getSize()
|
||||||
|
id -> "disk_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
268
mbs.lua
Normal file
268
mbs.lua
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
local arg = table.pack(...)
|
||||||
|
local root_dir = settings.get("mbs.install_path", ".mbs")
|
||||||
|
local rom_dir = "rom/.mbs"
|
||||||
|
local install_dir = fs.exists(root_dir) and root_dir or rom_dir
|
||||||
|
local repo_url = "https://raw.githubusercontent.com/SquidDev-CC/mbs/master/"
|
||||||
|
|
||||||
|
--- Write a string with the given colour to the terminal
|
||||||
|
local function write_coloured(colour, text)
|
||||||
|
local old = term.getTextColour()
|
||||||
|
term.setTextColour(colour)
|
||||||
|
io.write(text)
|
||||||
|
term.setTextColour(old)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Print usage for this program
|
||||||
|
local commands = { "install", "modules", "module", "download" }
|
||||||
|
local function print_usage()
|
||||||
|
local name = fs.getName(shell.getRunningProgram()):gsub("%.lua$", "")
|
||||||
|
write_coloured(colours.cyan, name .. " modules ") io.write("Print the status of all modules\n")
|
||||||
|
write_coloured(colours.cyan, name .. " module ") io.write("Print information about a given module\n")
|
||||||
|
write_coloured(colours.cyan, name .. " install ") io.write("Download all modules and create a startup file\n")
|
||||||
|
write_coloured(colours.cyan, name .. " download ") io.write("Download all modules WITHOUT creating a startup file\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Attempt to load a module from the given path, returning the module or false
|
||||||
|
-- and an error message.
|
||||||
|
local function load_module(path)
|
||||||
|
if fs.isDir(path) then return false, "Invalid module (is directory)" end
|
||||||
|
|
||||||
|
local fn, err = loadfile(path, _ENV)
|
||||||
|
if not fn then return false, "Invalid module (" .. err .. ")" end
|
||||||
|
|
||||||
|
local ok, res = pcall(fn)
|
||||||
|
if not ok then return false, "Invalid module (" .. res .. ")" end
|
||||||
|
|
||||||
|
if type(res) ~= "table" or type(res.description) ~= "string" or type(res.enabled) ~= "function" then
|
||||||
|
return false, "Malformed module"
|
||||||
|
end
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Setup all modules
|
||||||
|
local function setup_module(module)
|
||||||
|
for _, setting in ipairs(module.settings) do
|
||||||
|
if settings.define then
|
||||||
|
settings.define(setting.name, {
|
||||||
|
description = setting.description,
|
||||||
|
type = setting.type,
|
||||||
|
default = setting.default,
|
||||||
|
})
|
||||||
|
elseif settings.get(setting.name) == nil then
|
||||||
|
settings.set(setting.name, setting.default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Download a set of files
|
||||||
|
local function download_files(files)
|
||||||
|
if #files == 0 then return end
|
||||||
|
|
||||||
|
local urls = {}
|
||||||
|
for _, file in ipairs(files) do
|
||||||
|
local url = repo_url .. file
|
||||||
|
http.request(url)
|
||||||
|
urls[url] = file
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local event, url, arg1 = os.pullEvent()
|
||||||
|
if event == "http_success" and urls[url] then
|
||||||
|
local handle = fs.open(fs.combine(root_dir, urls[url]), "w")
|
||||||
|
handle.write(arg1.readAll())
|
||||||
|
handle.close()
|
||||||
|
arg1.close()
|
||||||
|
|
||||||
|
urls[url] = nil
|
||||||
|
if next(urls) == nil then return end
|
||||||
|
elseif event == "http_failure" and urls[url] then
|
||||||
|
error("Could not download " .. urls[url], 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- read completion helper, completes text using the given options
|
||||||
|
local function complete_multi(text, options, add_spaces)
|
||||||
|
local results = {}
|
||||||
|
for n = 1, #options do
|
||||||
|
local option = options[n]
|
||||||
|
if #option + (add_spaces and 1 or 0) > #text and option:sub(1, #text) == text then
|
||||||
|
local result = option:sub(#text + 1)
|
||||||
|
if add_spaces then
|
||||||
|
results[#results + 1] = result .. " "
|
||||||
|
else
|
||||||
|
results[#results + 1] = result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Append an object to a list if it is not already contained within
|
||||||
|
local function add_unique(list, x)
|
||||||
|
for i = 1, #list do if list[i] == x then return end end
|
||||||
|
list[#list + 1] = x
|
||||||
|
end
|
||||||
|
|
||||||
|
local function load_all_modules()
|
||||||
|
-- Load all modules and update them.
|
||||||
|
local module_dir = fs.combine(root_dir, "modules")
|
||||||
|
local modules = fs.isDir(module_dir) and fs.list(module_dir) or {}
|
||||||
|
|
||||||
|
-- Add the default modules if not already there.
|
||||||
|
for _, module in ipairs { "lua.lua", "pager.lua", "readline.lua", "shell.lua" } do
|
||||||
|
add_unique(modules, module)
|
||||||
|
end
|
||||||
|
|
||||||
|
local files = {}
|
||||||
|
for i = 1, #modules do files[i] = "modules/" .. modules[i] end
|
||||||
|
download_files(files)
|
||||||
|
|
||||||
|
-- Scan for dependencies in enabled modules, downloading them as well
|
||||||
|
local deps = {}
|
||||||
|
for i = 1, #files do
|
||||||
|
local module = load_module(fs.combine(root_dir, files[i]))
|
||||||
|
if module then
|
||||||
|
setup_module(module)
|
||||||
|
if module.enabled() then
|
||||||
|
for _, dep in ipairs(module.dependencies) do deps[#deps + 1] = dep end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
download_files(deps)
|
||||||
|
end
|
||||||
|
|
||||||
|
if arg.n == 0 then
|
||||||
|
printError("Expected some command")
|
||||||
|
print_usage()
|
||||||
|
error()
|
||||||
|
elseif arg[1] == "download" then
|
||||||
|
load_all_modules()
|
||||||
|
elseif arg[1] == "install" then
|
||||||
|
load_all_modules()
|
||||||
|
|
||||||
|
-- Move the existing startup file. We have to read the whole thing,
|
||||||
|
-- as otherwise we'd end up copying inside ourselves.
|
||||||
|
if fs.exists("startup") and not fs.isDir("startup") then
|
||||||
|
write_coloured(colours.cyan, "Moving your existing startup file to startup/30_startup.lua.\n")
|
||||||
|
|
||||||
|
local handle = fs.open("startup", "r")
|
||||||
|
local contents = handle.readAll()
|
||||||
|
handle.close()
|
||||||
|
fs.delete("startup")
|
||||||
|
|
||||||
|
handle = fs.open("startup/30_startup.lua", "w")
|
||||||
|
handle.write(contents)
|
||||||
|
handle.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Also move the startup.lua file afterwards
|
||||||
|
if fs.exists("startup.lua") and not fs.isDir("startup.lua") then
|
||||||
|
write_coloured(colours.cyan, "Moving your existing startup.lua file to startup/31_startup.lua.\n")
|
||||||
|
fs.move("startup.lua", "startup/31_startup.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
if fs.exists("startup/99_mbs.lua") then
|
||||||
|
write_coloured(colours.cyan, "Deleting the old startup/99_mbs.lua file. We now run before other startup files.\n")
|
||||||
|
fs.delete("startup/99_mbs.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We'll run at the first possible position to ensure
|
||||||
|
local handle = fs.open("startup/00_mbs.lua", "w")
|
||||||
|
local current = shell.getRunningProgram()
|
||||||
|
handle.writeLine(("assert(loadfile(%q, _ENV))('startup', %q)"):format(current, current))
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
write_coloured(colours.green, "Installed! ")
|
||||||
|
io.write("Please reboot to apply changes.\n")
|
||||||
|
elseif arg[1] == "startup" then
|
||||||
|
-- Gather a list of all modules
|
||||||
|
local module_dir = fs.combine(install_dir, "modules")
|
||||||
|
local files = fs.isDir(module_dir) and fs.list(module_dir) or {}
|
||||||
|
|
||||||
|
-- Load those modules and determine which are enabled.
|
||||||
|
local enabled = {}
|
||||||
|
local module_names = {}
|
||||||
|
for _, file in ipairs(files) do
|
||||||
|
local module = load_module(fs.combine(module_dir, file))
|
||||||
|
if module then
|
||||||
|
setup_module(module)
|
||||||
|
module_names[#module_names + 1] = file:gsub("%.lua$", "")
|
||||||
|
if module.enabled() then enabled[#enabled + 1] = module end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local current = arg[2] or shell.getRunningProgram()
|
||||||
|
shell.setCompletionFunction(current, function(_, index, text, previous)
|
||||||
|
if index == 1 then
|
||||||
|
return complete_multi(text, commands, true)
|
||||||
|
elseif index == 2 and previous[#previous] == "module" then
|
||||||
|
return complete_multi(text, module_names, false)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Setup those modules
|
||||||
|
for _, module in ipairs(enabled) do
|
||||||
|
if type(module.setup) == "function" then module.setup(install_dir) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- And run the startup hook if needed
|
||||||
|
for _, module in ipairs(enabled) do
|
||||||
|
if type(module.startup) == "function" then module.startup(install_dir) end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif arg[1] == "modules" then
|
||||||
|
local module_dir = fs.combine(install_dir, "modules")
|
||||||
|
local files = fs.isDir(module_dir) and fs.list(module_dir) or {}
|
||||||
|
local found_any = false
|
||||||
|
|
||||||
|
for _, file in ipairs(files) do
|
||||||
|
local res, err = load_module(fs.combine(module_dir, file))
|
||||||
|
write_coloured(colours.cyan, file:gsub("%.lua$", "") .. " ")
|
||||||
|
if res then
|
||||||
|
write(res.description)
|
||||||
|
if res.enabled() then
|
||||||
|
write_coloured(colours.green, " (enabled)")
|
||||||
|
else
|
||||||
|
write_coloured(colours.red, " (disabled)")
|
||||||
|
end
|
||||||
|
found_any = true
|
||||||
|
else
|
||||||
|
write_coloured(colours.red, err)
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not found_any then error("No modules found. Maybe try running the `install` command?", 0) end
|
||||||
|
elseif arg[1] == "module" then
|
||||||
|
if not arg[2] then error("Expected module name", 0) end
|
||||||
|
local module, err = load_module(fs.combine(install_dir, fs.combine("modules", arg[2] .. ".lua")))
|
||||||
|
if not module then error(err, 0) end
|
||||||
|
|
||||||
|
io.write(module.description)
|
||||||
|
if module.enabled() then
|
||||||
|
write_coloured(colours.green, " (enabled)")
|
||||||
|
else
|
||||||
|
write_coloured(colours.red, " (disabled)")
|
||||||
|
end
|
||||||
|
io.write("\n\n")
|
||||||
|
|
||||||
|
for _, setting in ipairs(module.settings) do
|
||||||
|
local value = settings.get(setting.name)
|
||||||
|
write_coloured(colours.cyan, setting.name)
|
||||||
|
io.write(" " .. setting.description .. " (")
|
||||||
|
write_coloured(colours.yellow, textutils.serialise(value))
|
||||||
|
if value ~= setting.default then
|
||||||
|
io.write(", default is \n")
|
||||||
|
write_coloured(colours.yellow, textutils.serialise(setting.default))
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(")\n")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
printError("Unknown command")
|
||||||
|
print_usage()
|
||||||
|
error()
|
||||||
|
end
|
||||||
1
startup/00_mbs.lua
Normal file
1
startup/00_mbs.lua
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--assert(loadfile("mbs.lua", _ENV))('startup', "mbs.lua")
|
||||||
1
startup/31_startup.lua
Normal file
1
startup/31_startup.lua
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dofile("AceVM/init")
|
||||||
Reference in New Issue
Block a user