I forgot you have to give it write permissions (minified)

This commit is contained in:
github-actions[bot]
2026-04-30 12:32:52 +00:00
parent 2a2b27a827
commit b08d7b3f98
44 changed files with 102 additions and 4919 deletions
+1 -691
View File
@@ -1,691 +1 @@
local packages = {...}
local command = packages[1]
table.remove(packages, 1)
local fs = import("filesystem")
local component = import("component")
local agReg = import("/argentum/registry.cfg")
if not command then
shell.run("help argentum")
return
end
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.")
return
end
local internet = component.internet
local source
if table.find(packages, "-s") then
source = table.remove(packages, table.find(packages, "-s") + 1)
table.remove(packages, table.find(packages, "-s"))
print("Using " .. source .. " as package source")
elseif table.find(packages, "--source") then
source = table.remove(packages, table.find(packages, "--source") + 1)
table.remove(packages, table.find(packages, "--source"))
print("Using " .. source .. " as package source")
else
print("Using main registry as package source")
end
if source and source:sub(1, 1) == "/" and source:sub(-1, -1) ~= "/" then
source = source .. "/"
end
local packageList = table.copy(packages)
local function getFile(path)
if path:sub(1,1) == "/" then
if not fs.exists(path) then
return false, "file does not exist"
end
local handle, data, tmpdata = fs.open(path, "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return data
else
local request, data, tmpdata = nil, "", nil
local status, errorMessage = pcall(function()
request = internet.request(path)
request:finishConnect()
end)
if not status then
return false, errorMessage
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
return false, responseCode
end
repeat
tmpdata = request.read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
return data
end
end
local i = 1
local function getAgConfig(package, source)
source = source or agReg[package]
local data, errorMessage = getFile(source .. "argentum.cfg")
if not data or data == "" then
print("\27[91mCould not fetch Ag config: " .. (errorMessage or "returned nil data"))
return false
end
local func, errorMessage = load(data, "=argentum.cfg", "bt", {})
if not func then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
return false
end
local agcfg
local status, errorMessage = pcall(function()
agcfg = func()
end)
if not status then
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
return false
end
if not agcfg[package] or not agcfg[package].maindir or not agcfg[package].directories or not agcfg[package].files or not agcfg[package].version then
local response = ("\27[91mAg config of " .. package .. " is improperly configured.\nPlease contact the package owner.")
end
return agcfg
end
local function doChecks(package)
if not agReg[package] and not source then
print("\27[91mPackage " .. package .. " does not exist.")
return false
end
if fs.exists("/argentum/store/" .. package) then
print("\27[91mPackage " .. package .. " is already installed.")
return false
end
agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = read(nil, "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]")
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
end
end
end
for _, dependency in pairs(agcfg[package].dependencies) do
print(package .. " depends on " .. dependency)
if not table.find(packages, dependency) and doChecks(dependency) then
table.insert(packages, table.find(packages, package), dependency)
table.insert(packageList, dependency)
i = i + 1
end
end
end
return true
end
local function lpad(str, len, char)
str=tostring(str)
if char == nil then char = ' ' end
return string.rep(char, len - #str) .. str
end
local gpu = component.gpu
local width,height = gpu.getResolution()
local function progress(package,progress)
local info = string.format("%s %s%%",package,lpad(math.floor(progress*100),2))
info=info..string.rep(" ",width-#info)
local progX = math.floor(progress*width)
gpu.setBackground(0x00FF00)
gpu.setForeground(0x000000)
gpu.set(1,height,info:sub(1,progX))
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.set(progX+1,height,info:sub(progX+1))
end
local function clearProgress()
gpu.setBackground(0x000000)
gpu.fill(1,height,width,1," ")
end
local function installPackage(package, overwriteFlag)
if not overwriteFlag then
overwriteFlag = false
end
if not overwriteFlag then print("Installing " .. package .. "...") end
local agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
local source = source or agReg[package]
local packageStore = "V" .. agcfg[package].version
if agcfg[package].dependencies then
for _, dependency in ipairs(agcfg[package].dependencies) do
if not agReg[dependency] and not agcfg[dependency] then
local response = read(nil, "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]")
if response:lower() ~= "s" then
fs.remove("/argentum/store/" .. package)
return false
end
end
end
for _, dependency in pairs(agcfg[package].dependencies) do
if agReg[dependency] or agcfg[dependency] then
--installPackage(dependency)
packageStore = packageStore .. "\nD" .. dependency
end
end
end
if agcfg[package].directories then
for _, directory in pairs(agcfg[package].directories) do
if directory:sub(-1, -1) ~= "/" then
directory = directory .. "/"
end
packageStore = "A" .. directory .. "\n" .. packageStore
if not fs.exists(directory) then
fs.makeDirectory(directory)
end
end
end
for idx, file in ipairs(agcfg[package].files) do
clearProgress()
::retry::
print(" Downloading " .. file .. "...")
progress(package,idx/#agcfg[package].files)
local data, errorMessage = getFile(source .. agcfg[package].maindir .. file)
if not data then
clearProgress()
local response = read(nil, "\27[91mCould not fetch " .. file .. ": " .. errorMessage .. "\n\27[0m[a - Abort/R - Retry/s - Skip]")
if response:lower() == "a" then
fs.remove("/argentum/store/" .. package)
return false
elseif response:lower() == "s" then
goto skip
else
goto retry
end
end
if fs.exists(file) and not overwriteFlag then
if not fs.exists("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)")) then
fs.makeDirectory("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)"))
end
fs.copy(file, "/argentum/store/" .. package .. "/files/" .. file)
packageStore = packageStore .. "\nM" .. file
else
packageStore = packageStore .. "\nA" .. file
end
local handle = fs.open(file, "w")
handle:write(data)
handle:close()
::skip::
end
clearProgress()
fs.makeDirectory("/argentum/store/" .. package)
local handle = fs.open("/argentum/store/" .. package .. "/package.cfg", "w")
handle:write(packageStore)
handle:close()
return true
end
local function removePackage(package)
print("Removing " .. package .. "...")
if not fs.exists("/argentum/store/" .. package .. "/package.cfg") then
print("\27[91mLocal Ag config of " .. package .. " does not exist.")
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
data = data .. "\n"
local idx = 0
for line in data:gmatch("(.-)\n") do
idx=idx+1
if line:sub(1, 1) == "A" then
clearProgress()
::retry::
print(" Removing " .. line:sub(2) .. "...")
if line:sub(-1, -1) == "/" and fs.list(line:sub(2))[1] then
print(" There are still files in " .. line:sub(2) .. ". Skipping.")
else
progress(package,idx/select(2,data:gsub("\n","\n")))
local result, errorMessage = fs.remove(line:sub(2))
if not result then
clearProgress()
local response = read(nil, "\27[91mFailed to remove " .. line:sub(2) .. ": " .. errorMessage .. "\n\27[0m[a - Abort/r - Retry/S - Skip]")
if response:lower() == "a" then
return false
elseif response:lower() == "r" then
goto retry
end
end
end
elseif line:sub(1, 1) == "M" then
clearProgress()
::retry::
print(" Reverting " .. line:sub(2) .. "...")
progress(package,idx/select(2,data:gsub("\n","\n")))
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/files/" .. line:sub(2), "r"), "", nil
if not handle then
clearProgress()
local response = read(nil, "\27[91mFailed to revert " .. line:sub(2) .. ": " .. data .. "\n\27[0m[a - Abort/R - Retry/s - Skip]") -- this is pretty stupid but i think the error message would get pushed to data
if response:lower() == "a" then
return false
elseif response:lower() == "s" then
goto skip
else
goto retry
end
end
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local handle = fs.open(line:sub(2), "w")
handle:write(data)
handle:close()
::skip::
end
end
clearProgress()
fs.remove("/argentum/store/" .. package .. "/")
return true
end
local function updatePackage(package)
print("Updating " .. package .. "...")
local agcfg = getAgConfig(package, source)
if not agcfg then
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local oldFiles = {}
for line in (data .. "\n"):gmatch("(.-)\n") do
if line:sub(1, 1) == "A" or line:sub(1, 1) == "M" then
if agcfg[package].directories then
if not table.find(agcfg[package].files, line:sub(2)) and not table.find(agcfg[package].directories, line:sub(2, -2)) then
table.insert(oldFiles, line:sub(2))
end
else
if not table.find(agcfg[package].files, line:sub(2)) then
table.insert(oldFiles, line:sub(2))
end
end
end
end
for _, oldFile in pairs(oldFiles) do
print(" Removing " .. oldFile .. "...")
end
return installPackage(package, true)
end
local fails = {}
if command == "install" then
if not packages or not packages[1] then
print("Please specify packages to install.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = import("/argentum/registry.cfg")
while true do
if not doChecks(packages[i]) then
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
end
i = i + 1
if i > #packages then
break
end
end
local answer
if #fails == 0 then
print("Packages that will be installed: " .. table.concat(packageList, ", "))
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
return
end
elseif #packageList == 0 then
print("None of the packages can be installed.")
return
else
print("Some packages cannot be installed.")
print("Packages that will be installed: " .. table.concat(packageList, ", "))
print("Packages that cannot be installed: " .. table.concat(fails, ", "))
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in ipairs(packages) do
if not installPackage(package) then
table.insert(fails, package)
table.remove(packageList, table.find(packageList, package))
end
end
if #fails == 0 then
print("Installation completed successfully.")
print("Packages installed: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to install.")
print("Packages that could not be installed: " .. table.concat(fails, ", "))
else
print("Some packages failed to install.")
print("Packages installed: " .. table.concat(packageList, ", "))
print("Packages that could not be installed: " .. table.concat(fails, ", "))
end
elseif command == "remove" then
if not packages or not packages[1] then
print("Please specify packages to remove.")
return
end
while true do
if not fs.exists("/argentum/store/" .. packages[i]) then
print("\27[91mPackage " .. packages[i] .. " is not installed.")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "halyde" then -- yes, this stuff is hard-coded.
print("\27[91mFor obvious reasons, you can't uninstall Halyde.")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
elseif packages[i] == "argentum" then
print("\27[91mFor obvious reasons, you can't uninstall Argentum.")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
end
i = i + 1
if i > #packages then
break
end
end
-- do dependency checks
local packagesInstalled = fs.list("/argentum/store")
for _, currentPackage in pairs(packagesInstalled) do
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
local handle, data, tmpdata = fs.open("/argentum/store/" .. currentPackage .. "package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
for line in (data.."\n"):gmatch("(.-)\n") do
for i = 1, #packages do
if line == "D" .. packages[i] then
print(packages[i] .. " depends on " .. currentPackage:sub(1, -2))
if not table.find(packages, currentPackage:sub(1, -2)) then
table.insert(packages, table.find(packages, packages[i]), currentPackage:sub(1, -2))
table.insert(packageList, currentPackage:sub(1, -2))
i = i + 1
end
end
end
end
end
end
local answer
if #fails == 0 then
print("Packages that will be removed: " .. table.concat(packageList, ", "))
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
return
end
elseif #packageList == 0 then
print("None of the packages can be removed.")
return
else
print("Some packages cannot be removed.")
print("Packages that will be removed: " .. table.concat(packageList, ", "))
print("Packages that cannot be removed: " .. table.concat(fails, ", "))
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in ipairs(packages) do
if not removePackage(package) then
table.insert(fails, package)
table.remove(packageList, table.find(packageList, package))
end
end
if #fails == 0 then
print("Removal completed successfully.")
print("Packages removed: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to be removed.")
print("Packages that could not be removed: " .. table.concat(fails, ", "))
else
print("Some packages failed to be removed.")
print("Packages removed: " .. table.concat(packageList, ", "))
print("Packages that could not be removed: " .. table.concat(fails, ", "))
end
elseif command == "update" then
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = import("/argentum/registry.cfg")
if not packages[1] then
local packagesInstalled = fs.list("/argentum/store/")
for _, currentPackage in pairs(packagesInstalled) do
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
table.insert(packages, currentPackage:sub(1, -2))
table.insert(packageList, currentPackage:sub(1, -2))
end
end
end
while true do
local nonexistent = false -- I couldn't figure out a better way to do this, so I have to use a flag if the package doesn't exist
if not fs.exists("/argentum/store/" .. packages[i]) then
print("\27[91mPackage " .. packages[i] .. " is not installed.")
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
nonexistent = true
end
if not nonexistent then
-- Check if up to date
local agcfg = getAgConfig(packages[i], source)
if not agcfg then
return false
end
local handle, data, tmpdata = fs.open("/argentum/store/" .. packages[i] .. "/package.cfg", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local version = "0.0.0"
for line in (data.."\n"):gmatch("(.-)\n") do
if line:sub(1, 1) == "V" then
version = line:sub(2)
break
end
end
if agcfg[packages[i]].version == version then
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
i = i - 1
else
print(packages[i].." is out of date [\x1b[93m"..version.."\x1b[39m < \x1b[92m"..agcfg[packages[i]].version.."\x1b[39m]")
end
end
i = i + 1
if i > #packages then
break
end
end
local answer
if #packageList == 0 then
if #fails == 0 then
print("All packages are up to date.")
return
else
print("None of the packages can be updated.")
return
end
elseif #fails == 0 then
print("Packages that will be updated: " .. table.concat(packageList, ", "))
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
return
end
else
print("Some packages cannot be updated.")
print("Packages that will be updated: " .. table.concat(packageList, ", "))
print("Packages that cannot be updated: " .. table.concat(fails, ", "))
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
return
end
end
for _, failedPackage in pairs(fails) do
table.remove(packages, table.find(packages, failedPackage))
end
fails = {}
for _, package in pairs(packages) do
-- Previous up-to-date check
--local agcfg = getAgConfig(package, source)
--if not agcfg then
-- return false
--end
--local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
--repeat
-- tmpdata = handle:read(math.huge)
-- data = data .. (tmpdata or "")
--until not tmpdata
--handle:close()
--local version = "0.0.0"
--for line in (data.."\n"):gmatch("(.-)\n") do
-- if line:sub(1, 1) == "V" then
-- version = line:sub(2)
-- break
-- end
--end
--if agcfg[package].version == version then
-- print(package .. " is up to date")
-- goto skip
--end
if not updatePackage(package) then
table.insert(fails, packages[i])
table.remove(packageList, table.find(packageList, packages[i]))
table.remove(packages, table.find(packages, packages[i]))
goto skip
end
::skip::
end
if #fails == 0 then
print("Update completed successfully.")
print("Packages updated: " .. table.concat(packageList, ", "))
elseif #packageList == 0 then
print("All packages failed to update.")
print("Packages that could not update: " .. table.concat(fails, ", "))
else
print("Some packages failed to update.")
print("Packages updated: " .. table.concat(packageList, ", "))
print("Packages that could not update: " .. table.concat(fails, ", "))
end
elseif command == "info" then
if not packages[1] then
print("Please specify a package to show information about.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = import("/argentum/registry.cfg")
if not agReg[packages[1]] and not source then
print("\27[91mPackage " .. packages[1] .. " does not exist.")
return
end
local agcfg = getAgConfig(packages[1], source)
if not agcfg then
return false
end
print("\27[93m" .. packages[1] .. "\27[0m v" .. agcfg[packages[1]].version .. "\n " .. (agcfg[packages[1]].description or "No description."):gsub("\n", " \n"))
elseif command == "search" then
if not packages[1] then
print("Please specify a search term.")
return
end
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = import("/argentum/registry.cfg")
local searchResults = {}
for packageName, _ in pairs(agReg) do
if packageName:find(packages[1], 1, true) then
table.insert(searchResults, packageName)
end
end
if not searchResults[1] then
print("No search results found for " .. packages[1] .. ".")
return
end
table.sort(searchResults)
print("Search results: \n " .. table.concat(searchResults, "\n "))
elseif command == "list" then
print("Fetching Ag registry...")
local newRegistry, errorMessage = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum/registry.cfg")
if newRegistry then
local handle = fs.open("/argentum/registry.cfg", "w")
handle:write(newRegistry)
handle:close()
else
print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil"))
end
agReg = import("/argentum/registry.cfg")
local sortedPackages = {}
for packageName, _ in pairs(agReg) do
table.insert(sortedPackages, packageName)
end
table.sort(sortedPackages)
print("List of available Ag packages: \n " .. table.concat(sortedPackages, "\n "))
else
shell.run("help ag")
end
Error: no such file. (``)
+1 -60
View File
@@ -1,60 +1 @@
local component = import("component")
local computer = import("computer")
local args = {...}
local force = false
local forceArgIdx = table.find(args,"-f") or table.find(args,"--force")
if forceArgIdx then
table.remove(args,forceArgIdx)
force = true
end
local function getComponentID(str)
local function fromSlot(slot)
for i,v in component.list() do
if component.slot(i)==slot then
return i
end
end
end
if str=="hdd1" or str=="#1" then return fromSlot(5) end
if str=="hdd2" or str=="#2" then return fromSlot(6) end
if str=="floppy" or str=="#3" then return fromSlot(7) end
if #str<3 then return nil,"Abbreviated ID must atleast have 3 characters" end
return component.get(str)
end
local function fileExists(compID,file)
return component.invoke(compID,"exists",file) and not component.invoke(compID,"isDirectory",file)
end
if type(args[1])=="string" then
local compID,err = getComponentID(args[1])
if not compID then
print("\x1b[91mCould not get component ID from '"..args[1].."'.")
if type(err)=="string" then print("\x1b[91m"..err) end
return
end
if not force then
if componentlib.additions[compID] then
return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..compID)
end
local type = component.type(compID)
if type~="filesystem" and type~="drive" then
return print("\x1b[91mThis component is not a storage medium.\nID: "..compID)
end
if type=="filesystem" and not fileExists(compID,"/init.lua") then
return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..compID)
end
end
computer.setBootAddress(compID)
if computer.getBootAddress()~=compID then
return print("\x1b[91mFailed to set the boot address.")
end
computer.shutdown(true)
else
shell.run("help boot")
end
Error: no such file. (``)
+1 -20
View File
@@ -1,20 +1 @@
local files = {...}
local fs = import("filesystem")
if not files or not files[1] then
shell.run("help cat")
return
end
for _, file in ipairs(files) do
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.workingDirectory, file)
end
if not fs.exists(file) then
print("\27[91mFile does not exist.")
end
local handle = fs.open(file, "r")
local data
repeat
data = handle:read(math.huge or math.maxinteger)
termlib.write(data)
until not data
end
Error: no such file. (``)
+1 -14
View File
@@ -1,14 +1 @@
local directory = ...
local fs = import("filesystem")
if not directory then
return
end
if directory:sub(1, 1) ~= "/" then
directory = fs.concat(shell.workingDirectory, directory)
end
if fs.exists(directory) and fs.isDirectory(directory) then
shell.workingDirectory = fs.canonical(directory)
else
print("\27[91mNo such directory.")
end
Error: no such file. (``)
+1 -2
View File
@@ -1,2 +1 @@
clear()
-- truly so much going on here
Error: no such file. (``)
+1 -26
View File
@@ -1,26 +1 @@
local fromFile, toFile = ...
local fs = import("filesystem")
if not fromFile or not toFile then
shell.run("help cp")
return
end
if fromFile:sub(1, 1) ~= "/" then
fromFile = fs.concat(shell.workingDirectory, fromFile)
end
if toFile:sub(1, 1) ~= "/" then
toFile = fs.concat(shell.workingDirectory, toFile)
end
if fromFile == toFile then
print("\27[91mSource and destination are the same.")
return
end
if not fs.exists(fromFile) then
print("\27[91mSource file does not exist.")
return
end
if fs.exists(toFile) and not (table.find({...}, "-o") or table.find({...}, "--overwrite")) then
print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")
return
end
fs.copy(fromFile, toFile)
Error: no such file. (``)
+1 -57
View File
@@ -1,57 +1 @@
local url = ...
local component = import("component")
local fs = import("filesystem")
if not component.list("internet")() then
print("\27[91mThis program requires an internet card to run.")
return
end
if not url then
print("Please enter a URL to download from.")
shell.run("help download")
return
end
if url:sub(-1, -1) == "/" then
url = url:sub(1, -2)
end
local internet = component.internet
local request, data, tmpdata = nil, "", nil
local status, errorMessage = pcall(function()
request = internet.request(url)
request:finishConnect()
end)
if not status then
print("\27[91mDownload failed: " .. errorMessage)
end
local responseCode = request:response()
if responseCode and responseCode ~= 200 then
print("\27[91mDownload failed: " .. tostring(responseCode))
end
repeat
tmpdata = request.read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
local saveLocation
local saveLocationOK = false
repeat
saveLocation = read(nil, "File save location: ", fs.concat(shell.workingDirectory, url:match("/([^/]+)$")))
if fs.isDirectory(saveLocation) then
print("\27[91mThe specified location is a directory.")
elseif fs.exists(saveLocation) then
local answer = read(nil, "\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]")
if answer:lower() ~= "n" then
saveLocationOK = true
end
else
saveLocationOK = true
end
until saveLocationOK
local handle = fs.open(saveLocation, "w")
handle:write(data)
handle:close()
print("File downloaded successfully.")
Error: no such file. (``)
+1 -7
View File
@@ -1,7 +1 @@
local args = {...}
local concatText = args[1]
table.remove(args, 1)
for _, item in pairs(args) do
concatText = concatText .. " " .. item
end
print(concatText)
Error: no such file. (``)
+1 -351
View File
@@ -1,351 +1 @@
local file = ...
local fs = import("filesystem")
local event = import("event")
local component = import("component")
local unicode = import("unicode")
local gpu = component.gpu
local width, height = gpu.getResolution()
local scrollPosX, scrollPosY = 1, 1
local cursorPosX, cursorPosY = 1, 1
local cursorWhite = true
local changesMade = false
local renderBuffer = gpu.allocateBuffer()
local scrollSpeed = 5
local tab = " "
--local ocelot = component.ocelot
local function rawset(x, y, text)
termlib.cursorPosX = x
termlib.cursorPosY = y
termlib.write(text, false)
end
local filestring, filepath, handle, data, tmpdata
if file then
if file:sub(1, 1) == "/" then
filepath = file
else
filepath = shell.workingDirectory .. file
end
handle, data, tmpdata = fs.open(filepath, "r"), "", nil
if fs.exists(filepath) then
filestring = filepath
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = {}
if data:gmatch("(.-)\n")() then
for line in data:gmatch("(.-)\n") do
local newLine = line:gsub("\r", "") -- this took me SO LONG TO FIGURE OUT AAAAAAAA I HATE CRLF I HATE CRLF I HATE CRLF
table.insert(tmpdata, newLine)
end
else
tmpdata = {data}
end
else
filepath = shell.workingDirectory .. file
filestring = "[NEW FILE]"
tmpdata = {""}
end
else
filepath = ""
filestring = "[NEW FILE]"
tmpdata = {""}
end
local function render()
gpu.setActiveBuffer(renderBuffer)
clear()
--ocelot.log(tostring(scrollPosY))
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
for i = scrollPosY, height + scrollPosY - 3 do
gpu.set(1, i - scrollPosY + 1, (tmpdata[i] or ""):sub(scrollPosX))
end
rawset(1, height - 1, "\27[107m\27[30m" .. filestring .. string.rep(" ", width))
rawset(1, height, "\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save" .. string.rep(" ", width))
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setForeground(0)
gpu.setBackground(0xFFFFFF)
end
gpu.set(realCursorX, cursorPosY, char)
gpu.bitblt()
gpu.setActiveBuffer(0)
end
local renderFlag, cursorRenderFlag = false, false
local function scrollUp()
cursorPosY = cursorPosY - 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY < 1 then
renderFlag = true
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
renderFlag = false
scrollPosY = 1
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollDown()
cursorPosY = cursorPosY + 1
cursorRenderFlag = true
cursorWhite = true
if cursorPosY + scrollPosY - 1 > #tmpdata then
renderFlag = false
cursorPosY = #tmpdata - scrollPosY + 1
end
if cursorPosY > height - 2 then
renderFlag = true
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollLeft()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX > 1 then
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2 then
cursorPosX = cursorPosX - 1
elseif unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 > 1 then
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1
end
elseif scrollPosX > 1 then
scrollPosX = scrollPosX - 1
renderFlag = true
end
if math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2) < 1 then
renderFlag = true
end
end
local function scrollRight()
cursorRenderFlag = true
cursorWhite = true
if cursorPosX <= unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 1 then
cursorPosX = cursorPosX + 1
end
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
end
end
local function processEvent(args)
renderFlag, cursorRenderFlag = false, false
if args[1] == "key_down" then
local keycode = args[4]
local key = keyboard.keys[keycode]
if keyboard.ctrlDown then
return false, false, key
end
if key == "down" and cursorPosY < #tmpdata then
scrollDown()
end
if key == "up" then
scrollUp()
end
if key == "left" then
scrollLeft()
end
if key == "right" then
scrollRight()
end
if key == "enter" then
changesMade = true
renderFlag = true
cursorWhite = true
table.insert(tmpdata, cursorPosY + 1, tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX))
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX - 1)
cursorPosX = 1
cursorPosY = cursorPosY + 1
scrollPosX = 1
if cursorPosY > height - 2 then
scrollPosY = scrollPosY + 1
cursorPosY = height - 2
end
end
if key == "back" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
if cursorPosX == 1 and cursorPosY + scrollPosY - 1 > 1 then
cursorPosY = cursorPosY - 1
if cursorPosY < 1 then
scrollPosY = scrollPosY - 1
cursorPosY = 1
end
if scrollPosY < 1 then
scrollPosY = 1
end
cursorPosX = unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2
if cursorPosX > width then
scrollPosX = cursorPosX - width + 1
cursorPosX = width
end
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1] .. tmpdata[cursorPosY + 1]
table.remove(tmpdata, cursorPosY + 1)
renderFlag = true
else
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 3) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX - 1, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) + 1)
if cursorPosX < 1 then
cursorPosX = 1
scrollPosX = scrollPosX - 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX) .. " ")
end
end
end
if key == "tab" then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. tab .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = cursorPosX + unicode.wlen(tab)
if cursorPosX > width then
scrollPosX = scrollPosX + cursorPosX - width
cursorPosX = width
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
if args[3] >= 32 and args[3] <= 126 then
changesMade = true
cursorRenderFlag = true
cursorWhite = true
tmpdata[cursorPosY + scrollPosY - 1] = tmpdata[cursorPosY + scrollPosY - 1]:sub(1, cursorPosX + scrollPosX - 2) .. unicode.char(args[3]) .. tmpdata[cursorPosY + scrollPosY - 1]:sub(cursorPosX + scrollPosX - 1)
cursorPosX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1])) + 1
--ocelot.log(tostring(cursorPosX))
if cursorPosX > width then
cursorPosX = width
scrollPosX = scrollPosX + 1
renderFlag = true
else
gpu.set(1, cursorPosY, tmpdata[cursorPosY + scrollPosY - 1]:sub(scrollPosX))
end
end
elseif args[1] == "scroll" then
if args[5] == 1 then
for i = 1, scrollSpeed do
scrollUp()
end
elseif args[5] == -1 and cursorPosY < #tmpdata then
for i = 1, scrollSpeed do
scrollDown()
end
end
end
return renderFlag, cursorRenderFlag
end
local function save()
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, string.rep(" ", width))
termlib.cursorPosX = 1
termlib.cursorPosY = height - 1
local savepath = read(nil, "\27[107m\27[30mSave location: ", filepath)
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
if fs.exists(savepath) then
gpu.set(1, height - 1, string.rep(" ", width))
local answer = read(nil, "\27[107m\27[30mFile already exists. Overwrite it? [Y/n] ")
if answer:lower() == "n" then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
return
end
end
local handle, errorMessage = fs.open(savepath, "w")
if handle then
if table.concat(tmpdata, "\n"):sub(-1, -1) == "\n" then
handle:write(table.concat(tmpdata, "\n"))
else
handle:write(table.concat(tmpdata, "\n") .. "\n") -- add a newline at the end to follow POSIX standards
end
handle:close()
gpu.set(1, height - 1, filestring .. string.rep(" ", width))
else
gpu.set(1, height - 1, "ERROR: " .. errorMessage:gsub("\n", "") .. string.rep(" ", width))
end
changesMade = false
end
render()
while true do
local args = {event.pull(0.5)}
local renderFlag, cursorRenderFlag, specialKey = false, false, nil
local previousCursorX, previousCursorY = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2), cursorPosY
if args and args[1] then
cursorWhite = true
renderFlag, cursorRenderFlag, specialKey = processEvent(args)
if specialKey == "x" then
if changesMade then
termlib.cursorPosX = 1
termlib.cursorPosY = height - 1
local response = read(nil, "\27[107m\27[30mWould you like to save changes? [Y/n] ")
if response:lower() ~= "n" then
save()
end
end
gpu.freeAllBuffers()
clear()
return
end
if specialKey == "s" then
save()
end
repeat
args = {event.pull("key_down", 0)}
if args and args[1] then
processEvent(args)
end
until not args or not args[1]
else
cursorWhite = not cursorWhite
cursorRenderFlag = true
end
if cursorRenderFlag then
local char = gpu.get(previousCursorX, previousCursorY)
gpu.set(previousCursorX, previousCursorY, char)
local realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
if realCursorX < 1 then
scrollPosX = scrollPosX + realCursorX - 1
cursorPosX = 1
realCursorX = math.min(cursorPosX, unicode.wlen(tmpdata[cursorPosY + scrollPosY - 1]) - scrollPosX + 2)
end
local char = gpu.get(realCursorX, cursorPosY)
if cursorWhite then
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0)
end
gpu.set(realCursorX, cursorPosY, char)
if cursorWhite then
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0)
end
end
if renderFlag then
render()
end
end
Error: no such file. (``)
+1 -70
View File
@@ -1,70 +1 @@
local component = import("component")
local computer = import("computer")
local function printstat(text)
termlib.cursorPosX = 35
termlib.write(text .. "\n", false)
end
termlib.write(_OSLOGO, false)
termlib.cursorPosY = termlib.cursorPosY - 17
printstat("\27[92mOS\27[0m: ".._OSVERSION)
printstat("\27[92mArchitecture\27[0m: ".._VERSION)
local componentCounter = 0
for _, _ in component.list() do
componentCounter = componentCounter + 1
end
printstat("\27[92mComponents\27[0m: "..tostring(componentCounter))
printstat("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList))
printstat("\27[92mBattery\27[0m: "..tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10).."%")
local totalMemory = computer.totalMemory()
local usedMemory = computer.totalMemory() - computer.freeMemory()
local totalMemoryString
if convert(totalMemory, "B", "GiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(totalMemory, "B", "MiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(totalMemory, "B", "KiB") >= 1 then
totalMemoryString = tostring(math.floor(convert(totalMemory, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
totalMemoryString = tostring(totalMemory) .. " B"
end
local usedMemoryString
if convert(usedMemory, "B", "GiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(usedMemory, "B", "MiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(usedMemory, "B", "KiB") >= 1 then
usedMemoryString = tostring(math.floor(convert(usedMemory, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
usedMemoryString = tostring(usedMemory) .. " B"
end
printstat("\27[92mMemory\27[0m: "..usedMemoryString.." / "..totalMemoryString)
local totalDisk = component.invoke(computer.getBootAddress(), "spaceTotal")
local usedDisk = component.invoke(computer.getBootAddress(), "spaceUsed")
local totalDiskString
if convert(totalDisk, "B", "GiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(totalDisk, "B", "MiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(totalDisk, "B", "KiB") >= 1 then
totalDiskString = tostring(math.floor(convert(totalDisk, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
totalDiskString = tostring(totalDisk) .. " B"
end
local usedDiskString
if convert(usedDisk, "B", "GiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "GiB") * 100 + 0.5) / 100) .. " GiB"
elseif convert(usedDisk, "B", "MiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "MiB") * 100 + 0.5) / 100) .. " MiB"
elseif convert(usedDisk, "B", "KiB") >= 1 then
usedDiskString = tostring(math.floor(convert(usedDisk, "B", "KiB") * 100 + 0.5) / 100) .. " KiB"
else
usedDiskString = tostring(usedDisk) .. " B"
end
printstat("\27[92mDisk\27[0m: "..usedDiskString.." / "..totalDiskString)
local width, height = component.invoke(component.list("gpu")(), "getResolution")
printstat("\27[92mResolution\27[0m: "..tostring(width).."x"..tostring(height).."\n")
printstat("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")
printstat("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")
termlib.cursorPosY = termlib.cursorPosY + 5
Error: no such file. (``)
+1 -38
View File
@@ -1,38 +1 @@
local fs = import("filesystem")
local args = {...}
local command = args[1]
args = nil
if not command then
local handle, data, tmpdata = fs.open("/halyde/apps/helpdb/default.txt", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
print(data)
return
end
if shell.aliases[command] then
command = shell.aliases[command]
end
if fs.exists("/halyde/apps/helpdb/" .. command .. ".txt") then
local handle, data, tmpdata = fs.open("/halyde/apps/helpdb/" .. command .. ".txt", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
print(data)
local aliases = table.copy(shell.aliases)
if table.find(aliases, command) then
local aliasIndex = table.find(aliases, command)
local aliasString = "Aliases:\n " .. aliasIndex
aliases[aliasIndex] = nil
while table.find(aliases, command) do
aliasIndex = table.find(aliases, command)
aliasString = aliasString .. ", " .. aliasIndex
aliases[aliasIndex] = nil
end
print(aliasString)
end
else
print("Could not find help file for: " .. command .. ".")
end
Error: no such file. (``)
+1 -92
View File
@@ -1,92 +1 @@
local component = import("component")
local computer = import("computer")
local args = {...}
if not args then return print("\x1b[91mCannot get arguments.") end
if not args[1] then
return shell.run("help label")
end
local inputID = args[1]
local comp
local function componentFromSlot(slotNum)
if slotNum>=5 and slotNum<=8 then slotNum=slotNum-1 end
for i,v in component.list() do
if component.slot(i)==slotNum then
comp=component.proxy(i)
end
end
end
if inputID=="eeprom" then
comp = component.eeprom
elseif inputID=="halyde" then
comp = component.proxy(computer.getBootAddress())
elseif inputID:sub(1,4)=="slot" and tonumber(inputID:sub(5)) then
local slotNum = tonumber(inputID:sub(5))-1
componentFromSlot(slotNum)
elseif inputID:sub(1,1)=="#" and tonumber(inputID:sub(2)) then
local slotNum = tonumber(inputID:sub(2))+5
componentFromSlot(slotNum)
elseif #inputID>=3 then
local fullID = component.get(inputID)
if not fullID then return print("\x1b[91mCould not find entire component ID from \""..inputID.."\".") end
comp = component.proxy(fullID)
else
print("\x1b[91mAddress must have atleast 3 characters")
return shell.run("help label")
end
if not comp then
return print("\x1b[91mCould not find component from \""..inputID.."\".")
end
local compID = comp.address
local function formatID(id)
return id:sub(1,8).."\x1b[37m"..id:sub(9).."\x1b[39m"
end
local function unsupported(act)
print("This \x1b[92m"..(comp.type or "unknown").."\x1b[39m component doesn't support "..act.." labels.\nID: "..formatID(compID))
end
local function compError(act,reason)
print("\x1b[91mAn error occured while "..act.." the label of this component.\nComponent: "..(compID or "unknown id").." ("..((comp or {}).type or "unknown type")..")\n\n"..reason)
end
local function formatLabel(label)
local res = "No label defined"
if label then res="\""..label.."\"" end
return res
end
if type(args[2])~="string" then
if not comp.getLabel then
return unsupported("getting")
end
local label
local success,reason = pcall(function()
label = comp.getLabel()
end)
if success then
print("Label of "..formatID(compID)..((comp.type and comp.type~="filesystem") and " ("..comp.type..")" or "")..":\n \x1b[92m"..formatLabel(label).."\x1b[39m")
else
compError("getting",reason)
end
else
if not comp.setLabel then
return unsupported("setting")
end
local newLabel = ""
for i=2,#args do
newLabel=newLabel..tostring(args[i])
if i<#args then newLabel=newLabel.." " end
end
local label
local success,reason = pcall(function()
label = comp.setLabel(newLabel)
end)
if success then
print("Successfully set label of "..formatID(compID)..(comp.type and " ("..comp.type..")" or "").." to:\n \x1b[92m"..formatLabel(label).."\x1b[39m")
else
compError("setting",reason)
end
end
Error: no such file. (``)
+1 -70
View File
@@ -1,70 +1 @@
local args = {...}
local target = args[1]
args = nil
local fs = import("filesystem")
local unicode = import("unicode")
local maxLength = 0
local margin = 2 -- minimum space between filename and size
local dirTable = {}
local fileTable = {}
if target then
if target:sub(1, 1) ~= "/" then
target = fs.concat(shell.workingDirectory, target)
end
else
target = shell.workingDirectory
end
local files = fs.list(target)
if files then
for _, file in pairs(files) do
if file:sub(-1, -1) == "/" then
table.insert(dirTable, file)
file = file:sub(1, -2)
else
table.insert(fileTable, file)
end
if unicode.wlen(file) > maxLength then
maxLength = unicode.wlen(file)
end
end
table.sort(dirTable)
table.sort(fileTable)
files = {}
for _, v in ipairs(dirTable) do
table.insert(files, v)
end
for _, v in ipairs(fileTable) do
table.insert(files, v)
end
dirTable, fileTable = nil, nil
for _, file in ipairs(files) do
local dir = false
local filetext
if file:sub(-1, -1) == "/" then
dir = true
filetext = "\27[93m"..file:sub(1, -2)
elseif file:find(".") and file:match("[^.]+$") == "lua" then
filetext = "\27[92m"..file
end
filetext = (filetext or file)..string.rep(" ", maxLength - unicode.wlen(file) + margin)
if dir then
print(filetext.." \27[0m[DIR]")
else
local size = fs.size(fs.concat(target, file))
local sizeString
if convert(size, "B", "GiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "GiB") * 100 + 0.5) / 100).." GiB"
elseif convert(size, "B", "MiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "MiB") * 100 + 0.5) / 100).." MiB"
elseif convert(size, "B", "KiB") >= 1 then
sizeString = tostring(math.floor(convert(size, "B", "KiB") * 100 + 0.5) / 100).." KiB"
else
sizeString = tostring(size).." B"
end
print(filetext.."\27[0m"..sizeString)
end
end
end
Error: no such file. (``)
+1 -9
View File
@@ -1,9 +1 @@
print("\27[93m"..tostring(#cormgr.corList).."\27[0m coroutines active")
for i=1, #cormgr.corList do
if i==#cormgr.corList then
print("\27[93m└ "..i.."\27[0m - "..cormgr.labelList[i].." \27[0m")
else
print("\27[93m├ "..i.."\27[0m - "..cormgr.labelList[i].." \27[0m")
end
end
Error: no such file. (``)
+1 -320
View File
@@ -1,320 +1 @@
local serialize = import("serialize")
local component = import("component")
local computer = import("computer")
local unicode = import("unicode")
local width,height = component.gpu.getResolution()
local args = {...}
local showAll = not not (table.find(args,"-a") or table.find(args,"--all"))
local tablePos = {}
local tableOut = {}
local headers = {
["slot"]="SLOT",
["capacity"]="CAPACITY",
["managed"]="MANAGED",
["readOnly"]="READ-ONLY",
["id"]="FULL COMPONENT ID",
["mount"]="MOUNT",
["bootable"]="BOOTABLE",
["label"]="LABEL"
}
local headerAlign = {
["slot"]=false,
["capacity"]=true,
["managed"]=false,
["readOnly"]=false,
["id"]=false,
["mount"]=false,
["bootable"]=false,
["label"]=false
}
local function addHeader(id)
table.insert(tableOut,{headerAlign[id],headers[id]})
tablePos[id]=#tableOut
end
for i,v in pairs(tablePos) do print(i,v) end
local function everyHeader()
addHeader("slot")
addHeader("capacity")
addHeader("managed")
addHeader("readOnly")
addHeader("id")
addHeader("mount")
addHeader("bootable")
addHeader("label")
end
local function defaultHeaders()
if width>100 then addHeader("slot") end
addHeader("capacity")
if width>80 then addHeader("id") end
addHeader("mount")
addHeader("label")
end
local function invalidArgSyntax(err)
print(err)
return shell.run("help lsdrv")
end
local outArgIdx = table.find(args,"-o") or table.find(args,"--output")
if showAll then
everyHeader()
elseif outArgIdx then
table.remove(args,outArgIdx)
local arg = table.remove(args,outArgIdx)
if not arg then return invalidArgSyntax("Argument -o must have a value") end
if arg=="all" then
everyHeader()
else
if arg:sub(1,1)=="+" then
defaultHeaders()
end
for word in string.gmatch(arg:sub(2),"([^,]+)") do
if headers[word] then
addHeader(word)
else
print("\x1b[93mCategory \""..word.."\" doesn't exist\x1b[39m")
end
end
end
else
defaultHeaders()
end
local function headerUsed(id)
return not not tablePos[id]
end
local bibytes = not (table.find(args,"-H") or table.find(args,"--si"))
local function formatSize(mem)
local units = bibytes and {"B","KiB","MiB","GiB"} or {"B","KB","MB","GB"}
local unit = 1
local unitStep = bibytes and 1024 or 1000
while mem > unitStep and units[unit] do
unit = unit + 1
mem = mem/unitStep
end
local memStr = tostring(mem):sub(1,5)
if unicode.sub(memStr,-2)==".0" then
memStr=unicode.sub(memStr,1,-3)
end
return memStr.." "..units[unit]
end
local function fileExists(proxy,path)
return proxy.exists(path) and not proxy.isDirectory(path)
end
local function getBootCode(proxy)
local sector1 = proxy.readSector(1)
for i = 1,#sector1 do
if sector1:sub(i,i)=="\0" then
sector1 = sector1:sub(1,i-1)
break
end
end
return sector1
end
local function isBootable(proxy,type)
if type=="drive" then
return not not load(getBootCode(proxy))
elseif type=="filesystem" then
return not not (fileExists(proxy,"/init.lua") or fileExists(proxy,"/OS.lua"))
end
end
local function formatBoolean(bool)
return ({[true]="Yes",[false]="No"})[bool]
end
local function handleComponent(id,type)
if not id then return end
local proxy = component.proxy(id)
if not proxy then return end
-- local out = {}
-- for i=1,#tableOut do table.insert(out,"unknown") end
local slot,capacity,managed,readOnly,mount,bootable,label
local cslot = component.slot(id)
if cslot==-1 then
slot="Virtual"
elseif cslot==9 then
slot="EEPROM"
else
slot="#"..(cslot+2)
end
managed="Yes"
readOnly="No"
if type=="drive" then
managed="No"
capacity=formatSize(proxy.getCapacity())
mount="/special/drive/"..id:sub(1,3)
elseif type=="filesystem" then
capacity=formatSize(proxy.spaceTotal())
if proxy.isReadOnly() then
readOnly="Yes"
end
mount="/mnt/"..id:sub(1,3)
if computer.getBootAddress()==id then mount="/" end
if computer.tmpAddress()==id then
mount="/tmp"
slot="Temporary"
end
elseif type=="eeprom" then
capacity=formatSize(proxy.getSize()+proxy.getDataSize())
mount="/special/eeprom/"
end
if headerUsed("bootable") then
bootable = formatBoolean(isBootable(proxy,type))
end
if proxy.getLabel then
local clabel = proxy.getLabel()
label=clabel and serialize.string(clabel) or "None"
else
label="Unsupported"
end
local function insertElement(i,v)
if not tablePos[i] then return end
table.insert(tableOut[tablePos[i]],v or "unknown")
end
insertElement("slot",slot)
insertElement("capacity",capacity)
insertElement("managed",managed)
insertElement("readOnly",readOnly)
insertElement("id",id)
insertElement("mount",mount)
insertElement("bootable",bootable)
insertElement("label",label)
end
local function filter(tbl,test)
local i=1
while i<=#tbl do
if not test(tbl[i]) then
table.remove(tbl,i)
i=i-1
end
i=i+1
end
end
local function luaExpr(arg)
local func,err = load("local component,computer,type,id,readonly,capacity=... local managed,eeprom,halyde,tmp,proxy,slot,all=type==\"drive\",type==\"eeprom\",id==\""..computer.getBootAddress().."\",id==\""..computer.tmpAddress().."\",component.proxy(id),component.slot(id)+2,true return "..arg)
if func then
return function(comp)
local readOnly,capacity=false,nil
if comp[2]=="filesystem" then
readOnly=component.invoke(comp[1],"isReadOnly")
capacity=component.invoke(comp[1],"spaceTotal")
elseif comp[2]=="drive" then
capacity=component.invoke(comp[1],"getCapacity")
elseif comp[2]=="eeprom" then
capacity=component.invoke(comp[1],"getSize")+component.invoke(comp[1],"getDataSize")
end
return func(component,computer,comp[2],comp[1],readOnly,capacity)
end
else
return nil,err
end
end
local function boolToNum(val)
if type(val)=="boolean" then
if val then
return 1
else
return 0
end
end
return val
end
local comps = {}
for i,v in component.list("filesystem") do table.insert(comps,{i,v}) end
for i,v in component.list("drive") do table.insert(comps,{i,v}) end
for i,v in component.list("eeprom") do table.insert(comps,{i,v}) end
if not showAll then
local showArgIdx = table.find(args,"-s") or table.find(args,"--show")
if showArgIdx then
table.remove(args,showArgIdx)
local arg = table.remove(args,showArgIdx)
if not arg then return invalidArgSyntax("Argument -s must have a value") end
local func,err = luaExpr(arg)
if func then
filter(comps,func)
else
return print("\x1b[91mInvalid component filter:\n\n"..tostring(err).."\x1b[39m")
end
else
filter(comps,function(comp)
return comp[2]~="eeprom" and comp[1]~=computer.tmpAddress()
end)
end
end
local sortArgIdx = table.find(args,"-S") or table.find(args,"--sort")
if sortArgIdx then
table.remove(args,sortArgIdx)
local arg = table.remove(args,sortArgIdx)
if not arg then return invalidArgSyntax("Argument -S must have a value") end
local func,err = luaExpr(arg)
if func then
table.sort(comps,function(a,b)
return (boolToNum(func(a)) or 0)<(boolToNum(func(b)) or 0)
end)
else
return print("\x1b[91mInvalid sort expression:\n\n"..tostring(err).."\x1b[39m")
end
else
table.sort(comps,function(a,b)
return a[1]<b[1]
end)
end
if #comps>0 then
for i,v in ipairs(comps) do handleComponent(v[1],v[2]) end
else
return print("Could not find storage components for this filter.")
end
local function renderTableOutput()
local lines = {}
for i=1,#tableOut[1]-1 do
table.insert(lines,"")
end
for i=1,#tableOut do
local length = 1
for j=1,#lines do
tableOut[i][j+1]=tableOut[i][j+1] or "[nil]"
length = math.max(length,unicode.wlen(tableOut[i][j+1]))
end
for j=1,#lines do
if tableOut[i][1] then
lines[j]=lines[j]..string.rep(" ",length-unicode.wlen(tableOut[i][j+1]))..tableOut[i][j+1]
elseif i<#tableOut then
lines[j]=lines[j]..tableOut[i][j+1]..string.rep(" ",length-unicode.wlen(tableOut[i][j+1]))
else
lines[j]=lines[j]..tableOut[i][j+1]
end
if i<#tableOut then lines[j]=lines[j].." " end
end
end
print(lines[1].."\n")
for i=2,#lines do
print(lines[i])
end
end
renderTableOutput()
Error: no such file. (``)
+1 -31
View File
@@ -1,31 +1 @@
print("\27[44m".._VERSION.."\27[0m shell")
print('Type "exit" to exit.')
termlib.readHistory["lua"] = {""}
local fs = import("filesystem")
local loadedLibraries = ""
local libList = fs.list("halyde/lib")
for _, lib in pairs(libList) do
if lib:match("(.+)%.lua") then
loadedLibraries = loadedLibraries .. "local " .. lib:match("(.+)%.lua") .. ' = import("' .. lib:match("(.+)%.lua") .. '")\n'
end
end
while true do
local command = read("lua", "\27[44mlua>\27[0m ")
if command == "exit" then
return
else
local function runCommand()
local func = load(loadedLibraries.."return "..command,"=stdin") or load(loadedLibraries..command,"=stdin")
local res = {assert(func)()}
if res and (type(res[1])~="nil" or type(res[2])~="nil") then print(table.unpack(res)) end
end
local result, reason = xpcall(runCommand, function(errMsg)
return errMsg .. "\n\n" .. debug.traceback()
end)
if not result then
print("\27[91m" .. reason)
end
end
end
Error: no such file. (``)
+1 -8
View File
@@ -1,8 +1 @@
local computer = import("computer")
if type(computer)~="table" then
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m")
end
local address = computer.getBootAddress()
print(address)
Error: no such file. (``)
+1 -14
View File
@@ -1,14 +1 @@
local directory = ...
local fs = import("filesystem")
if not directory then
shell.run("help mkdir")
return
end
if directory:sub(1, 1) ~= "/" then
directory = fs.concat(shell.workingDirectory, directory)
end
if fs.exists(directory) then
print("\27[91mAn object already exists at the specified path.")
end
fs.makeDirectory(directory)
Error: no such file. (``)
+1 -24
View File
@@ -1,24 +1 @@
local fromFile, toFile = ...
local fs = import("filesystem")
if not fromFile or not toFile then
shell.run("help mv")
return
end
if fromFile:sub(1, 1) ~= "/" then
fromFile = fs.concat(shell.workingDirectory, fromFile)
end
if toFile:sub(1, 1) ~= "/" then
toFile = fs.concat(shell.workingDirectory, toFile)
end
if fromFile == toFile then
print("\27[91mSource and destination are the same.")
end
if not fs.exists(fromFile) then
print("\27[91mSource file does not exist.")
end
if fs.exists(toFile) and not (table.find({...}, "-o") or table.find({...}, "--overwrite")) then
print("\27[91mDestination file already exists. Run this command again with -o to overwrite it.")
return
end
fs.rename(fromFile, toFile)
Error: no such file. (``)
+1 -1
View File
@@ -1 +1 @@
import("computer").shutdown(true)
Error: no such file. (``)
+1 -15
View File
@@ -1,15 +1 @@
local file = ...
local fs = import("filesystem")
if not file then
shell.run("help rm")
return
end
if file:sub(1, 1) ~= "/" then
file = fs.concat(shell.workingDirectory, file)
end
if not fs.exists(file) then
print("\27[91mFile does not exist.")
return
end
fs.remove(file)
Error: no such file. (``)
+1 -91
View File
@@ -1,91 +1 @@
local raster = import("raster")
raster.init()
--[[for i=4,20 do
raster.set(i,i)
raster.set(i,i+4,0xFF00FF)
end]]
--[[ for x=4,20 do
for y=4,20 do
if (x+y)%2==0 then
raster.set(x,y,0xFF00FF)
end
end
end ]]
local event = import("event")
local x=0
local y=0
local vx=1
local vy=1
local col = 0x808080
local i=0
while event.pull("key_down",0)==nil do
i = i + 1
raster.set(x,y,col)
x = x + vx
y = y + vy
if x>raster.displayWidth then
x=raster.displayWidth
vx = -math.abs(vx)
col = math.random(0,0xFFFFFF)
end
if x<1 then
x=1
vx = math.abs(vx)
col = math.random(0,0xFFFFFF)
end
if y>raster.displayHeight-6 then
y=raster.displayHeight-6
vy = -math.abs(vy)
col = math.random(0,0xFFFFFF)
end
if y<1 then
y=1
vy = math.abs(vy)
col = math.random(0,0xFFFFFF)
end
if i>10 and i%15>0 then
while true do
local tries=0
local dx,dy=math.random(1,raster.displayWidth),math.random(1,raster.displayHeight-6)
if raster.get(dx,dy)~=0 then
raster.set(dx,dy,0)
break
end
tries = tries + 1
if tries>20 then
break
end
end
end
if i%10==0 then
raster.update()
coroutine.yield()
end
end
--[[ for i=0,360,4 do
local angle = i/180*math.pi
if false then
local x1,y1,x2,y2=raster.displayWidth/2,raster.displayHeight/2,raster.displayWidth/2+math.sin(angle)*80,raster.displayHeight/2+math.cos(angle)*80
raster.fillEllipse(x1,y1,x2,y2,0xFF00FF)
raster.update()
raster.fillEllipse(x1,y1,x2,y2,0x000000)
else
local x,y,c=raster.displayWidth/2,raster.displayHeight/2,math.abs(math.sin(angle)*100)
raster.drawCircle(x,y,c,0xFF00FF)
raster.update()
raster.drawCircle(x,y,c,0x000000)
end
end ]]
raster.free()
termlib.cursorPosY=1
Error: no such file. (``)
+1 -141
View File
@@ -1,141 +1 @@
local component = import("component")
local computer = import("computer")
local raster = import("raster")
local event = import("event")
-- Initialize the 3D renderer for a spinning cube
-- Using the raster library for drawing
-- Screen dimensions
local SCREEN_WIDTH, SCREEN_HEIGHT = component.invoke(component.list("gpu")(), "getResolution")
SCREEN_WIDTH, SCREEN_HEIGHT = SCREEN_WIDTH * 2, SCREEN_HEIGHT * 4
local CENTER_X = SCREEN_WIDTH / 2
local CENTER_Y = SCREEN_HEIGHT / 2
-- Cube properties
local CUBE_SIZE = 10
local increment = 0
local WHITE = 0xFFFFFF
local ROTATION_SPEED = 0.1
-- 3D cube vertices (centered at origin)
local vertices = {
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 0: left bottom back
{CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 1: right bottom back
{CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 2: right top back
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 3: left top back
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 4: left bottom front
{CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 5: right bottom front
{CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, -- 6: right top front
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} -- 7: left top front
}
-- Cube edges defined by vertex indices
local edges = {
{0, 1}, {1, 2}, {2, 3}, {3, 0}, -- back face
{4, 5}, {5, 6}, {6, 7}, {7, 4}, -- front face
{0, 4}, {1, 5}, {2, 6}, {3, 7} -- connecting edges
}
-- Projection parameters
local FOV = 256 -- Field of view (distance from camera to screen)
local Z_OFFSET = 300 -- Distance from camera to cube center
-- Initialize rotation angles
local angleX, angleY, angleZ = 0, 0, 0
-- Matrix multiplication function (apply rotation to a 3D point)
local function rotatePoint(x, y, z)
-- Rotation around X axis
local cosX, sinX = math.cos(angleX), math.sin(angleX)
local y1 = y * cosX - z * sinX
local z1 = y * sinX + z * cosX
-- Rotation around Y axis
local cosY, sinY = math.cos(angleY), math.sin(angleY)
local x1 = x * cosY + z1 * sinY
local z2 = -x * sinY + z1 * cosY
-- Rotation around Z axis
local cosZ, sinZ = math.cos(angleZ), math.sin(angleZ)
local x2 = x1 * cosZ - y1 * sinZ
local y2 = x1 * sinZ + y1 * cosZ
return x2, y2, z2
end
-- Perspective projection function (3D to 2D)
local function projectPoint(x, y, z)
-- Apply perspective projection
local scale = FOV / (z + Z_OFFSET)
local x2d = x * scale + CENTER_X
local y2d = y * scale + CENTER_Y
return x2d, y2d
end
-- Render a single frame
local function renderFrame()
local time = computer.uptime()*20
increment = time*0.05 -- increment + 0.05
CUBE_SIZE = (math.sin(increment) + 1) * 25
vertices = {
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 0: left bottom back
{CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE}, -- 1: right bottom back
{CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 2: right top back
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE}, -- 3: left top back
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 4: left bottom front
{CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE}, -- 5: right bottom front
{CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}, -- 6: right top front
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE} -- 7: left top front
}
-- Update rotation angles
raster.clear()
angleX = time * ROTATION_SPEED -- angleX
angleY = time * ROTATION_SPEED * 0.7 -- angleY
angleZ = time * ROTATION_SPEED * 0.5 -- angleZ
-- Project all vertices
local projectedPoints = {}
for i, vertex in ipairs(vertices) do
-- Rotate the point
local x, y, z = rotatePoint(vertex[1], vertex[2], vertex[3])
-- Project the point to 2D
local x2d, y2d = projectPoint(x, y, z)
projectedPoints[i] = {x2d, y2d}
end
-- Draw all edges
for _, edge in ipairs(edges) do
local p1 = projectedPoints[edge[1] + 1] -- +1 because Lua indices start at 1
local p2 = projectedPoints[edge[2] + 1]
-- Draw the line
raster.drawLine(p1[1], p1[2], p2[1], p2[2], WHITE)
end
-- Render the frame
raster.update()
end
-- Main program
function main()
-- Initialize raster engine
raster.init()
-- Main loop (assume this is called repeatedly by the host environment)
while true do
renderFrame()
coroutine.yield()
if event.pull("key_down", 0) then
raster.free()
break
end
end
-- Return a reference to renderFrame so it can be called for animation
return renderFrame
end
-- Start the program
return main()
Error: no such file. (``)
+1 -1
View File
@@ -1 +1 @@
import("computer").shutdown()
Error: no such file. (``)