11 Commits

Author SHA1 Message Date
github-actions[bot] 53710672c7 But did YOU know (minified) 2026-04-30 15:09:56 +00:00
github-actions[bot] 663354f781 AFSDHJFJKHDSAFHJKSHJKFJHDFJSKOAPOPJIUFSJIFOPSA (minified) 2026-04-30 15:07:25 +00:00
github-actions[bot] 32ff91d1d0 Ponali the legend comes in clutch once again (minified) 2026-04-30 13:13:20 +00:00
github-actions[bot] 8535cb9380 DO YOU WANT A BANANA (minified) 2026-04-30 13:01:41 +00:00
github-actions[bot] b7b7b3e569 kukgug (minified) 2026-04-30 12:55:30 +00:00
github-actions[bot] a5cd53656a Bwomp (minified) 2026-04-30 12:50:37 +00:00
github-actions[bot] 6f2a561e3d I'm gonna go instane (minified) 2026-04-30 12:45:25 +00:00
github-actions[bot] b08d7b3f98 I forgot you have to give it write permissions (minified) 2026-04-30 12:32:52 +00:00
WahPlus 2a2b27a827 Made filesystem.concat() work with more than 2 paths
Also made the code a bit cleaner.
2026-03-04 17:42:06 +02:00
WahPlus 9581d5ce52 Added MD5 library 2025-10-27 20:08:04 +02:00
WahPlus 2dee5eaba7 Revert pre-alpha 3.0.0 because I was supposed to push it to a branch.
This reverts commit cbf25999f0.
2025-08-17 16:44:40 +03:00
70 changed files with 144 additions and 5178 deletions
+14
View File
@@ -0,0 +1,14 @@
const fs = require("fs")
const luamin = require('lua-format')
const Code = fs.readFileSync(process.argv[2],"utf-8")
const Settings = {
RenameVariables: true,
RenameGlobals: false,
SolveMath: true,
Indentation: '\t'
}
const Beautified = luamin.Beautify(Code, Settings)
const Minified = luamin.Minify(Code, Settings)
fs.writeFileSync(process.argv[2],"utf-8")
+55
View File
@@ -0,0 +1,55 @@
name: Minify all Lua files to minified branch
on:
push:
branches:
- main
jobs:
minify:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout main branch
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Get latest commit info
id: commit
run: |
COMMIT_MSG=$(git log -1 --pretty=%s)
echo "message=${COMMIT_MSG}" >> $GITHUB_OUTPUT
- name: Set up Node.js
uses: actions/setup-node@v4
- name: Install luamin
run: npm install -g luamin
- name: Switch to minified branch
run: git checkout minified
- name: Copy files from main
run: |
git checkout main -- .
git reset HEAD
- name: Minify all Lua files
run: |
for file in $(find . -name "*.lua" -not -path "./.git/*"); do
echo $file
cat "$file" | luamin -c > "$file"
done
- name: Commit and push to minified branch
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "${{ steps.commit.outputs.message }} (minified)"
git push origin minified
+7 -97
View File
@@ -1,100 +1,10 @@
{ {
"$schema": "https://raw.githubusercontent.com/LuaLS/lua-language-server/master/locale/en-us/setting.lua", "diagnostics.globals": [
"runtime": { "checkArg",
"version": "Lua 5.3", "computer",
"special": {}, "component"
"unicodeName": false,
"nonstandardSymbol": []
},
"workspace": {
"checkThirdParty": false,
"maxPreload": 5000,
"preloadFileSize": 500
},
"diagnostics": {
"disable": [
"undefined-global",
"lowercase-global"
], ],
"globals": [ "diagnostics.disable": [
"_G", "lowercase-global"
"_VERSION",
"assert",
"error",
"getmetatable",
"ipairs",
"load",
"next",
"pairs",
"pcall",
"rawequal",
"rawget",
"rawlen",
"rawset",
"select",
"setmetatable",
"tonumber",
"tostring",
"type",
"xpcall",
"checkArg",
"bit32",
"coroutine",
"debug",
"math",
"os",
"string",
"table",
"component",
"computer",
"unicode",
"utf8"
] ]
}, }
"completion": {
"enable": true,
"callSnippet": "Both",
"keywordSnippet": "Both",
"displayContext": 6
},
"hover": {
"enable": true,
"viewString": true,
"viewStringMax": 1000,
"viewNumber": true,
"fieldInfer": 3000,
"previewFields": 50,
"enumsLimit": 5
},
"semantic": {
"enable": true,
"variable": true,
"annotation": true,
"keyword": false
},
"format": {
"enable": true,
"defaultConfig": {
"indent_style": "space",
"indent_size": "2",
"tab_width": "2"
}
},
"spell": {
"dict": []
},
"telemetry": {
"enable": false
},
"IntelliSense": {
"traceLocalSet": false,
"traceReturn": false,
"traceBeSetted": false,
"traceFieldInject": false
},
"type": {
"castNumberToInteger": false,
"weakUnionCheck": false,
"weakNilCheck": false
}
}
File diff suppressed because one or more lines are too long
+1 -60
View File
@@ -1,60 +1 @@
local component = require("component") local a=import("component")local b=import("computer")local c={...}local d=false;local e=table.find(c,"-f")or table.find(c,"--force")if e then table.remove(c,e)d=true end;local function e(b)local function c(b)for c,d in a.list()do if a.slot(c)==b then return c end end end;if b=="hdd1"or b=="#1"then return c(5)end;if b=="hdd2"or b=="#2"then return c(6)end;if b=="floppy"or b=="#3"then return c(7)end;if#b<3 then return nil,"Abbreviated ID must atleast have 3 characters"end;return a.get(b)end;local function f(b,c)return a.invoke(b,"exists",c)and not a.invoke(b,"isDirectory",c)end;if type(c[1])=="string"then local e,g=e(c[1])if not e then print("\x1b[91mCould not get component ID from '"..c[1].."'.")if type(g)=="string"then print("\x1b[91m"..g)end;return end;if not d then if componentlib.additions[e]then return print("\x1b[91mThis component is virtual and cannot be booted from directly.\nID: "..e)end;local a=a.type(e)if a~="filesystem"and a~="drive"then return print("\x1b[91mThis component is not a storage medium.\nID: "..e)end;if a=="filesystem"and not f(e,"/init.lua")then return print("\x1b[91mThis storage medium doesn't have an \"init.lua\" file.\nID: "..e)end end;b.setBootAddress(e)if b.getBootAddress()~=e then return print("\x1b[91mFailed to set the boot address.")end;b.shutdown(true)else shell.run("help boot")end
local computer = require("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
+1 -20
View File
@@ -1,20 +1 @@
local files = {...} local a={...}local b=import("filesystem")if not a or not a[1]then shell.run("help cat")return end;for a,a in ipairs(a)do if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")end;local a=b.open(a,"r")local b;repeat b=a:read(math.huge or math.maxinteger)termlib.write(b)until not b end
local fs = require("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
+1 -14
View File
@@ -1,14 +1 @@
local directory = ... local a=...local b=import("filesystem")if not a then return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)and b.isDirectory(a)then shell.workingDirectory=b.canonical(a)else print("\27[91mNo such directory.")end
local fs = require("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
+1 -2
View File
@@ -1,2 +1 @@
clear() clear()
-- truly so much going on here
+1 -26
View File
@@ -1,26 +1 @@
local fromFile, toFile = ... local a,b=...local c=import("filesystem")if not a or not b then shell.run("help cp")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")return end;if not c.exists(a)then print("\27[91mSource file does not exist.")return end;if c.exists(b)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;c.copy(a,b)
local fs = require("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)
+1 -57
View File
@@ -1,57 +1 @@
local url = ... local a=...local b=import("component")local c=import("filesystem")if not b.list("internet")()then print("\27[91mThis program requires an internet card to run.")return end;if not a then print("Please enter a URL to download from.")shell.run("help download")return end;if a:sub(-1,-1)=="/"then a=a:sub(1,-2)end;local b=b.internet;local d,e,f=nil,"",nil;local b,g=pcall(function()d=b.request(a)d:finishConnect()end)if not b then print("\27[91mDownload failed: "..g)end;local b=d:response()if b and b~=200 then print("\27[91mDownload failed: "..tostring(b))end;repeat f=d.read(math.huge)e=e..(f or"")until not f;local b;local d=false;repeat b=read(nil,"File save location: ",c.concat(shell.workingDirectory,a:match("/([^/]+)$")))if c.isDirectory(b)then print("\27[91mThe specified location is a directory.")elseif c.exists(b)then local a=read(nil,"\27[91mThere is already a file at the specified directory. Overwrite it? [Y/n]")if a:lower()~="n"then d=true end else d=true end until d;local a=c.open(b,"w")a:write(e)a:close()print("File downloaded successfully.")
local component = require("component")
local fs = require("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.")
+1 -7
View File
@@ -1,7 +1 @@
local args = {...} local a={...}local b=a[1]table.remove(a,1)for a,a in pairs(a)do b=b.." "..a end;print(b)
local concatText = args[1]
table.remove(args, 1)
for _, item in pairs(args) do
concatText = concatText .. " " .. item
end
print(concatText)
+1 -351
View File
@@ -1,351 +1 @@
local file = ... local a=...local b=import("filesystem")local c=import("event")local d=import("component")local e=import("unicode")local d=d.gpu;local f,g=d.getResolution()local h,i=1,1;local j,k=1,1;local l=true;local m=false;local n=d.allocateBuffer()local o=5;local p=" "local function q(a,b,c)termlib.cursorPosX=a;termlib.cursorPosY=b;termlib.write(c,false)end;local r,s,t,u,v;if a then if a:sub(1,1)=="/"then s=a else s=shell.workingDirectory..a end;t,u,v=b.open(s,"r"),"",nil;if b.exists(s)then r=s;repeat v=t:read(math.huge)u=u..(v or"")until not v;v={}if u:gmatch("(.-)\n")()then for a in u:gmatch("(.-)\n")do local a=a:gsub("\r","")table.insert(v,a)end else v={u}end else s=shell.workingDirectory..a;r="[NEW FILE]"v={""}end else s=""r="[NEW FILE]"v={""}end;local function a()d.setActiveBuffer(n)clear()local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;for a=i,g+i-3 do d.set(1,a-i+1,(v[a]or""):sub(h))end;q(1,g-1,"\27[107m\27[30m"..r..string.rep(" ",f))q(1,g,"\27[107m\27[30m^X\27[0m Exit \27[107m\27[30m^S\27[0m Save"..string.rep(" ",f))local b=d.get(a,k)if l then d.setForeground(0)d.setBackground(16777215)end;d.set(a,k,b)d.bitblt()d.setActiveBuffer(0)end;local n,q=false,false;local function t()k=k-1;q=true;l=true;if k<1 then n=true;i=i-1;k=1 end;if i<1 then n=false;i=1 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function u()k=k+1;q=true;l=true;if k+i-1>#v then n=false;k=#v-i+1 end;if k>g-2 then n=true;i=i+1;k=g-2 end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function w()q=true;l=true;if j>1 then if j<=e.wlen(v[k+i-1])-h+2 then j=j-1 elseif e.wlen(v[k+i-1])-h+1>1 then j=e.wlen(v[k+i-1])-h+1 end elseif h>1 then h=h-1;n=true end;if math.min(j,e.wlen(v[k+i-1])-h+2)<1 then n=true end end;local function x()q=true;l=true;if j<=e.wlen(v[k+i-1])-h+1 then j=j+1 end;if j>f then j=f;h=h+1;n=true end end;local function y(a)n,q=false,false;if a[1]=="key_down"then local b=a[4]local b=keyboard.keys[b]if keyboard.ctrlDown then return false,false,b end;if b=="down"and k<#v then u()end;if b=="up"then t()end;if b=="left"then w()end;if b=="right"then x()end;if b=="enter"then m=true;n=true;l=true;table.insert(v,k+1,v[k+i-1]:sub(j))v[k+i-1]=v[k+i-1]:sub(1,j-1)j=1;k=k+1;h=1;if k>g-2 then i=i+1;k=g-2 end end;if b=="back"then m=true;q=true;l=true;if j==1 and k+i-1>1 then k=k-1;if k<1 then i=i-1;k=1 end;if i<1 then i=1 end;j=e.wlen(v[k+i-1])-h+2;if j>f then h=j-f+1;j=f end;v[k+i-1]=v[k+i-1]..v[k+1]table.remove(v,k+1)n=true else v[k+i-1]=v[k+i-1]:sub(1,j+h-3)..v[k+i-1]:sub(j+h-1)j=math.min(j-1,e.wlen(v[k+i-1])+1)if j<1 then j=1;h=h-1;n=true else d.set(1,k,v[k+i-1]:sub(h).." ")end end end;if b=="tab"then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..p..v[k+i-1]:sub(j+h-1)j=j+e.wlen(p)if j>f then h=h+j-f;j=f;n=true else d.set(1,k,v[k+i-1]:sub(h))end end;if a[3]>=32 and a[3]<=126 then m=true;q=true;l=true;v[k+i-1]=v[k+i-1]:sub(1,j+h-2)..e.char(a[3])..v[k+i-1]:sub(j+h-1)j=math.min(j,e.wlen(v[k+i-1]))+1;if j>f then j=f;h=h+1;n=true else d.set(1,k,v[k+i-1]:sub(h))end end elseif a[1]=="scroll"then if a[5]==1 then for a=1,o do t()end elseif a[5]==-1 and k<#v then for a=1,o do u()end end end;return n,q end;local function n()d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,string.rep(" ",f))termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mSave location: ",s)d.setBackground(16777215)d.setForeground(0)if b.exists(a)then d.set(1,g-1,string.rep(" ",f))local a=read(nil,"\27[107m\27[30mFile already exists. Overwrite it? [Y/n] ")if a:lower()=="n"then d.setBackground(16777215)d.setForeground(0)d.set(1,g-1,r..string.rep(" ",f))return end end;local a,b=b.open(a,"w")if a then if table.concat(v,"\n"):sub(-1,-1)=="\n"then a:write(table.concat(v,"\n"))else a:write(table.concat(v,"\n").."\n")end;a:close()d.set(1,g-1,r..string.rep(" ",f))else d.set(1,g-1,"ERROR: "..b:gsub("\n","")..string.rep(" ",f))end;m=false end;a()while true do local b={c.pull(0.5)}local f,o,p=false,false,nil;local q,r=math.min(j,e.wlen(v[k+i-1])-h+2),k;if b and b[1]then l=true;f,o,p=y(b)if p=="x"then if m then termlib.cursorPosX=1;termlib.cursorPosY=g-1;local a=read(nil,"\27[107m\27[30mWould you like to save changes? [Y/n] ")if a:lower()~="n"then n()end end;d.freeAllBuffers()clear()return end;if p=="s"then n()end;repeat b={c.pull("key_down",0)}if b and b[1]then y(b)end until not b or not b[1]else l=not l;o=true end;if o then local a=d.get(q,r)d.set(q,r,a)local a=math.min(j,e.wlen(v[k+i-1])-h+2)if a<1 then h=h+a-1;j=1;a=math.min(j,e.wlen(v[k+i-1])-h+2)end;local b=d.get(a,k)if l then d.setBackground(16777215)d.setForeground(0)end;d.set(a,k,b)if l then d.setForeground(16777215)d.setBackground(0)end end;if f then a()end end
local fs = require("filesystem")
local event = require("event")
local component = require("component")
local unicode = require("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
+1 -70
View File
@@ -1,70 +1 @@
local component = require("component") local a=import("component")local b=import("computer")local function c(a)termlib.cursorPosX=35;termlib.write(a.."\n",false)end;termlib.write(_OSLOGO,false)termlib.cursorPosY=termlib.cursorPosY-17;c("\27[92mOS\27[0m: ".._OSVERSION)c("\27[92mArchitecture\27[0m: ".._VERSION)local d=0;for a,a in a.list()do d=d+1 end;c("\27[92mComponents\27[0m: "..tostring(d))c("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList))c("\27[92mBattery\27[0m: "..tostring(math.floor(b.energy()/b.maxEnergy()*1000+0.5)/10).."%")local d=b.totalMemory()local e=b.totalMemory()-b.freeMemory()local f;if convert(d,"B","GiB")>=1 then f=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then f=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then f=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else f=tostring(d).." B"end;local d;if convert(e,"B","GiB")>=1 then d=tostring(math.floor(convert(e,"B","GiB")*100+0.5)/100).." GiB"elseif convert(e,"B","MiB")>=1 then d=tostring(math.floor(convert(e,"B","MiB")*100+0.5)/100).." MiB"elseif convert(e,"B","KiB")>=1 then d=tostring(math.floor(convert(e,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(e).." B"end;c("\27[92mMemory\27[0m: "..d.." / "..f)local d=a.invoke(b.getBootAddress(),"spaceTotal")local b=a.invoke(b.getBootAddress(),"spaceUsed")local e;if convert(d,"B","GiB")>=1 then e=tostring(math.floor(convert(d,"B","GiB")*100+0.5)/100).." GiB"elseif convert(d,"B","MiB")>=1 then e=tostring(math.floor(convert(d,"B","MiB")*100+0.5)/100).." MiB"elseif convert(d,"B","KiB")>=1 then e=tostring(math.floor(convert(d,"B","KiB")*100+0.5)/100).." KiB"else e=tostring(d).." B"end;local d;if convert(b,"B","GiB")>=1 then d=tostring(math.floor(convert(b,"B","GiB")*100+0.5)/100).." GiB"elseif convert(b,"B","MiB")>=1 then d=tostring(math.floor(convert(b,"B","MiB")*100+0.5)/100).." MiB"elseif convert(b,"B","KiB")>=1 then d=tostring(math.floor(convert(b,"B","KiB")*100+0.5)/100).." KiB"else d=tostring(b).." B"end;c("\27[92mDisk\27[0m: "..d.." / "..e)local a,b=a.invoke(a.list("gpu")(),"getResolution")c("\27[92mResolution\27[0m: "..tostring(a).."x"..tostring(b).."\n")c("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ")c("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ")termlib.cursorPosY=termlib.cursorPosY+5
local computer = require("computer")
local function printstat(text)
terminal.cursorPosX = 35
terminal.write(text .. "\n", false)
end
terminal.write(_OSLOGO, false)
terminal.cursorPosY = terminal.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(#tsched.getTasks()))
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 ")
terminal.cursorPosY = terminal.cursorPosY + 5
+1 -38
View File
@@ -1,38 +1 @@
local fs = require("filesystem") local a=import("filesystem")local b={...}local c=b[1]b=nil;if not c then local a,b,c=a.open("/halyde/apps/helpdb/default.txt","r"),"",nil;repeat c=a:read(math.huge or math.maxinteger)b=b..(c or"")until not c;print(b)return end;if shell.aliases[c]then c=shell.aliases[c]end;if a.exists("/halyde/apps/helpdb/"..c..".txt")then local a,b,d=a.open("/halyde/apps/helpdb/"..c..".txt","r"),"",nil;repeat d=a:read(math.huge or math.maxinteger)b=b..(d or"")until not d;print(b)local a=table.copy(shell.aliases)if table.find(a,c)then local b=table.find(a,c)local d="Aliases:\n "..b;a[b]=nil;while table.find(a,c)do b=table.find(a,c)d=d..", "..b;a[b]=nil end;print(d)end else print("Could not find help file for: "..c..".")end
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
+1 -92
View File
@@ -1,92 +1 @@
local component = require("component") local a=import("component")local b=import("computer")local c={...}if not c then return print("\x1b[91mCannot get arguments.")end;if not c[1]then return shell.run("help label")end;local d=c[1]local e;local function f(b)if b>=5 and b<=8 then b=b-1 end;for c,d in a.list()do if a.slot(c)==b then e=a.proxy(c)end end end;if d=="eeprom"then e=a.eeprom elseif d=="halyde"then e=a.proxy(b.getBootAddress())elseif d:sub(1,4)=="slot"and tonumber(d:sub(5))then local a=tonumber(d:sub(5))-1;f(a)elseif d:sub(1,1)=="#"and tonumber(d:sub(2))then local a=tonumber(d:sub(2))+5;f(a)elseif#d>=3 then local b=a.get(d)if not b then return print("\x1b[91mCould not find entire component ID from \""..d.."\".")end;e=a.proxy(b)else print("\x1b[91mAddress must have atleast 3 characters")return shell.run("help label")end;if not e then return print("\x1b[91mCould not find component from \""..d.."\".")end;local a=e.address;local function b(a)return a:sub(1,8).."\x1b[37m"..a:sub(9).."\x1b[39m"end;local function d(c)print("This \x1b[92m"..(e.type or"unknown").."\x1b[39m component doesn't support "..c.." labels.\nID: "..b(a))end;local function f(b,c)print("\x1b[91mAn error occured while "..b.." the label of this component.\nComponent: "..(a or"unknown id").." ("..((e or{}).type or"unknown type")..")\n\n"..c)end;local function g(a)local b="No label defined"if a then b="\""..a.."\""end;return b end;if type(c[2])~="string"then if not e.getLabel then return d("getting")end;local c;local d,h=pcall(function()c=e.getLabel()end)if d then print("Label of "..b(a)..((e.type and e.type~="filesystem")and" ("..e.type..")"or"")..":\n \x1b[92m"..g(c).."\x1b[39m")else f("getting",h)end else if not e.setLabel then return d("setting")end;local d=""for a=2,#c do d=d..tostring(c[a])if a<#c then d=d.." "end end;local c;local d,h=pcall(function()c=e.setLabel(d)end)if d then print("Successfully set label of "..b(a)..(e.type and" ("..e.type..")"or"").." to:\n \x1b[92m"..g(c).."\x1b[39m")else f("setting",h)end end
local computer = require("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
+1 -70
View File
@@ -1,70 +1 @@
local args = {...} local a={...}local b=a[1]a=nil;local a=import("filesystem")local c=import("unicode")local d=0;local e=2;local f={}local g={}if b then if b:sub(1,1)~="/"then b=a.concat(shell.workingDirectory,b)end else b=shell.workingDirectory end;local h=a.list(b)if h then for a,a in pairs(h)do if a:sub(-1,-1)=="/"then table.insert(f,a)a=a:sub(1,-2)else table.insert(g,a)end;if c.wlen(a)>d then d=c.wlen(a)end end;table.sort(f)table.sort(g)h={}for a,a in ipairs(f)do table.insert(h,a)end;for a,a in ipairs(g)do table.insert(h,a)end;f,g=nil,nil;for f,f in ipairs(h)do local g=false;local h;if f:sub(-1,-1)=="/"then g=true;h="\27[93m"..f:sub(1,-2)elseif f:find(".")and f:match("[^.]+$")=="lua"then h="\27[92m"..f end;h=(h or f)..string.rep(" ",d-c.wlen(f)+e)if g then print(h.." \27[0m[DIR]")else local a=a.size(a.concat(b,f))local b;if convert(a,"B","GiB")>=1 then b=tostring(math.floor(convert(a,"B","GiB")*100+0.5)/100).." GiB"elseif convert(a,"B","MiB")>=1 then b=tostring(math.floor(convert(a,"B","MiB")*100+0.5)/100).." MiB"elseif convert(a,"B","KiB")>=1 then b=tostring(math.floor(convert(a,"B","KiB")*100+0.5)/100).." KiB"else b=tostring(a).." B"end;print(h.."\27[0m"..b)end end end
local target = args[1]
args = nil
local fs = require("filesystem")
local unicode = require("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
+1 -9
View File
@@ -1,9 +1 @@
print("\27[93m"..tostring(#cormgr.corList).."\27[0m coroutines active") print("\27[93m"..tostring(#cormgr.corList).."\27[0m coroutines active")for a=1,#cormgr.corList do if a==#cormgr.corList then print("\27[93m└ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")else print("\27[93m├ "..a.."\27[0m - "..cormgr.labelList[a].." \27[0m")end end
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
+1 -320
View File
File diff suppressed because one or more lines are too long
+1 -31
View File
@@ -1,31 +1 @@
print("\27[44m".._VERSION.."\27[0m shell") print("\27[44m".._VERSION.."\27[0m shell")print('Type "exit" to exit.')termlib.readHistory["lua"]={""}local a=import("filesystem")local b=""local a=a.list("halyde/lib")for a,a in pairs(a)do if a:match("(.+)%.lua")then b=b.."local "..a:match("(.+)%.lua")..' = import("'..a:match("(.+)%.lua")..'")\n'end end;while true do local a=read("lua","\27[44mlua>\27[0m ")if a=="exit"then return else local function c()local a=load(b.."return "..a,"=stdin")or load(b..a,"=stdin")local a={assert(a)()}if a and(type(a[1])~="nil"or type(a[2])~="nil")then print(table.unpack(a))end end;local a,b=xpcall(c,function(a)return a.."\n\n"..debug.traceback()end)if not a then print("\27[91m"..b)end end end
print('Type "exit" to exit.')
termlib.readHistory["lua"] = {""}
local fs = require("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") .. ' = require("' .. 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
+1 -8
View File
@@ -1,8 +1 @@
local computer = require("computer") local a=import("computer")if type(a)~="table"then return print("\x1b[91mComputer library returned '"..type(a).."' type\x1b[39m")end;local a=a.getBootAddress()print(a)
if type(computer)~="table" then
return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m")
end
local address = computer.getBootAddress()
print(address)
+1 -14
View File
@@ -1,14 +1 @@
local directory = ... local a=...local b=import("filesystem")if not a then shell.run("help mkdir")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if b.exists(a)then print("\27[91mAn object already exists at the specified path.")end;b.makeDirectory(a)
local fs = require("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)
+1 -24
View File
@@ -1,24 +1 @@
local fromFile, toFile = ... local a,b=...local c=import("filesystem")if not a or not b then shell.run("help mv")return end;if a:sub(1,1)~="/"then a=c.concat(shell.workingDirectory,a)end;if b:sub(1,1)~="/"then b=c.concat(shell.workingDirectory,b)end;if a==b then print("\27[91mSource and destination are the same.")end;if not c.exists(a)then print("\27[91mSource file does not exist.")end;if c.exists(b)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;c.rename(a,b)
local fs = require("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)
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown(true) import("computer").shutdown(true)
View File
+1 -15
View File
@@ -1,15 +1 @@
local file = ... local a=...local b=import("filesystem")if not a then shell.run("help rm")return end;if a:sub(1,1)~="/"then a=b.concat(shell.workingDirectory,a)end;if not b.exists(a)then print("\27[91mFile does not exist.")return end;b.remove(a)
local fs = require("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)
+1 -91
View File
@@ -1,91 +1 @@
local raster = require("raster") local a=import("raster")a.init()local b=import("event")local c=0;local d=0;local e=1;local f=1;local g=8421504;local h=0;while b.pull("key_down",0)==nil do h=h+1;a.set(c,d,g)c=c+e;d=d+f;if c>a.displayWidth then c=a.displayWidth;e=-math.abs(e)g=math.random(0,16777215)end;if c<1 then c=1;e=math.abs(e)g=math.random(0,16777215)end;if d>a.displayHeight-6 then d=a.displayHeight-6;f=-math.abs(f)g=math.random(0,16777215)end;if d<1 then d=1;f=math.abs(f)g=math.random(0,16777215)end;if h>10 and h%15>0 then while true do local b=0;local c,d=math.random(1,a.displayWidth),math.random(1,a.displayHeight-6)if a.get(c,d)~=0 then a.set(c,d,0)break end;b=b+1;if b>20 then break end end end;if h%10==0 then a.update()coroutine.yield()end end;a.free()termlib.cursorPosY=1
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 = require("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
+1 -141
View File
@@ -1,141 +1 @@
local component = require("component") local a=import("component")local b=import("computer")local c=import("raster")local d=import("event")local a,e=a.invoke(a.list("gpu")(),"getResolution")a,e=a*2,e*4;local a=a/2;local e=e/2;local f=10;local g=0;local h=16777215;local i=0.1;local j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}local k={{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}}local l=256;local m=300;local n,o,p=0,0,0;local function q(a,b,c)local d,e=math.cos(n),math.sin(n)local f=b*d-c*e;local b=b*e+c*d;local c,d=math.cos(o),math.sin(o)local e=a*c+b*d;local a=-a*d+b*c;local b,c=math.cos(p),math.sin(p)local d=e*b-f*c;local b=e*c+f*b;return d,b,a end;local function r(b,c,d)local d=l/(d+m)local a=b*d+a;local b=c*d+e;return a,b end;local function a()local a=b.uptime()*20;g=a*0.05;f=(math.sin(g)+1)*25;j={{-f,-f,-f},{f,-f,-f},{f,f,-f},{-f,f,-f},{-f,-f,f},{f,-f,f},{f,f,f},{-f,f,f}}c.clear()n=a*i;o=a*i*0.7;p=a*i*0.5;local a={}for b,c in ipairs(j)do local c,d,e=q(c[1],c[2],c[3])local c,d=r(c,d,e)a[b]={c,d}end;for b,b in ipairs(k)do local d=a[b[1]+1]local a=a[b[2]+1]c.drawLine(d[1],d[2],a[1],a[2],h)end;c.update()end;function main()c.init()while true do a()coroutine.yield()if d.pull("key_down",0)then c.free()break end end;return a end;return main()
local computer = require("computer")
local raster = require("raster")
local event = require("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()
+1 -1
View File
@@ -1 +1 @@
require("computer").shutdown() import("computer").shutdown()
+1 -1
View File
@@ -1 +1 @@
{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!","Now i% more secure!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"} {"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"}
+1 -1
View File
@@ -1 +1 @@
["/halyde/shell/shell.lua"] ["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/drvload.lua","/halyde/core/shell.lua"]
+1
View File
@@ -0,0 +1 @@
local a=...local b=a("/halyde/lib/filesystem.lua")(a)_G._OSVERSION="Halyde 2.8.1"_G._OSLOGO=""local c,d=b.open("/halyde/config/oslogo.ans","r"),nil;repeat d=c:read(math.huge)_OSLOGO=_OSLOGO..(d or"")until not d;_G.package={["preloaded"]={}}a("/halyde/core/datatools.lua")()function _G.import(a,...)local c=table.pack(...)if package.preloaded[a]then return package.preloaded[a]end;local d;if b.exists(a)then d=a elseif b.exists("/halyde/lib/"..a..".lua")then d="/halyde/lib/"..a..".lua"elseif shell and shell.workingDirectory and b.exists(shell.workingDirectory..a)then d=shell.workingDirectory..a end;assert(d,"module not found\npossible locations:\n/halyde/lib/"..a..".lua")local a,b,e=b.open(d),"",nil;repeat e=a:read(math.huge or math.maxinteger)b=b..(e or"")until not e;a:close()return(assert(load(b,"="..d))(table.unpack(c)))end;local function a(a)local b,c,d=assert(b.open("/halyde/lib/"..a..".lua","r")),"",nil;repeat d=b:read(math.huge or math.maxinteger)c=c..(d or"")until not d;package.preloaded[a]=assert(load(c,"="..a))()_G[a]=nil end;a("component")a("computer")a("filesystem")local a=import("component")local b=a.gpu;local a=a.list("screen")()b.bind(a)b.setResolution(b.maxResolution())local a=import("filesystem")if not a.exists("/halyde/config/shell.json")then a.copy("/halyde/config/generate/shell.json","/halyde/config/shell.json")end;if not a.exists("/halyde/config/startupapps.json")then a.copy("/halyde/config/generate/startupapps.json","/halyde/config/startupapps.json")end;a=nil;import("/halyde/core/cormgr.lua")
+1
View File
@@ -0,0 +1 @@
_G.cormgr={}_G.cormgr.corList={}_G.cormgr.labelList={}local a=import("component")local b=import("filesystem")local c=import("json")local a=a.gpu;function _G.cormgr.loadCoroutine(b,...)local c={...}local function d()local b,c=xpcall(function(...)import(...)end,function(a)return a.."\n \n"..debug.traceback()end,b,table.unpack(c))if not b then if print then a.freeAllBuffers()print("\n\27[91m"..c)else error(c)end end end;cormgr.addCoroutine(d,string.match(tostring(b),"([^/]+)%.lua$"))end;function _G.cormgr.addCoroutine(a,b)local a=coroutine.create(a)table.insert(cormgr.corList,a)table.insert(cormgr.labelList,b)return a end;function _G.cormgr.removeCoroutine(a)local a=table.find(cormgr.labelList,cor)table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)end;function handleError(a)if a==nil then error("unknown error")else error(tostring(a).."\n \n"..debug.traceback())end end;local function a()for a=1,#_G.cormgr.corList do if cormgr.corList[a]then local b,c=coroutine.resume(cormgr.corList[a])if cormgr.corList[a]then if not b then handleError(c)end;if coroutine.status(cormgr.corList[a])=="dead"then table.remove(cormgr.corList,a)table.remove(cormgr.labelList,a)a=a-1 end end end end end;local b,d,e=b.open("/halyde/config/startupapps.json","r"),"",nil;repeat e=b:read(math.huge or math.maxinteger)d=d..(e or"")until not e;b:close()for b,b in ipairs(c.decode(d))do if b~=""then _G.cormgr.loadCoroutine(b)a()end end;while true do a()if#_G.cormgr.corList==0 then computer.shutdown()end end
+1
View File
@@ -0,0 +1 @@
local a={["bytes"]={["B"]=1,["KB"]=1000,["MB"]=1000000,["GB"]=1000000000},["bibytes"]={["B"]=1,["KiB"]=1024,["MiB"]=1048576,["GiB"]=1073741824}}function table.find(a,b)for a,c in pairs(a)do if c==b then return a end end end;function table.copy(a)local b=type(a)local c;if b=='table'then c={}for a,b in next,a,nil do c[table.copy(a)]=table.copy(b)end;setmetatable(c,table.copy(getmetatable(a)))else c=a end;return c end;function convert(b,c,d)for a,a in pairs(a)do if a[d]then return b/a[d]*a[c]end end;return false,"unit does not exist"end
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b="/halyde/drivers"local c=a.list(b)local d={}local function e(f)local a=import(a.concat(b,f))table.remove(c,table.find(c,f))if a.dependencies then for a,a in pairs(a.dependencies)do if table.find(c,a)then e(a)elseif table.find(c,a..".lua")then e(a..".lua")else for b,c in pairs(d)do if c==a then e(b)end end end end end;if a.onStartup then a.onStartup()end end;for c,c in pairs(c)do local a=import(a.concat(b,c))if a.type then d[c]=a.type end end;for a,a in pairs(c)do if a:sub(-1,-1)~="/"then e(a)end end
+1
View File
@@ -0,0 +1 @@
_G.evmgr={}_G.evmgr.eventQueue={}local a=10;local b=import("computer")keyboard.ctrlDown=false;keyboard.altDown=false;keyboard.shiftDown=false;while true do local c;repeat c={b.uptime(),b.pullSignal(0)}if c and c[2]then table.insert(evmgr.eventQueue,c)if keyboard then if c[2]=="key_down"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=true elseif a=="lmenu"then keyboard.altDown=true elseif a=="lshift"then keyboard.shiftDown=true elseif a=="c"and keyboard.ctrlDown and keyboard.altDown then if print then print("\n\27[91mCoroutine "..tostring(#cormgr.corList).." killed.")end;cormgr.corList[#cormgr.corList]=nil end elseif c[2]=="key_up"then local a=c[5]local a=keyboard.keys[a]if a=="lcontrol"then keyboard.ctrlDown=false elseif a=="lmenu"then keyboard.altDown=false elseif a=="lshift"then keyboard.shiftDown=true end end end;while#evmgr.eventQueue>a do table.remove(evmgr.eventQueue,1)end end until not c or not c[1]coroutine.yield()end
+1
View File
@@ -0,0 +1 @@
_G.keyboard={["keys"]={}}keyboard.keys["1"]=2;keyboard.keys["2"]=3;keyboard.keys["3"]=4;keyboard.keys["4"]=5;keyboard.keys["5"]=6;keyboard.keys["6"]=7;keyboard.keys["7"]=8;keyboard.keys["8"]=9;keyboard.keys["9"]=10;keyboard.keys["0"]=11;keyboard.keys.a=30;keyboard.keys.b=48;keyboard.keys.c=46;keyboard.keys.d=32;keyboard.keys.e=18;keyboard.keys.f=33;keyboard.keys.g=34;keyboard.keys.h=35;keyboard.keys.i=23;keyboard.keys.j=36;keyboard.keys.k=37;keyboard.keys.l=38;keyboard.keys.m=50;keyboard.keys.n=49;keyboard.keys.o=24;keyboard.keys.p=25;keyboard.keys.q=16;keyboard.keys.r=19;keyboard.keys.s=31;keyboard.keys.t=20;keyboard.keys.u=22;keyboard.keys.v=47;keyboard.keys.w=17;keyboard.keys.x=45;keyboard.keys.y=21;keyboard.keys.z=44;keyboard.keys.apostrophe=40;keyboard.keys.at=145;keyboard.keys.back=14;keyboard.keys.backslash=43;keyboard.keys.capital=58;keyboard.keys.colon=146;keyboard.keys.comma=51;keyboard.keys.enter=28;keyboard.keys.equals=13;keyboard.keys.grave=41;keyboard.keys.lbracket=26;keyboard.keys.lcontrol=29;keyboard.keys.lmenu=56;keyboard.keys.lshift=42;keyboard.keys.minus=12;keyboard.keys.numlock=69;keyboard.keys.pause=197;keyboard.keys.period=52;keyboard.keys.rbracket=27;keyboard.keys.rcontrol=157;keyboard.keys.rmenu=184;keyboard.keys.rshift=54;keyboard.keys.scroll=70;keyboard.keys.semicolon=39;keyboard.keys.slash=53;keyboard.keys.space=57;keyboard.keys.stop=149;keyboard.keys.tab=15;keyboard.keys.underline=147;keyboard.keys.up=200;keyboard.keys.down=208;keyboard.keys.left=203;keyboard.keys.right=205;keyboard.keys.home=199;keyboard.keys["end"]=207;keyboard.keys.pageUp=201;keyboard.keys.pageDown=209;keyboard.keys.insert=210;keyboard.keys.delete=211;keyboard.keys.f1=59;keyboard.keys.f2=60;keyboard.keys.f3=61;keyboard.keys.f4=62;keyboard.keys.f5=63;keyboard.keys.f6=64;keyboard.keys.f7=65;keyboard.keys.f8=66;keyboard.keys.f9=67;keyboard.keys.f10=68;keyboard.keys.f11=87;keyboard.keys.f12=88;keyboard.keys.f13=100;keyboard.keys.f14=101;keyboard.keys.f15=102;keyboard.keys.f16=103;keyboard.keys.f17=104;keyboard.keys.f18=105;keyboard.keys.f19=113;keyboard.keys.kana=112;keyboard.keys.kanji=148;keyboard.keys.convert=121;keyboard.keys.noconvert=123;keyboard.keys.yen=125;keyboard.keys.circumflex=144;keyboard.keys.ax=150;keyboard.keys.numpad0=82;keyboard.keys.numpad1=79;keyboard.keys.numpad2=80;keyboard.keys.numpad3=81;keyboard.keys.numpad4=75;keyboard.keys.numpad5=76;keyboard.keys.numpad6=77;keyboard.keys.numpad7=71;keyboard.keys.numpad8=72;keyboard.keys.numpad9=73;keyboard.keys.numpadmul=55;keyboard.keys.numpaddiv=181;keyboard.keys.numpadsub=74;keyboard.keys.numpadadd=78;keyboard.keys.numpaddecimal=83;keyboard.keys.numpadcomma=179;keyboard.keys.numpadenter=156;keyboard.keys.numpadequals=141;setmetatable(keyboard.keys,{__index=function(a,b)if type(b)~="number"then return end;for a,c in pairs(a)do if c==b then return a end end end})
+1
View File
@@ -0,0 +1 @@
local a=import("filesystem")local b=import("json")local c,d,e=a.open("/halyde/config/shell.json","r"),"",nil;repeat e=c:read(math.huge)d=d..(e or"")until not e;c:close()local b=b.decode(d)import("/halyde/core/termlib.lua")local c=import("event")local c=import("component")local c=c.gpu;_G.shell={}_G.shell.workingDirectory=b["defaultWorkingDirectory"]_G.shell.aliases=b["aliases"]local function d(a,...)cormgr.loadCoroutine(a,...)local a=#cormgr.corList;local b=cormgr.corList[#cormgr.corList]repeat coroutine.yield()until cormgr.corList[a]~=b end;function _G.shell.run(c)checkArg(1,c,"string")if shell.aliases[c:match("[^ ]+")]then local a,a=c:find("[^ ]+")c=shell.aliases[c:match("[^ ]+")]..c:sub(a+1)end;local c,e,f,g=c:gmatch("[^ ]+"),nil,{},c;while true do e=c()if not e then break end;if e:find('"')then local a=g:find('"')local b=e:sub(1,e:find('"')-1)if b and b~=""then table.insert(f,b)end;g=g:sub(a+1)if g:find('"')then table.insert(f,g:sub(1,g:find('"')-1))g=g:sub(g:find('"')+1)c=g:gmatch('[^ ]+')else print("\27[91mmalformed shell command")return end else table.insert(f,e)end end;local b=table.copy(b.path)table.insert(b,shell.workingDirectory)if not f[1]then return end;if a.exists(f[1])and not a.isDirectory(f[1])then local a=f[1]table.remove(f,1)d(a,table.unpack(f))return end;for b,b in pairs(b)do if a.exists(b..f[1])and not a.isDirectory(b..f[1])then local a=a.concat(b,f[1])table.remove(f,1)d(a,table.unpack(f))return else local c=a.list(b)or{}for c,c in pairs(c)do if f[1]==c:match("(.+)%.[^%.]+$")and not a.isDirectory(b..c)then table.remove(f,1)d(b..c,table.unpack(f))return end end end end;print("No such file or command: "..f[1])end;print(b["startupMessage"]:format(_OSVERSION,b.splashMessages[math.random(1,#b.splashMessages)]))while true do coroutine.yield()if shell.workingDirectory:sub(-1,-1)~="/"then shell.workingDirectory=shell.workingDirectory.."/"end;local a=read("shell",b.prompt:format(shell.workingDirectory))shell.run(a)c.freeAllBuffers()end
File diff suppressed because one or more lines are too long
-73
View File
@@ -1,73 +0,0 @@
local loadfile = ...
local filesystem = assert(loadfile("/lib/filesystem.lua")(loadfile))
_G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file
_G._OSLOGO = ""
_G._PUBLIC = {}
local ocelot = component.proxy(component.list("ocelot")())
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
tmpdata = handle:read(math.huge)
_OSLOGO = _OSLOGO .. (tmpdata or "")
until not tmpdata
_G.package = {["preloaded"] = {}}
loadfile("/halyde/kernel/modules/datatools.lua")()
function _G.require(module, ...)
ocelot.log("Requiring " .. module)
local args = table.pack(...)
if package.preloaded[module] then
return package.preloaded[module]
end
local modulepath
if filesystem.exists(module) then
modulepath = module
elseif filesystem.exists("/lib/" .. module .. ".lua") then
modulepath = "/lib/" .. module .. ".lua"
elseif shell and shell.workingDirectory and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua")) then
modulepath = shell.workingDirectory .. module .. ".lua"
end
assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua")
local handle, data, tmpdata = filesystem.open(modulepath), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return(assert(load(data, "="..modulepath))(table.unpack(args)))
end
function _G.package.preload(module)
local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
package.preloaded[module] = assert(load(data, "="..module))()
_G[module] = nil
end
require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools.
require("/halyde/kernel/modload.lua")
package.preload("component")
package.preload("computer")
local component = require("component")
local gpu = component.gpu
local screenAddress = component.list("screen")()
gpu.bind(screenAddress)
gpu.setResolution(gpu.maxResolution())
if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs
filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json")
end
if not filesystem.exists("/halyde/config/startupapps.json") then
filesystem.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json")
end
require("/halyde/kernel/tsched.lua")
-45
View File
@@ -1,45 +0,0 @@
local conversionTables = {
["bytes"] = {
["B"] = 1,
["KB"] = 1000,
["MB"] = 1000000,
["GB"] = 1000000000
}, ["bibytes"] = {
["B"] = 1,
["KiB"] = 1024,
["MiB"] = 1048576,
["GiB"] = 1073741824
}
}
function table.find(tab, item)
for k, v in pairs(tab) do
if v == item then
return k
end
end
end
function table.copy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[table.copy(orig_key)] = table.copy(orig_value)
end
setmetatable(copy, table.copy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function convert(amount, fromUnit, toUnit)
for _, convTable in pairs(conversionTables) do
if convTable[toUnit] then
return amount / convTable[toUnit] * convTable[fromUnit]
end
end
return false, "unit does not exist"
end
-55
View File
@@ -1,55 +0,0 @@
_G.evmgr = {}
_G.evmgr.eventQueue = {}
local maxEventQueueLength = 10 -- increase if events start getting dropped
local computer = require("computer")
_G._PUBLIC.keyboard.ctrlDown = false
_G._PUBLIC.keyboard.altDown = false
_G._PUBLIC.keyboard.shiftDown = false
--local ocelot = component.proxy(component.list("ocelot")())
while true do
local args
repeat
args = {computer.uptime(), computer.pullSignal(0)}
if args and args[2] then
table.insert(evmgr.eventQueue, args)
if _PUBLIC.keyboard then
if args[2] == "key_down" then
local keycode = args[5]
local key = _PUBLIC.keyboard.keys[keycode]
if key == "lcontrol" then
_PUBLIC.keyboard.ctrlDown = true
elseif key == "lmenu" then
_PUBLIC.keyboard.altDown = true
elseif key == "lshift" then
_PUBLIC.keyboard.shiftDown = true
elseif key == "c" and _PUBLIC.keyboard.ctrlDown and _PUBLIC.keyboard.altDown then
if print then
print("\n\27[91mCoroutine "..tostring(#tsched.tasks).." killed.")
end
tsched.tasks[#tsched.tasks] = nil
end
elseif args[2] == "key_up" then
local keycode = args[5]
local key = _PUBLIC.keyboard.keys[keycode]
if key == "lcontrol" then
_PUBLIC.keyboard.ctrlDown = false
elseif key == "lmenu" then
_PUBLIC.keyboard.altDown = false
elseif key == "lshift" then
_PUBLIC.keyboard.shiftDown = true
end
end
end
while #evmgr.eventQueue > maxEventQueueLength do
--ocelot.log("Queue length breach, removing first signal")
table.remove(evmgr.eventQueue, 1)
end
end
until not args or not args[1]
--ocelot.log("done")
coroutine.yield()
end
-53
View File
@@ -1,53 +0,0 @@
local fs = require("filesystem")
local ocelot = require("component").ocelot
local modulePath = "/halyde/kernel/modules"
local modules = fs.list(modulePath)
local moduleTypes = {}
local function loadModule(modName)
ocelot.log("Checking module " .. modName)
local moduleData = require(fs.concat(modulePath, modName))
table.remove(modules, table.find(modules, modName))
if not moduleData.check() then
return
end
ocelot.log("Loading module " .. modName)
if moduleData.dependencies then
for _, dependency in pairs(moduleData.dependencies) do
if table.find(modules, dependency) then
loadModule(dependency)
elseif table.find(modules, dependency .. ".lua") then
loadModule(dependency .. ".lua")
else
for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do
if typeLookupDrvType == dependency then
loadModule(typeLookupDrvName)
-- Don't break, because there can be multiple modules of the correct type
end
end
end
end
end
--print(modName)
if moduleData.init then -- I have no idea why this would not exist, but it's a failsafe
moduleData.init()
end
end
for _, modName in pairs(modules) do -- Get all the module types
local moduleData = require(fs.concat(modulePath, modName))
if moduleData.type then
--print(moduleData.type)
moduleTypes[modName] = moduleData.type -- Not the other way around because there can be multiple modules of the same type, but there can't be multiple entries with the same key
end
end
while modules[1] do
if modules[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config
loadModule(modules[1])
end
end
ocelot.log("Finished loading modules!")
-53
View File
@@ -1,53 +0,0 @@
local module = {}
module.dependencies = {"terminal"}
function module.check()
return true -- This module should always be loaded
end
function module.init()
local publicTable = {
"print",
"require",
"_VERSION",
"_OSVERSION",
"assert",
"error",
"getmetatable",
"ipairs",
"load",
"next",
"pairs",
"pcall",
"rawequal",
"rawget",
"rawlen",
"rawset",
"select",
"setmetatable",
"tonumber",
"tostring",
"type",
"xpcall",
"bit32",
"coroutine",
"debug",
"math",
"os",
"string",
"table",
"checkArg",
"utf8",
"convert"
}
for _, value in ipairs(publicTable) do
_G._PUBLIC[value] = table.copy(_G[value])
end
end
function module.exit()
_G._PUBLIC = nil
end
return module
-15
View File
@@ -1,15 +0,0 @@
local module = {}
function module.check()
return true -- This module should always be loaded
end
function module.init()
end
function module.exit()
end
return module
-157
View File
@@ -1,157 +0,0 @@
local module = {}
function module.check()
return true -- This module should always be loaded
end
function module.init()
_G._PUBLIC.keyboard = {["keys"] = {}}
_PUBLIC.keyboard.keys["1"] = 0x02
_PUBLIC.keyboard.keys["2"] = 0x03
_PUBLIC.keyboard.keys["3"] = 0x04
_PUBLIC.keyboard.keys["4"] = 0x05
_PUBLIC.keyboard.keys["5"] = 0x06
_PUBLIC.keyboard.keys["6"] = 0x07
_PUBLIC.keyboard.keys["7"] = 0x08
_PUBLIC.keyboard.keys["8"] = 0x09
_PUBLIC.keyboard.keys["9"] = 0x0A
_PUBLIC.keyboard.keys["0"] = 0x0B
_PUBLIC.keyboard.keys.a = 0x1E
_PUBLIC.keyboard.keys.b = 0x30
_PUBLIC.keyboard.keys.c = 0x2E
_PUBLIC.keyboard.keys.d = 0x20
_PUBLIC.keyboard.keys.e = 0x12
_PUBLIC.keyboard.keys.f = 0x21
_PUBLIC.keyboard.keys.g = 0x22
_PUBLIC.keyboard.keys.h = 0x23
_PUBLIC.keyboard.keys.i = 0x17
_PUBLIC.keyboard.keys.j = 0x24
_PUBLIC.keyboard.keys.k = 0x25
_PUBLIC.keyboard.keys.l = 0x26
_PUBLIC.keyboard.keys.m = 0x32
_PUBLIC.keyboard.keys.n = 0x31
_PUBLIC.keyboard.keys.o = 0x18
_PUBLIC.keyboard.keys.p = 0x19
_PUBLIC.keyboard.keys.q = 0x10
_PUBLIC.keyboard.keys.r = 0x13
_PUBLIC.keyboard.keys.s = 0x1F
_PUBLIC.keyboard.keys.t = 0x14
_PUBLIC.keyboard.keys.u = 0x16
_PUBLIC.keyboard.keys.v = 0x2F
_PUBLIC.keyboard.keys.w = 0x11
_PUBLIC.keyboard.keys.x = 0x2D
_PUBLIC.keyboard.keys.y = 0x15
_PUBLIC.keyboard.keys.z = 0x2C
_PUBLIC.keyboard.keys.apostrophe = 0x28
_PUBLIC.keyboard.keys.at = 0x91
_PUBLIC.keyboard.keys.back = 0x0E -- backspace
_PUBLIC.keyboard.keys.backslash = 0x2B
_PUBLIC.keyboard.keys.capital = 0x3A -- capslock
_PUBLIC.keyboard.keys.colon = 0x92
_PUBLIC.keyboard.keys.comma = 0x33
_PUBLIC.keyboard.keys.enter = 0x1C
_PUBLIC.keyboard.keys.equals = 0x0D
_PUBLIC.keyboard.keys.grave = 0x29 -- accent grave
_PUBLIC.keyboard.keys.lbracket = 0x1A
_PUBLIC.keyboard.keys.lcontrol = 0x1D
_PUBLIC.keyboard.keys.lmenu = 0x38 -- left Alt
_PUBLIC.keyboard.keys.lshift = 0x2A
_PUBLIC.keyboard.keys.minus = 0x0C
_PUBLIC.keyboard.keys.numlock = 0x45
_PUBLIC.keyboard.keys.pause = 0xC5
_PUBLIC.keyboard.keys.period = 0x34
_PUBLIC.keyboard.keys.rbracket = 0x1B
_PUBLIC.keyboard.keys.rcontrol = 0x9D
_PUBLIC.keyboard.keys.rmenu = 0xB8 -- right Alt
_PUBLIC.keyboard.keys.rshift = 0x36
_PUBLIC.keyboard.keys.scroll = 0x46 -- Scroll Lock
_PUBLIC.keyboard.keys.semicolon = 0x27
_PUBLIC.keyboard.keys.slash = 0x35 -- / on main _PUBLIC.keyboard
_PUBLIC.keyboard.keys.space = 0x39
_PUBLIC.keyboard.keys.stop = 0x95
_PUBLIC.keyboard.keys.tab = 0x0F
_PUBLIC.keyboard.keys.underline = 0x93
-- Keypad (and numpad with numlock off)
_PUBLIC.keyboard.keys.up = 0xC8
_PUBLIC.keyboard.keys.down = 0xD0
_PUBLIC.keyboard.keys.left = 0xCB
_PUBLIC.keyboard.keys.right = 0xCD
_PUBLIC.keyboard.keys.home = 0xC7
_PUBLIC.keyboard.keys["end"] = 0xCF
_PUBLIC.keyboard.keys.pageUp = 0xC9
_PUBLIC.keyboard.keys.pageDown = 0xD1
_PUBLIC.keyboard.keys.insert = 0xD2
_PUBLIC.keyboard.keys.delete = 0xD3
-- Function keys
_PUBLIC.keyboard.keys.f1 = 0x3B
_PUBLIC.keyboard.keys.f2 = 0x3C
_PUBLIC.keyboard.keys.f3 = 0x3D
_PUBLIC.keyboard.keys.f4 = 0x3E
_PUBLIC.keyboard.keys.f5 = 0x3F
_PUBLIC.keyboard.keys.f6 = 0x40
_PUBLIC.keyboard.keys.f7 = 0x41
_PUBLIC.keyboard.keys.f8 = 0x42
_PUBLIC.keyboard.keys.f9 = 0x43
_PUBLIC.keyboard.keys.f10 = 0x44
_PUBLIC.keyboard.keys.f11 = 0x57
_PUBLIC.keyboard.keys.f12 = 0x58
_PUBLIC.keyboard.keys.f13 = 0x64
_PUBLIC.keyboard.keys.f14 = 0x65
_PUBLIC.keyboard.keys.f15 = 0x66
_PUBLIC.keyboard.keys.f16 = 0x67
_PUBLIC.keyboard.keys.f17 = 0x68
_PUBLIC.keyboard.keys.f18 = 0x69
_PUBLIC.keyboard.keys.f19 = 0x71
-- Japanese keyboards
_PUBLIC.keyboard.keys.kana = 0x70
_PUBLIC.keyboard.keys.kanji = 0x94
_PUBLIC.keyboard.keys.convert = 0x79
_PUBLIC.keyboard.keys.noconvert = 0x7B
_PUBLIC.keyboard.keys.yen = 0x7D
_PUBLIC.keyboard.keys.circumflex = 0x90
_PUBLIC.keyboard.keys.ax = 0x96
-- Numpad
_PUBLIC.keyboard.keys.numpad0 = 0x52
_PUBLIC.keyboard.keys.numpad1 = 0x4F
_PUBLIC.keyboard.keys.numpad2 = 0x50
_PUBLIC.keyboard.keys.numpad3 = 0x51
_PUBLIC.keyboard.keys.numpad4 = 0x4B
_PUBLIC.keyboard.keys.numpad5 = 0x4C
_PUBLIC.keyboard.keys.numpad6 = 0x4D
_PUBLIC.keyboard.keys.numpad7 = 0x47
_PUBLIC.keyboard.keys.numpad8 = 0x48
_PUBLIC.keyboard.keys.numpad9 = 0x49
_PUBLIC.keyboard.keys.numpadmul = 0x37
_PUBLIC.keyboard.keys.numpaddiv = 0xB5
_PUBLIC.keyboard.keys.numpadsub = 0x4A
_PUBLIC.keyboard.keys.numpadadd = 0x4E
_PUBLIC.keyboard.keys.numpaddecimal = 0x53
_PUBLIC.keyboard.keys.numpadcomma = 0xB3
_PUBLIC.keyboard.keys.numpadenter = 0x9C
_PUBLIC.keyboard.keys.numpadequals = 0x8D
-- Create inverse mapping for name lookup.
setmetatable(_PUBLIC.keyboard.keys,
{
__index = function(tbl, k)
if type(k) ~= "number" then return end
for name,value in pairs(tbl) do
if value == k then
return name
end
end
end
})
end
function module.exit()
_G._PUBLIC.keyboard = nil
end
return module
-466
View File
@@ -1,466 +0,0 @@
local module = {}
function module.check()
return true -- Usually always loaded, but maybe it would be worth it to check if the computer has a GPU or not? I'm not sure.
end
function module.init()
local serialize = require("serialize")
local unicode = require("unicode")
local event = require("event")
--local ocelot = component.proxy(component.list("ocelot")())
local component = require("component")
local computer = require("computer")
local gpu = component.gpu
_G._PUBLIC.terminal = {}
_PUBLIC.terminal.cursorPosX = 1
_PUBLIC.terminal.cursorPosY = 1
_PUBLIC.terminal.readHistory = {}
local width, height = gpu.getResolution()
local ANSIColorPalette = {
["dark"] = {
[0] = 0x000000,
[1] = 0x800000,
[2] = 0x008000,
[3] = 0x808000,
[4] = 0x000080,
[5] = 0x800080,
[6] = 0x008080,
[7] = 0xC0C0C0
},
["bright"] = {
[0] = 0x808080,
[1] = 0xFF0000,
[2] = 0x00FF00,
[3] = 0xFFFF00,
[4] = 0x0000FF,
[5] = 0xFF00FF,
[6] = 0x00FFFF,
[7] = 0xFFFFFF
}
}
defaultForegroundColor = ANSIColorPalette["bright"][7]
defaultBackgroundColor = ANSIColorPalette["dark"][0]
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
local function scrollDown()
local width, height = gpu.getResolution()
if gpu.copy(1,1,width,height,0,-1) then
local prevForeground = gpu.getForeground()
local prevBackground = gpu.getBackground()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1, height, width, 1, " ")
gpu.setForeground(prevForeground)
gpu.setBackground(prevBackground)
_PUBLIC.terminal.cursorPosY=height
end
end
local function newLine()
_PUBLIC.terminal.cursorPosX=1
_PUBLIC.terminal.cursorPosY = _PUBLIC.terminal.cursorPosY + 1
if _PUBLIC.terminal.cursorPosY>height then
scrollDown()
end
end
local function parseCodeNumbers(code)
local o = {}
for num in code:sub(3,-2):gmatch("[^;]+") do
table.insert(o,tonumber(num))
end
return o
end
local function from8BitColor(num)
num=math.floor(num)&255
if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end
if num>=232 then return 0x10101*(8+(num-232)*10) end
num=num-16
local palette = {0,95,135,175,215,255}
return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1]
end
local function from24BitColor(r,g,b)
r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255
return (r<<16)|(g<<8)|b
end
local function findCodeEnd(text,i)
local function inRange(v,min,max)
return v>=min and v<=max
end
i=i+2
while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
return i
end
function _PUBLIC.terminal.write(text, textWrap)
local width, height = gpu.getResolution()
-- you don't know how tiring this was just for ANSI escape code support
if textWrap == nil then
textWrap = true
end
if not text or not tostring(text) then
return
end
if text:find("\a") then
computer.beep()
end
text = tostring(text)
text = "\27[0m" .. text:gsub("\t", " ")
local readBreak = 0
-- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character.
-- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done.
local section = ""
local function printSection()
if #section==0 then
return
end
while true do
gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,section)
if unicode.wlen(section) > width - _PUBLIC.terminal.cursorPosX + 1 and textWrap then
section = section:sub(width - _PUBLIC.terminal.cursorPosX + 2)
newLine()
else
_PUBLIC.terminal.cursorPosX = _PUBLIC.terminal.cursorPosX+unicode.wlen(section)
break
end
end
section = ""
end
for i=1,#text do
if readBreak>0 then
readBreak = readBreak - 1
goto continue
end
if string.byte(text,i)==10 then
printSection()
newLine()
elseif string.byte(text,i)==13 then
printSection()
_PUBLIC.terminal.cursorPosX=1
elseif string.byte(text,i)==0x1b and i<=#text-2 then
printSection()
--ocelot.log("0x1b char detected")
local codeType = string.sub(text,i+1,i+1)
if codeType=="[" then
-- Control Sequence Introducer
--ocelot.log("Control Sequence Introducer")
local codeEndIdx = findCodeEnd(text,i)
-- codeEndIdx = string.find(text,"m",i)
local code = string.sub(text,i,codeEndIdx)
--ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")")
readBreak = readBreak + #code - 1
local nums = parseCodeNumbers(code)
local codeEnd = code:sub(-1)
--ocelot.log("Code end: "..codeEnd..", "..#codeEnd)
if codeEnd == "m" then
-- Select Graphic Rendition
--ocelot.log("Select Graphic Rendition, ID "..nums[1])
if nums[1]>=30 and nums[1]<=37 then
gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==38 and nums[2]==5 then
gpu.setForeground(from8BitColor(nums[3]))
end
if nums[1]==38 and nums[2]==2 then
gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==39 or nums[1]==0 then
gpu.setForeground(defaultForegroundColor)
end
if nums[1]>=40 and nums[1]<=47 then
gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10])
end
if nums[1]==48 and nums[2]==5 then
gpu.setBackground(from8BitColor(nums[3]))
end
if nums[1]==48 and nums[2]==2 then
gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5]))
end
if nums[1]==49 or nums[1]==0 then
gpu.setBackground(defaultBackgroundColor)
end
if nums[1]>=90 and nums[1]<=97 then
gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10])
end
if nums[1]>=100 and nums[1]<=107 then
gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10])
end
end
end
else
--gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,string.sub(text,i,i))
section = section..string.sub(text,i,i)
end
::continue::
end
printSection()
end
function _G.print(...)
local args = {...}
local stringArgs = {}
for _, arg in pairs(args) do
if type(arg)=="table" then
table.insert(stringArgs, serialize.table(arg,true))
elseif tostring(arg) then
table.insert(stringArgs, tostring(arg))
end
end
_PUBLIC.terminal.write(table.concat(stringArgs, " ") .. "\n")
end
function _G._PUBLIC.terminal.clear()
width, height = gpu.getResolution()
gpu.setForeground(defaultForegroundColor)
gpu.setBackground(defaultBackgroundColor)
gpu.fill(1,1,width,height," ")
_PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY = 1, 1
end
function _G._PUBLIC.terminal.read(readHistoryType, prefix, defaultText, maxChars)
checkArg(1, readHistoryType, "string", "nil")
checkArg(2, prefix, "string", "nil")
checkArg(3, defaultText, "string", "nil")
checkArg(4, maxChars, "number", "nil")
maxChars = maxChars or math.huge
local text = defaultText or ""
local historyIdx
if readHistoryType then
if not _PUBLIC.terminal.readHistory[readHistoryType] then
_PUBLIC.terminal.readHistory[readHistoryType] = {text}
elseif _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType] ] ~= "" then
table.insert(_PUBLIC.terminal.readHistory[readHistoryType], text)
end
historyIdx = #_PUBLIC.terminal.readHistory[readHistoryType]
end
local function updateHistory()
if not readHistoryType then return end
_PUBLIC.terminal.readHistory[readHistoryType][historyIdx]=text
end
local cur = unicode.len(text)+1
if prefix then _PUBLIC.terminal.write(prefix) end
local startX, startY = _PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY
local fg, bg = gpu.getForeground(), gpu.getBackground()
local cursorBlink = true
local function get(idx)
idx=startX+idx-1
return gpu.get(idx%width,startY+(idx//width))
end
local function checkScroll(y)
for i=1,y-height do
scrollDown()
startY=startY-1
end
return math.min(y,height)
end
local function set(idx,chr,rev)
if chr==nil or chr=="" then return end
if rev then
gpu.setForeground(bg)
gpu.setBackground(fg)
else
gpu.setForeground(fg)
gpu.setBackground(bg)
end
idx=startX+idx-1
local setX, setY = (idx-1)%width+1, startY+((idx-1)//width+1)-1
setY = checkScroll(setY)
gpu.set(setX,setY,unicode.sub(chr,1,width-setX+1))
for i=1,math.ceil((#chr+setX-1)/width)+1 do
gpu.set(1,setY+i,unicode.sub(chr,2-setX+i*width,width+i*width-setX))
setY = checkScroll(setY)
end
end
local function strDef(a,b)
if #a==0 then return b end
return a
end
local function curPos(cur)
return unicode.wlen(unicode.sub(text,1,cur-1))+1
end
local function add(chr)
if type(chr)~="string" or #chr==0 then return end
if unicode.len(text)>=maxChars then return end
if maxChars<math.huge then
chr=unicode.sub(chr,1,maxChars-unicode.len(text))
end
text=unicode.sub(text,1,cur-1)..chr..unicode.sub(text,cur)
set(curPos(cur),chr,false)
cur=math.min(cur+unicode.len(chr),maxChars+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur+1),unicode.sub(text,cur+1),false)
end
local function moveCur(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=math.max(math.min(cur+dir,unicode.len(text)+1),1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function isLetter(chr)
return not string.find("\x09 :@-./_~?&=%+#",chr,1,true)
end
local function nextCur(dir,chr,icur)
if icur==nil then icur=cur end
local next = math.max(math.min(icur+dir,unicode.len(text)+1),1)
if chr then return unicode.sub(text,next,next) end
return next
end
local function curAfterWord(dir)
local ncur = cur
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==1) do
ncur=nextCur(dir,false,ncur)
end
while nextCur(dir,false,ncur)~=ncur and isLetter(nextCur(dir,true,ncur))==(dir==-1) do
ncur=nextCur(dir,false,ncur)
end
return ncur
end
local function moveWord(dir)
if nextCur(dir)==cur then return end
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
cur=curAfterWord(dir)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
end
local function deleteWord(dir)
local after = curAfterWord(dir)
local lenb = unicode.wlen(text)
if dir==1 then
text=unicode.sub(text,1,cur-1)..unicode.sub(text,after)
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
else
text = unicode.sub(text,1,after-1)..unicode.sub(text,cur)
cur=after
set(curPos(cur+1),unicode.sub(text,cur+1)..string.rep(" ",lenb-unicode.wlen(text)+1),false)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
end
updateHistory()
cursorBlink = true
end
local function isLine(chr)
return chr=="\n" or chr=="\r"
end
--[[ gpu.set(startX,startY,unicode.sub(text,1,width-startX))
for i=1,(#text+startX)//width-1 do
gpu.set(startX,startY+i,unicode.sub(text,1+i*width,width-startX+i*width))
end ]]
set(1,text,false)
set(curPos(cur)," ",true)
local function reprint(new)
set(1,new..string.rep(" ",unicode.wlen(text)-unicode.wlen(new)+1),false)
cur=unicode.len(new)+1
text=new
set(curPos(cur)," ",true)
end
while true do
local args = {event.pull("key_down", "clipboard", 0.5)}
if args and args[1] == "key_down" and args[4] then
local key = _PUBLIC.keyboard.keys[args[4]]
if key=="up" and readHistoryType then
historyIdx=math.max(historyIdx-1,1)
reprint(_PUBLIC.terminal.readHistory[readHistoryType][historyIdx])
elseif key=="down" and readHistoryType then
historyIdx=math.min(historyIdx+1,#_PUBLIC.terminal.readHistory[readHistoryType])
reprint(_PUBLIC.terminal.readHistory[readHistoryType][historyIdx])
elseif key=="left" and _PUBLIC.keyboard.ctrlDown then
moveWord(-1)
elseif key=="right" and _PUBLIC.keyboard.ctrlDown then
moveWord(1)
elseif key=="left" then
moveCur(-1)
elseif key=="right" then
moveCur(1)
elseif key=="home" then
moveCur(-math.huge)
elseif key=="end" then
moveCur(math.huge)
elseif key=="back" and _PUBLIC.keyboard.ctrlDown then
deleteWord(-1)
elseif key=="delete" and _PUBLIC.keyboard.ctrlDown then
deleteWord(1)
elseif key=="back" and cur>1 then
text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur)
cur=cur-1
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
set(curPos(cur)+1,unicode.sub(text,cur+1).." ",false)
updateHistory()
elseif key=="delete" then
text = unicode.sub(text,1,cur-1)..unicode.sub(text,cur+1)
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true)
cursorBlink = true
if cur<=unicode.len(text) then
set(curPos(cur+1),unicode.sub(text,cur+1).." ",false)
end
updateHistory()
elseif key=="enter" then
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false)
break
elseif not (args[3]<32 or (args[3]>0x7F and args[3]<=0x9F)) then
add(unicode.char(args[3]) or " ")
updateHistory()
end
elseif args and args[1]=="clipboard" then
local clip = args[3]
if not args[3] then goto continue end
while isLine(unicode.sub(clip,1,1)) do clip=unicode.sub(clip,2) end
while isLine(unicode.sub(clip,-1)) do clip=unicode.sub(clip,1,-2) end
add(clip)
updateHistory()
else
cursorBlink=not cursorBlink
set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),cursorBlink)
end
::continue::
end
if readHistoryType then
if _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType]]=="" then
table.remove(_PUBLIC.terminal.readHistory[readHistoryType],#_PUBLIC.terminal.readHistory[readHistoryType])
end
if historyIdx<#_PUBLIC.terminal.readHistory[readHistoryType] then
table.remove(_PUBLIC.terminal.readHistory[readHistoryType],historyIdx)
table.insert(_PUBLIC.terminal.readHistory[readHistoryType],text)
end
while #_PUBLIC.terminal.readHistory[readHistoryType] > 50 do
table.remove(_PUBLIC.terminal.readHistory[readHistoryType], 1)
end
end
_PUBLIC.terminal.cursorPosX=1
_PUBLIC.terminal.cursorPosY=_PUBLIC.terminal.cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width)
if _PUBLIC.terminal.cursorPosY>height then scrollDown() end
return text
end
end
function module.exit()
_G._PUBLIC.terminal = nil
end
return module
-149
View File
@@ -1,149 +0,0 @@
_G._PUBLIC.tsched = {}
_G.tsched = {}
_G.tsched.tasks = {}
local currentTask
local component = require("component")
local computer = require("computer")
local filesystem = require("filesystem")
local json = require("json")
local gpu = component.gpu
local ocelot = component.ocelot
function _G._PUBLIC.tsched.runAsTask(path,...)
local args = {...}
local function taskFunction()
local result, errorMessage = xpcall(function(...)
local args = table.pack(...)
if not filesystem.exists(path) then
error("No such file: " .. path)
end
local handle, data, tmpdata = filesystem.open(path), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
-- Userland environment definition
local userland = table.copy(_PUBLIC)
userland._G = userland
assert(load(data, "="..path, "t", userland))(table.unpack(args))
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, path, table.unpack(args))
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
--require(path, table.unpack(args))
end
_PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$"))
end
function _G._PUBLIC.tsched.addTask(func, name)
ocelot.log("Added task " .. name)
local task = coroutine.create(func)
table.insert(tsched.tasks, {["task"] = task, ["name"] = name})
return task
end
function _G._PUBLIC.tsched.removeTask(id)
-- TODO: Check for user permissions before running
table.remove(_G.tsched.tasks, id)
end
function handleError(errormsg)
if errormsg == nil then -- TODO: Replace with proper error handling (if this isn't considered proper..?)
print("\27[91munknown error" .. "\n \n" .. debug.traceback())
else
print("\27[91m" .. tostring(errormsg) .. "\n \n" .. debug.traceback())
end
end
local function runTasks()
for i = 1, #_G.tsched.tasks do
if tsched.tasks[i] then
currentTask = tsched.tasks[i]
local result, errorMessage = coroutine.resume(tsched.tasks[i].task)
if not result then
handleError(errorMessage)
end
if coroutine.status(tsched.tasks[i].task) == "dead" then
_PUBLIC.tsched.removeTask(i)
--ocelot.log("Removed coroutine")
i = i - 1
end
--computer.pullSignal(0)
--coroutine.yield()
end
end
end
function _G._PUBLIC.tsched.getCurrentTask()
return table.copy(currentTask)
end
function _G._PUBLIC.tsched.getTasks()
return table.copy(tsched.tasks)
end
local function taskFunction()
local result, errorMessage = xpcall(function()
if not filesystem.exists("/halyde/kernel/evmgr.lua") then
error("No such file: /halyde/kernel/evmgr.lua")
end
local handle, data, tmpdata = filesystem.open("/halyde/kernel/evmgr.lua"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
assert(load(data, "=/halyde/kernel/evmgr.lua"))()
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, "/halyde/kernel/evmgr.lua")
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
end
_PUBLIC.tsched.addTask(taskFunction, "evmgr")
package.preload("event")
local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
for _, line in ipairs(json.decode(data)) do
if line ~= "" then
--[[ if _G.print then
print(line)
end ]]
_G._PUBLIC.tsched.runAsTask(line)
runTasks()
end
end
-- _G.cormgr.loadCoroutine("/halyde/core/shell.lua")
while true do
runTasks()
if #_G.tsched.tasks == 0 then
computer.beep(1000, 0.5)
while true do
computer.pullSignal()
end
end
end
+1
View File
@@ -0,0 +1 @@
local a;local b;if table.copy then a=table.copy(component)b=table.copy(component)else a={}b=component end;_G.componentlib={["additions"]={},["removals"]={}}a.virtual={}function a.virtual.add(a,b,c)checkArg(1,a,"string")checkArg(2,b,"string")checkArg(3,c,"table")c["address"]=a;componentlib.additions[a]={["componentType"]=b,["proxy"]=c}if componentlib.removals[a]then componentlib.removals[a]=nil end end;function a.virtual.remove(a)checkArg(1,a,"string")if componentlib.additions[a]then componentlib.additions[a]=nil else table.insert(componentlib.removals,a)end end;function a.list(a)checkArg(1,a,"string","nil")local b=table.copy(b.list(a))for c,d in pairs(componentlib.additions)do if d.componentType==a or not a then b[c]=d.componentType end end;for a,a in pairs(componentlib.removals)do b[a]=nil end;local a,c;setmetatable(b,{__call=function(b)a,c=next(b,a)return a,c end})return b end;function a.proxy(a)if componentlib.additions[a]then return componentlib.additions[a].proxy else return b.proxy(a)end end;function a.invoke(a,c,...)if componentlib.additions[a]then return componentlib.additions[a].proxy[c](...)else return b.invoke(a,c,...)end end;function a.get(b)checkArg(1,b,"string")if#b<3 then return nil,"abbreviated address must be at least 3 characters long"end;for a,c in a.list()do if a:find("^"..b)then return(a)end end;return nil,"full address not found"end;setmetatable(a,{["__index"]=function(b,b)if a.list(b)()then return a.proxy(a.list(b)())else return a[b]end end})return a
+1
View File
@@ -0,0 +1 @@
local a=table.copy(computer)local b=table.copy(computer)function a.pullSignal(a)local c=b.uptime()local d;repeat d={b.pullSignal(0)}coroutine.yield()until d or a and b.uptime()>=c+a;return table.unpack(d)end;return a
+1
View File
@@ -0,0 +1 @@
local a=import("computer")local b={}local c=0.1;function b.pull(...)local b={...}local d,e={},nil;for a,a in pairs(b)do if type(a)=="number"and not e then e=a else table.insert(d,tostring(a))end end;local b=a.uptime()while true do for a=1,#evmgr.eventQueue do local e=false;if d[1]then for d,d in pairs(d)do if evmgr.eventQueue[a][2]==d and evmgr.eventQueue[a][1]>=b-c then e=true end end else if evmgr.eventQueue[a][1]>=b-c then e=true end end;if e then local b=table.copy(evmgr.eventQueue[a])table.remove(evmgr.eventQueue,a)table.remove(b,1)return table.unpack(b)end end;if e and a.uptime()>=b+e then return nil end;coroutine.yield()end end;return b
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a={_version="0.1.2"}local b;local c={["\\"]="\\",["\""]="\"",["\b"]="b",["\f"]="f",["\n"]="n",["\r"]="r",["\t"]="t"}local d={["/"]="/"}for a,b in pairs(c)do d[b]=a end;local function e(a)return"\\"..(c[a]or string.format("u%04x",a:byte()))end;local function c(a)return"null"end;local function f(a,c)local d={}c=c or{}if c[a]then error("circular reference")end;c[a]=true;if rawget(a,1)~=nil or next(a)==nil then local e=0;for a in pairs(a)do if type(a)~="number"then error("invalid table: mixed or invalid key types")end;e=e+1 end;if e~=#a then error("invalid table: sparse array")end;for a,a in ipairs(a)do table.insert(d,b(a,c))end;c[a]=nil;return"["..table.concat(d,",").."]"else for a,e in pairs(a)do if type(a)~="string"then error("invalid table: mixed or invalid key types")end;table.insert(d,b(a,c)..":"..b(e,c))end;c[a]=nil;return"{"..table.concat(d,",").."}"end end;local function g(a)return'"'..a:gsub('[%z\1-\31\\"]',e)..'"'end;local function e(a)if a~=a or a<=-math.huge or a>=math.huge then error("unexpected number value '"..tostring(a).."'")end;return string.format("%.14g",a)end;local c={["nil"]=c,["table"]=f,["string"]=g,["number"]=e,["boolean"]=tostring}b=function(a,b)local d=type(a)local c=c[d]if c then return c(a,b)end;error("unexpected type '"..d.."'")end;function a.encode(a)return b(a)end;local b;local function c(...)local a={}for b=1,select("#",...)do a[select(b,...)]=true end;return a end;local e=c(" ","\t","\r","\n")local f=c(" ","\t","\r","\n","]","}",",")local g=c("\\","/",'"',"b","f","n","r","t","u")local c=c("true","false","null")local h={["true"]=true,["false"]=false,["null"]=nil}local function i(a,b,c,d)for b=b,#a do if c[a:sub(b,b)]~=d then return b end end;return#a+1 end;local function j(a,b,c)local d=1;local e=1;for b=1,b-1 do e=e+1;if a:sub(b,b)=="\n"then d=d+1;e=1 end end;error(string.format("%s at line %d col %d",c,d,e))end;local function k(a)local b=math.floor;if a<=127 then return string.char(a)elseif a<=2047 then return string.char(b(a/64)+192,a%64+128)elseif a<=65535 then return string.char(b(a/4096)+224,b(a%4096/64)+128,a%64+128)elseif a<=1114111 then return string.char(b(a/262144)+240,b(a%262144/4096)+128,b(a%4096/64)+128,a%64+128)end;error(string.format("invalid unicode codepoint '%x'",a))end;local function l(a)local b=tonumber(a:sub(1,4),16)local a=tonumber(a:sub(7,10),16)if a then return k((b-55296)*1024+a-56320+65536)else return k(b)end end;local function k(a,b)local c=""local e=b+1;local f=e;while e<=#a do local b=a:byte(e)if b<32 then j(a,e,"control character in string")elseif b==92 then c=c..a:sub(f,e-1)e=e+1;local b=a:sub(e,e)if b=="u"then local a=a:match("^[dD][89aAbB]%x%x\\u%x%x%x%x",e+1)or a:match("^%x%x%x%x",e+1)or j(a,e-1,"invalid unicode escape in string")c=c..l(a)e=e+#a else if not g[b]then j(a,e-1,"invalid escape char '"..b.."' in string")end;c=c..d[b]end;f=e+1 elseif b==34 then c=c..a:sub(f,e-1)return c,e+1 end;e=e+1 end;j(a,b,"expected closing quote for string")end;local function d(a,b)local c=i(a,b,f)local d=a:sub(b,c-1)local e=tonumber(d)if not e then j(a,b,"invalid number '"..d.."'")end;return e,c end;local function g(a,b)local d=i(a,b,f)local e=a:sub(b,d-1)if not c[e]then j(a,b,"invalid literal '"..e.."'")end;return h[e],d end;local function c(a,c)local d={}local f=1;c=c+1;while 1 do local g;c=i(a,c,e,true)if a:sub(c,c)=="]"then c=c+1;break end;g,c=b(a,c)d[f]=g;f=f+1;c=i(a,c,e,true)local b=a:sub(c,c)c=c+1;if b=="]"then break end;if b~=","then j(a,c,"expected ']' or ','")end end;return d,c end;local function f(a,c)local d={}c=c+1;while 1 do local f,g;c=i(a,c,e,true)if a:sub(c,c)=="}"then c=c+1;break end;if a:sub(c,c)~='"'then j(a,c,"expected string for key")end;f,c=b(a,c)c=i(a,c,e,true)if a:sub(c,c)~=":"then j(a,c,"expected ':' after key")end;c=i(a,c+1,e,true)g,c=b(a,c)d[f]=g;c=i(a,c,e,true)local b=a:sub(c,c)c=c+1;if b=="}"then break end;if b~=","then j(a,c,"expected '}' or ','")end end;return d,c end;local c={['"']=k,["0"]=d,["1"]=d,["2"]=d,["3"]=d,["4"]=d,["5"]=d,["6"]=d,["7"]=d,["8"]=d,["9"]=d,["-"]=d,["t"]=g,["f"]=g,["n"]=g,["["]=c,["{"]=f}b=function(a,b)local d=a:sub(b,b)local c=c[d]if c then return c(a,b)end;j(a,b,"unexpected character '"..d.."'")end;function a.decode(a)if type(a)~="string"then error("expected argument of type string, got "..type(a))end;local b,c=b(a,i(a,1,e,true))c=i(a,c,e,true)if c<=#a then j(a,c,"trailing garbage")end;return b end;return a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
local a={}function a.string(a)return'"'..a:gsub("[%z\1-\31\34\92\127-\159]",function(a)local a=a:byte()if a==7 then return"\\a"end;if a==8 then return"\\b"end;if a==9 then return"\\t"end;if a==10 then return"\\n"end;if a==11 then return"\\v"end;if a==12 then return"\\f"end;if a==13 then return"\\r"end;if a==34 then return"\\\""end;if a==92 then return"\\\\"end;return string.format("\\x%02x",a)end)..'"'end;function a.table(b,c,d)d=table.copy(d or{})table.insert(d,b)local e=0;local f=true;local g=""local h=true;for b,i in pairs(b)do if not h then g=g..",\n"end;h=false;g=g.." "if type(b)=="string"then if b:match("^[%a_][%w_]*$")then g=g..b.."="else g=g..'['..a.string(b)..']='end else g=g.."["..tostring(b).."]="end;if type(b)~="number"then f=false end;local a,b=pcall(function()local b=""if type(i)=="table"then if#d>4 or table.find(d,i)then b="..."else b=a.table(i,c,d)end elseif type(i)=="string"then local c={}for a in(i.."\n"):gmatch("([^\n]*)\n")do table.insert(c,a)end;if#c[#c]==0 then c[#c]=nil;c[#c]=c[#c].."\n"end;for b=1,#c do if b<#c then c[b]=a.string(c[b].."\n")else c[b]=a.string(c[b])end end;b=table.concat(c," ..\n ")else b=tostring(i)end;local a={}for b in(b.."\n"):gmatch("([^\n]*)\n")do table.insert(a,b)end;g=g..table.concat(a,"\n ")a=nil;e=e+1 end)if not a then if c then g=g.."\x1b[91m"end;g=g.."["..tostring(b).."]"if c then g=g.."\x1b[39m"end end;coroutine.yield()end;local h=getmetatable(b)local i={}if type(h)=="table"then for a,b in pairs(h)do f=false;table.insert(i,a)end end;if#i>0 then g=g.."\n "if c then g=g.."\x1b[92m"end;if table.find(i,"__tostring")then g=g.."tostring: "..a.string(tostring(b)).."\n "table.remove(i,table.find(i,"__tostring"))end;g=g..table.concat(i,", ")if c then g=g.."\x1b[39m"end end;if e==0 then return"{}"end;if f then local e={}for b,b in pairs(b)do if#e>=5 and#d>1 then table.insert(e,"...")break end;if type(b)=="table"then table.insert(e,a.table(b,c,d))elseif type(b)=="string"then table.insert(e,a.string(b))else table.insert(e,tostring(b))end end;return"{"..table.concat(e,", ").."}"end;return"{\n"..g.."\n}"end;return a
+1
View File
@@ -0,0 +1 @@
local a;local b;if table.copy then a=table.copy(unicode)b=table.copy(unicode)else a={}b=unicode end;function a.readCodePoint(a)checkArg(1,a,"function")local function b(a,b,...)for c,c in ipairs({...})do if not(c and c>=a and c<b)then return false end end;return true end;local c=a()if c==nil then return end;if c<128 then return c elseif c<192 then return nil elseif c<224 then local a=a()if a==nil then return nil end;if b(128,192,a)then local a=((c&31)<<6)|(a&63)return a end elseif c<240 then local a,d=a(),a()if a==nil and d==nil then return nil end;if b(128,192,a,d)then local a=((c&15)<<12)|((a&63)<<6)|(d&63)return a end elseif c<248 then local a,d,e=a(),a(),a()if a==nil and d==nil and e==nil then return nil end;if b(128,192,a,d,e)then local a=((c&7)<<18)|((a&63)<<12)|((d&63)<<6)|(e&63)return a end end;return nil end;function a.readChar(c)checkArg(1,c,"function")return b.char(a.readCodePoint(c))end;function a.codepoint(a)checkArg(1,a,"string")local b=1;return unicode.readCodePoint(function()local a=a:byte(b)b=b+1;return a end),b-1 end;function a.iterate(c)checkArg(1,c,"string","function")if type(c)=="string"then local a,b=c,0;c=function()b=b+1;return a:byte(b)end end;return function()local a=a.readCodePoint(c)if a==nil then return nil end;return b.char(a),a end end;a.char=b.char;a.charWidth=b.charWidth;a.isWide=b.isWide;a.len=b.len;a.lower=b.lower;a.reverse=b.reverse;a.sub=b.sub;a.upper=b.upper;a.wlen=b.wlen;a.wtrunc=b.wtrunc;return a
-104
View File
@@ -1,104 +0,0 @@
local fs = require("filesystem")
local json = require("json")
local handle, data, tmpdata = fs.open("/halyde/config/shell.json", "r"), "", nil
repeat
tmpdata = handle:read(math.huge)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
local shellcfg = json.decode(data)
local component = require("component")
local gpu = component.gpu
_G.shell = {}
_G.shell.workingDirectory = shellcfg["defaultWorkingDirectory"]
_G.shell.aliases = shellcfg["aliases"]
local function runAsTask(path, ...)
--ocelot.log("running " .. path .. " as coroutine")
tsched.runAsTask(path, ...)
local corIndex = #tsched.getTasks()
local task = tsched.getTasks()[#tsched.getTasks()]
repeat
coroutine.yield()
until tsched.getTasks()[corIndex] ~= task
end
function _G.shell.run(command)
checkArg(1, command, "string")
if shell.aliases[command:match("[^ ]+")] then
local _, cmdend = command:find("[^ ]+")
command = shell.aliases[command:match("[^ ]+")] .. command:sub(cmdend + 1)
end
local gm, result, args, trimmedCommand = command:gmatch("[^ ]+"), nil, {}, command
while true do
result = gm()
if not result then
break
end
if result:find('"') then
local location = trimmedCommand:find('"')
local argBefore = result:sub(1, result:find('"') - 1) -- edge case where there is no space before the quote, get the argument there
if argBefore and argBefore ~= "" then
table.insert(args, argBefore)
end
trimmedCommand = trimmedCommand:sub(location + 1)
if trimmedCommand:find('"') then
table.insert(args, trimmedCommand:sub(1, trimmedCommand:find('"') - 1))
trimmedCommand = trimmedCommand:sub(trimmedCommand:find('"') + 1)
gm = trimmedCommand:gmatch('[^ ]+')
else
print("\27[91mmalformed shell command")
return
end
else
table.insert(args, result)
end
end
-- execute the program
local PATH = table.copy(shellcfg.path)
table.insert(PATH, shell.workingDirectory)
if not args[1] then
return
end
if fs.exists(args[1]) and not fs.isDirectory(args[1]) then
local path = args[1]
table.remove(args, 1)
runAsTask(path, table.unpack(args))
return
end
for _, item in pairs(PATH) do
if fs.exists(item..args[1]) and not fs.isDirectory(item .. args[1]) then
local path = fs.concat(item, args[1])
table.remove(args, 1)
runAsTask(path, table.unpack(args))
return
else -- try to look for it without the file extension
local files = fs.list(item) or {}
for _, file in pairs(files) do
-- previous pattern: (.+)%.[^%.]+$
if args[1] == file:match("(.+)%.[^%.]+$") and not fs.isDirectory(item .. file) then
table.remove(args, 1)
runAsTask(item .. file, table.unpack(args))
return
end
end
end
end
print("No such file or command: "..args[1])
end
print(shellcfg["startupMessage"]:format(_OSVERSION, shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)]))
while true do
coroutine.yield()
-- print(shell.workingDirectory .. " >")
--print(shellcfg["prompt"]:format(shell.workingDirectory),false)
-- termlib.cursorPosX = #(shell.workingDirectory .. " > ")
-- termlib.cursorPosY = termlib.cursorPosY - 1
if shell.workingDirectory:sub(-1, -1) ~= "/" then
shell.workingDirectory = shell.workingDirectory .. "/"
end
local shellCommand = terminal.read("shell", shellcfg.prompt:format(shell.workingDirectory))
shell.run(shellCommand)
gpu.freeAllBuffers()
end
-4
View File
@@ -1,4 +0,0 @@
[00:00:04:12] Debug!
[00:00:04:19] Info!
[00:00:04:25] Warning!
[00:00:04:32] Error!
-7
View File
@@ -1,7 +0,0 @@
local cor = coroutine.create(function()
print("Hello World!")
end)
print(coroutine.status(cor))
coroutine.resume(cor)
print(coroutine.status(cor))
+1 -72
View File
@@ -1,72 +1 @@
local gpu = component.proxy(component.list("gpu")()) local a=component.proxy(component.list("gpu")())local b,c=a.getResolution()local function d(a)checkArg(1,a,"string")local b=component.invoke(computer.getBootAddress(),"open",a,"r")local c=""repeat local a=component.invoke(computer.getBootAddress(),"read",b,math.huge or math.maxinteger)c=c..(a or"")until not a;component.invoke(computer.getBootAddress(),"close",b)return assert(load(c,"="..a))end;local function e(a)return(a.."\n \n"..debug.traceback())end;function loadthething()d("/halyde/core/boot.lua")(d)end;a.setBackground(0)a.fill(1,1,b,c," ")local d,e=xpcall(loadthething,e)if not d then if import then local a=import("computer")end;a.setBackground(0)a.fill(1,1,b,c," ")a.setBackground(8388608)a.setForeground(16777215)a.set(2,2,"A critical error has occurred.")local b=4;e=e:gsub("\t"," ")for c in string.gmatch((e~=nil and tostring(e))or"unknown error","([^\n]*)\n?")do a.set(2,b,c)b=b+1 end;if computer~=nil then a.set(2,b+1,"Press any key to restart.")local a;repeat a=computer.pullSignal()until a=="key_down"computer.shutdown(true)end;while true do coroutine.yield()end end
local resX, resY = gpu.getResolution()
-- Architecture check
local foundArchitecture = false
for _, arch in pairs(computer.getArchitectures()) do
if arch == "Lua 5.3" then
foundArchitecture = true
break
end
end
if foundArchitecture then
computer.setArchitecture("Lua 5.3")
else
gpu.set(1, 1, "Required architecture (Lua 5.3) is not supported.")
gpu.set(1, 2, "Halting.")
while true do
computer.pullSignal()
end
end
local function loadfile(file)
checkArg(1, file, "string")
local handle = component.invoke(computer.getBootAddress(), "open", file, "r")
local data = ""
repeat
local tmpdata = component.invoke(computer.getBootAddress(), "read", handle, math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
component.invoke(computer.getBootAddress(), "close", handle)
return assert(load(data, "=" .. file))
end
local function handleError(errorMessage)
return(errorMessage.."\n \n"..debug.traceback())
end
function loadBoot()
loadfile("/halyde/kernel/boot.lua")(loadfile)
end
gpu.setBackground(0x000000)
gpu.fill(1, 1, resX, resY, " ")
-- Copying low-level functions in case of post-preload failure
local pullSignal = computer.pullSignal
local shutdown = computer.shutdown
local result, reason = xpcall(loadBoot, handleError)
if not result then
gpu.setBackground(0x000000)
gpu.fill(1, 1, resX, resY, " ")
gpu.setBackground(0x800000)
gpu.setForeground(0xFFFFFF)
gpu.set(2,2,"A critical error has occurred.")
local i = 4
reason = tostring(reason):gsub("\t", " ")
for line in string.gmatch(reason or "unknown error", "([^\n]*)\n?") do
gpu.set(2,i,line)
i = i + 1
end
gpu.set(2,i+1, "Press any key to restart.")
local evname
repeat
evname = pullSignal()
until evname == "key_down"
shutdown(true)
while true do
coroutine.yield()
end
end
-97
View File
@@ -1,97 +0,0 @@
local compLib
local LLcomponent
if table.copy then
compLib = table.copy(component)
LLcomponent = table.copy(component)
else
compLib = {}
LLcomponent = component
end
--local ocelot = LLcomponent.proxy(LLcomponent.list("ocelot")())
--ocelot.log("loaded")
_G.componentlib = {["additions"] = {}, ["removals"] = {}}
compLib.virtual = {}
function compLib.virtual.add(address, componentType, proxy)
checkArg(1, address, "string")
checkArg(2, componentType, "string")
checkArg(3, proxy, "table")
proxy["address"] = address
componentlib.additions[address] = {["componentType"] = componentType, ["proxy"] = proxy}
if componentlib.removals[address] then
componentlib.removals[address] = nil
end
end
function compLib.virtual.remove(address)
checkArg(1, address, "string")
if componentlib.additions[address] then
componentlib.additions[address] = nil
else
table.insert(componentlib.removals, address)
end
end
function compLib.list(componentType)
checkArg(1, componentType, "string", "nil")
local componentList = table.copy(LLcomponent.list(componentType))
for address, dataTable in pairs(componentlib.additions) do
if dataTable.componentType == componentType or not componentType then
componentList[address] = dataTable.componentType
end
end
for _, address in pairs(componentlib.removals) do
componentList[address] = nil
end
local i, value
setmetatable(componentList, {__call = function(self)
i, value = next(self, i)
return i, value
end})
return componentList
end
function compLib.proxy(address)
if componentlib.additions[address] then
--ocelot.log("vcomponent")
return componentlib.additions[address].proxy
else
return LLcomponent.proxy(address)
end
end
function compLib.invoke(address, funcName, ...)
--ocelot.log("Invoking " .. funcName .. " from " .. address)
if componentlib.additions[address] then
--ocelot.log("vcomponent")
return componentlib.additions[address].proxy[funcName](...)
else
return LLcomponent.invoke(address, funcName, ...)
end
end
function compLib.get(address)
checkArg(1, address, "string")
if #address < 3 then
return nil, "abbreviated address must be at least 3 characters long"
end
for currentAddress, name in compLib.list() do
if currentAddress:find("^" .. address) then
return(currentAddress)
end
end
return nil, "full address not found"
end
-- Add main component proxies to the library
setmetatable(compLib, {["__index"] = function(_, item)
if compLib.list(item)() then
return compLib.proxy(compLib.list(item)())
else
return compLib[item]
end
end})
return compLib
-14
View File
@@ -1,14 +0,0 @@
local computerlib = table.copy(computer)
local LLcomputer = table.copy(computer)
function computerlib.pullSignal(timeout)
local startTime = LLcomputer.uptime()
local result
repeat
result = {LLcomputer.pullSignal(0)}
coroutine.yield()
until result or timeout and LLcomputer.uptime() >= startTime + timeout
return table.unpack(result)
end
return computerlib
-55
View File
@@ -1,55 +0,0 @@
local computer = require("computer")
local event = {}
local bufferTime = 0.1 -- A little bit of buffer time so events won't be skipped by accident.
--local ocelot = component.proxy(component.list("ocelot")())
function event.pull(...)
local args = {...}
local evtypes, timeout = {}, nil
for _, arg in pairs(args) do
if type(arg) == "number" and not timeout then -- It's a timeout
timeout = arg
else -- It's an event type
table.insert(evtypes, tostring(arg))
end
end
local startTime = computer.uptime()
while true do
-- Check event queue for matching event
for i = 1, #evmgr.eventQueue do
local foundevent = false
if evtypes[1] then -- event type(s) specified
for _, evtype in pairs(evtypes) do
if evmgr.eventQueue[i][2] == evtype and evmgr.eventQueue[i][1] >= startTime - bufferTime then
foundevent = true
end
end
else
if evmgr.eventQueue[i][1] >= startTime - bufferTime then
foundevent = true
end
end
if foundevent then
-- Found matching event (or any event if no type specified)
local result = table.copy(evmgr.eventQueue[i])
table.remove(evmgr.eventQueue, i)
table.remove(result, 1) -- remove the time of event argument
return table.unpack(result)
end
end
-- Check if we've timed out
if timeout and computer.uptime() >= startTime + timeout then
return nil -- Timed out, return nil
end
-- Yield to allow other processes to run and more events to be added
coroutine.yield()
end
end
return event
-506
View File
@@ -1,506 +0,0 @@
local loadfile = ... -- raw loadfile from boot.lua
local unicode, component, computer
if loadfile then
unicode = loadfile("/lib/unicode.lua")(loadfile)
component = loadfile("/lib/component.lua")(loadfile)
computer = _G.computer
elseif require then
unicode = require("unicode")
component = require("component")
computer = require("computer")
end
local filesystem = {}
function filesystem.canonical(path)
checkArg(1, path, "string")
local segList = {}
if path:sub(1, 1) ~= "/" then
path = "/" .. path
end
path = path:gsub("/+", "/")
for segment in path:gmatch("[^/]+") do
if segment == ".." and segList[1] then
table.remove(segList, #segList)
elseif segment ~= "." then
table.insert(segList, segment)
end
end
return "/" .. table.concat(segList, "/")
end
function filesystem.concat(path1, path2)
checkArg(1, path1, "string")
checkArg(2, path2, "string")
if path1:sub(-1, -1) == "/" then
path1 = path1:sub(1, -2)
end
if path2:sub(1, 1) ~= "/" then
path2 = "/" .. path2
end
return path1 .. path2
end
function filesystem.absolutePath(path) -- returns the address and absolute path of an object
checkArg(1, path, "string")
path = filesystem.canonical(path)
local address = nil
if path:find("^/tmp") then
address = computer.tmpAddress()
path = path:sub(5)
elseif path:find("^/mnt/...") then
address = component.get(path:sub(6,8))
if not address then
address = computer.getBootAddress()
else
path = path:sub(9)
end
else
address = computer.getBootAddress()
end
if not address then
return nil, "no such component"
end
return address, path
end
function filesystem.exists(path) -- check if path exists
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
if absPath:find("^/special/drive/...") then
return not not (computer.getBootAddress() and component.get(absPath:sub(16,18)))
end
if absPath:find("^/special/eeprom/") then
return table.find({"init.lua","data.bin","label.txt"},absPath:sub(17))
end
return component.invoke(address, "exists", absPath)
end
local function readBytes(self,n)
n = n or 1
if n==1 then
local byte = self:read(1)
if byte==nil then return nil end
return string.byte(byte)
end
local bytes, res = {string.byte(self:read(n),1,n)}, 0
if self.littleEndian then
for i=#bytes,1,-1 do
res = (res<<8)&0xFFFFFFFF | bytes[i]
end
else
for i=1,#bytes do
res = (res<<8)&0xFFFFFFFF | bytes[i]
end
end
return res
end
local function readUnicodeChar(self)
return unicode.readChar(function()
return self:readBytes(1)
end)
end
local function iterateBytes(self)
return function()
local byte = readBytes(self,1)
if byte==nil then self:close() end
return byte
end
end
local function iterateUnicodeChars(self)
return unicode.iterate(iterateBytes(self))
end
function filesystem.makeReadStream(content)
local properHandle = {}
local readcursor = 1
function properHandle.read(self, amount)
checkArg(2, amount, "number")
local limit = string.len(content)+1
local out = nil
if readcursor<limit then
if amount==math.huge then
out = string.sub(content,math.min(readcursor,limit))
else
out = string.sub(content,math.min(readcursor,limit),math.min(readcursor+amount-1,limit))
end
end
readcursor=readcursor+amount
if out=="" then
return nil
end
return out
end
properHandle.readBytes = readBytes
properHandle.readUnicodeChar = readUnicodeChar
properHandle.iterateBytes = iterateBytes
properHandle.iterateUnicodeChars = iterateUnicodeChars
function properHandle.write()
return nil
end
function properHandle.close()
content=nil
end
return properHandle
end
function filesystem.open(path, mode, buffered) -- opens a file and returns its handle
checkArg(1, path, "string")
checkArg(2, mode, "string", "nil")
checkArg(3, buffered, "boolean", "nil")
if not mode then
mode = "r"
end
if buffered == nil then
buffered = true
end
if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb" or mode == "a" or mode == "ab") then
return nil, "invalid handle type"
end
if path:find("^/special") and not filesystem.exists(path) then
return nil, "/special does not allow creating files"
end
local address, absPath = filesystem.absolutePath(path)
local unmanagedDrive = address==computer.getBootAddress() and absPath:find("^/special/drive")
local unmanagedProxy, sectorSize, sectorCount, handle
if unmanagedDrive then
unmanagedProxy = component.proxy(component.get(absPath:sub(16,18)))
sectorSize = unmanagedProxy.getSectorSize()
sectorCount = math.ceil(unmanagedProxy.getCapacity()/sectorSize)
elseif not (address==computer.getBootAddress() and absPath:find("^/special/")) then
local handleArgs = {component.invoke(address, "open", absPath, mode)}
handle = handleArgs[1]
if not handle then
return table.unpack(handleArgs)
end
handleArgs = nil
end
local properHandle = {}
properHandle.handle = handle
properHandle.address = address
local content = nil
local readcursor = 1
if buffered and mode:sub(1,1)=="r" then
content=""
repeat
tmpdata = component.invoke(address, "read", handle, math.huge or math.maxinteger)
content = content .. (tmpdata or "")
until not tmpdata
component.invoke(address, "close", handle)
end
function properHandle.read(self, amount)
checkArg(2, amount, "number")
if unmanagedDrive then
local sectorIdx = ((readcursor-1)//sectorSize)+1
if sectorIdx>sectorCount then return nil end
local sector = unmanagedProxy.readSector(sectorIdx)
local data = sector:sub(((readcursor-1)%sectorSize)+1,((readcursor+math.min(amount,sectorSize)-2)%sectorSize)+1)
readcursor=readcursor+#data
if data=="" then return nil end
return data
else
if buffered then
local limit = string.len(content)+1
local out = nil
if readcursor<limit then
if amount==math.huge then
out = string.sub(content,math.min(readcursor,limit))
else
out = string.sub(content,math.min(readcursor,limit),math.min(readcursor+amount-1,limit))
end
end
readcursor=readcursor+amount
if out=="" then
return nil
end
return out
else
return component.invoke(self.address, "read", self.handle, amount)
end
end
end
properHandle.readBytes = readBytes
properHandle.readUnicodeChar = readUnicodeChar
properHandle.iterateBytes = iterateBytes
properHandle.iterateUnicodeChars = iterateUnicodeChars
function properHandle.write(self, data)
checkArg(2, data, "string")
if unmanagedDrive then
local startSector = ((readcursor-1)//sectorSize)+1
if startSector>sectorCount then return nil, "not enough space" end
local startSByte = ((readcursor-1)%sectorSize)+1
local sect = unmanagedProxy.readSector(startSector)
unmanagedProxy.writeSector(startSector,sect:sub(1,startSByte-1)..data:sub(1,sectorSize-startSByte+1))
for i=2,(#data+startSByte)//sectorSize do
if startSector+i-1>sectorCount then return nil, "not enough space" end
unmanagedProxy.writeSector(startSector+i-1,data:sub(startSByte+sectorSize*(i-1),startSByte+sectorSize*i-1))
end
readcursor=readcursor+#data
return true
else
return component.invoke(self.address, "write", self.handle, data)
end
end
function properHandle.close(self)
if buffered then
content = nil
else
return component.invoke(self.address, "close", self.handle)
end
end
if address==computer.getBootAddress() then
local eeprom
pcall(function()
eeprom = component.eeprom
end)
if eeprom then
local getFunc, setFunc
if absPath=="/special/eeprom/init.lua" then
getFunc,setFunc = "get","set"
elseif absPath=="/special/eeprom/data.bin" then
getFunc,setFunc = "getData","setData"
elseif absPath=="/special/eeprom/label.txt" then
getFunc,setFunc = "getLabel","setLabel"
end
if mode:sub(1,1)=="r" and getFunc then
local stream = filesystem.makeReadStream(eeprom[getFunc]() or "")
properHandle.read = stream.read
properHandle.close = stream.close
elseif mode:sub(1,1)=="w" and setFunc then
local content = ""
function properHandle.write(self, data)
checkArg(2, data, "string")
content=content..data
end
function properHandle.close(self)
return eeprom[setFunc](content)
end
end
end
end
return properHandle
end
function filesystem.list(path)
checkArg(1, path, "string")
path = filesystem.canonical(path)
if path == "/mnt" then
-- list drives
local returnTable = {}
local tmpAddress = computer.tmpAddress()
for address, _ in component.list("filesystem") do
if address~=tmpAddress then
table.insert(returnTable, address:sub(1, 3) .. "/")
end
end
return returnTable
elseif path == "/special/drive" then
local returnTable = {}
local tmpAddress = computer.tmpAddress()
for address, type in component.list("drive") do
if address~=tmpAddress and type=="drive" then
table.insert(returnTable, address:sub(1, 3))
end
end
return returnTable
elseif path=="/special/eeprom" then
return {"init.lua","data.bin","label.txt"}
else
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
return component.invoke(address, "list", absPath)
end
end
function filesystem.size(path)
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
if address==computer.getBootAddress() then
if absPath:find("^/special/drive") then
local drive = component.get(absPath:sub(16,18))
if not drive then return false end
return component.invoke(drive,"getCapacity")
elseif absPath:find("^/special/eeprom") then
local eeprom
pcall(function()
eeprom = component.eeprom
end)
if eeprom then
local getFunc
if absPath=="/special/eeprom/init.lua" then
getFunc = "get"
elseif absPath=="/special/eeprom/data.bin" then
getFunc = "getData"
elseif absPath=="/special/eeprom/label.txt" then
getFunc = "getLabel"
end
return #(eeprom[getFunc]())
end
end
end
return component.invoke(address, "size", absPath)
end
local function getRecursiveList(address,absPath)
local list = component.invoke(address,"list",absPath)
local dirList = {}
local listChanged = true
while listChanged do
listChanged = false
for i=1,#list do
if component.invoke(address, "isDirectory", absPath.."/"..list[i]) then
listChanged = true
local dir = list[i]
if dir:sub(-1)=="/" then dir=dir:sub(1,-2) end
table.insert(dirList,dir)
table.remove(list,i)
local subDir = component.invoke(address,"list",absPath.."/"..dir)
for j=1,#subDir do table.insert(list,dir.."/"..subDir[j]) end
end
end
end
return list,dirList
end
local function copyContent(fromHandle,toHandle)
if not (fromHandle and toHandle) then return end
local memory = math.floor(computer.freeMemory()*0.8)
local tmpdata
while true do
tmpdata = fromHandle:read(memory)
if not tmpdata then break end
local status,reason = toHandle:write(tmpdata)
if status~=true then break end
end
fromHandle:close()
toHandle:close()
end
local function copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
-- TODO: make this use copyContent
if fromAbsPath:sub(-1)=="/" then fromAbsPath=fromAbsPath:sub(1,-2) end
if toAbsPath:sub(-1)=="/" then toAbsPath=toAbsPath:sub(1,-2) end
component.invoke(toAddress,"makeDirectory",toAbsPath)
local fileList,dirList = getRecursiveList(fromAddress,fromAbsPath)
for i=1,#dirList do
component.invoke(toAddress,"makeDirectory",toAbsPath.."/"..dirList[i])
end
for i=1,#fileList do
local fromFile, toFile = fromAbsPath.."/"..fileList[i], toAbsPath.."/"..fileList[i]
--[[ local handle = component.invoke(fromAddress, "open", fromFile, "r")
local data, tmpdata = "", nil
repeat
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = component.invoke(fromAddress, "close", handle)
local handle = component.invoke(toAddress, "open", toFile, "w")
component.invoke(toAddress, "write", handle, data)
component.invoke(toAddress, "close", handle) ]]
local fromHandle = component.invoke(fromAddress, "open", fromFile, "r")
local toHandle = component.invoke(toAddress, "open", toFile, "w")
copyContent({
["read"]=function(...) return component.invoke(fromAddress, "read", handle, ...) end,
["close"]=function(...) return component.invoke(fromAddress, "close", handle, ...) end
},{
["write"]=function(...) return component.invoke(fromAddress, "write", handle, ...) end,
["close"]=function(...) return component.invoke(fromAddress, "close", handle, ...) end
})
end
end
function filesystem.isDirectory(path)
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
return component.invoke(address, "isDirectory", absPath)
end
function filesystem.rename(fromPath, toPath)
checkArg(1, fromPath, "string")
checkArg(2, toPath, "string")
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
if not fromAddress or not toAddress then
return false
end
if fromAddress == toAddress then
return component.invoke(fromAddress, "rename", fromAbsPath, toAbsPath)
elseif filesystem.isDirectory(fromPath) then -- component.invoke(fromAddress, "isDirectory", fromAbsPath) then
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
filesystem.remove(fromPath) -- component.invoke(fromAddress,"remove", fromAbsPath)
else
local handle, data, tmpdata = filesystem.open(fromPath), "", nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger) -- component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = handle:close() -- component.invoke(fromAddress, "close", handle)
local handle = filesystem.open(toPath) -- component.invoke(toAddress, "open", toAbsPath, "w")
handle:write(data) -- component.invoke(toAddress, "write", handle, data)
handle:close() -- component.invoke(toAddress, "close", handle)
filesystem.remove(fromPath) -- component.invoke(fromAddress, "remove", fromAbsPath)
end
end
function filesystem.copy(fromPath, toPath)
checkArg(1, fromPath, "string")
checkArg(2, toPath, "string")
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
if not fromAddress or not toAddress then
return false
end
if filesystem.isDirectory(fromPath) then -- component.invoke(fromAddress, "isDirectory", fromAbsPath)
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
else
--[[ local handle = filesystem.open(fromPath,"r")
local data, tmpdata = "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
tmpdata = handle:close()
local handle = filesystem.open(toPath,"w")
handle:write(data)
handle:close() ]]
copyContent(filesystem.open(fromPath,"r"),filesystem.open(toPath,"w"))
end
end
function filesystem.remove(path)
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
if absPath:find("^/special") then return false end
if absPath:find("^/tmp") then return false end
if absPath:find("^/mnt") then return false end
return component.invoke(address, "remove", absPath)
end
function filesystem.makeDirectory(path)
checkArg(1, path, "string")
local address, absPath = filesystem.absolutePath(path)
if not address then
return false
end
return component.invoke(address, "makeDirectory", absPath)
end
return(filesystem)
-4
View File
@@ -1,4 +0,0 @@
-- json.lua by rxi
-- Minified with luamin
-- Original: https://github.com/rxi/json.lua
local a={_version="0.1.2"}local b;local c={["\\"]="\\",["\""]="\"",["\b"]="b",["\f"]="f",["\n"]="n",["\r"]="r",["\t"]="t"}local d={["/"]="/"}for e,f in pairs(c)do d[f]=e end;local function g(h)return"\\"..(c[h]or string.format("u%04x",h:byte()))end;local function i(j)return"null"end;local function k(j,l)local m={}l=l or{}if l[j]then error("circular reference")end;l[j]=true;if rawget(j,1)~=nil or next(j)==nil then local n=0;for e in pairs(j)do if type(e)~="number"then error("invalid table: mixed or invalid key types")end;n=n+1 end;if n~=#j then error("invalid table: sparse array")end;for o,f in ipairs(j)do table.insert(m,b(f,l))end;l[j]=nil;return"["..table.concat(m,",").."]"else for e,f in pairs(j)do if type(e)~="string"then error("invalid table: mixed or invalid key types")end;table.insert(m,b(e,l)..":"..b(f,l))end;l[j]=nil;return"{"..table.concat(m,",").."}"end end;local function p(j)return'"'..j:gsub('[%z\1-\31\\"]',g)..'"'end;local function q(j)if j~=j or j<=-math.huge or j>=math.huge then error("unexpected number value '"..tostring(j).."'")end;return string.format("%.14g",j)end;local r={["nil"]=i,["table"]=k,["string"]=p,["number"]=q,["boolean"]=tostring}b=function(j,l)local s=type(j)local t=r[s]if t then return t(j,l)end;error("unexpected type '"..s.."'")end;function a.encode(j)return b(j)end;local u;local function v(...)local m={}for o=1,select("#",...)do m[select(o,...)]=true end;return m end;local w=v(" ","\t","\r","\n")local x=v(" ","\t","\r","\n","]","}",",")local y=v("\\","/",'"',"b","f","n","r","t","u")local z=v("true","false","null")local A={["true"]=true,["false"]=false,["null"]=nil}local function B(C,D,E,F)for o=D,#C do if E[C:sub(o,o)]~=F then return o end end;return#C+1 end;local function G(C,D,H)local I=1;local J=1;for o=1,D-1 do J=J+1;if C:sub(o,o)=="\n"then I=I+1;J=1 end end;error(string.format("%s at line %d col %d",H,I,J))end;local function K(n)local t=math.floor;if n<=0x7f then return string.char(n)elseif n<=0x7ff then return string.char(t(n/64)+192,n%64+128)elseif n<=0xffff then return string.char(t(n/4096)+224,t(n%4096/64)+128,n%64+128)elseif n<=0x10ffff then return string.char(t(n/262144)+240,t(n%262144/4096)+128,t(n%4096/64)+128,n%64+128)end;error(string.format("invalid unicode codepoint '%x'",n))end;local function L(M)local N=tonumber(M:sub(1,4),16)local O=tonumber(M:sub(7,10),16)if O then return K((N-0xd800)*0x400+O-0xdc00+0x10000)else return K(N)end end;local function P(C,o)local m=""local Q=o+1;local e=Q;while Q<=#C do local R=C:byte(Q)if R<32 then G(C,Q,"control character in string")elseif R==92 then m=m..C:sub(e,Q-1)Q=Q+1;local h=C:sub(Q,Q)if h=="u"then local S=C:match("^[dD][89aAbB]%x%x\\u%x%x%x%x",Q+1)or C:match("^%x%x%x%x",Q+1)or G(C,Q-1,"invalid unicode escape in string")m=m..L(S)Q=Q+#S else if not y[h]then G(C,Q-1,"invalid escape char '"..h.."' in string")end;m=m..d[h]end;e=Q+1 elseif R==34 then m=m..C:sub(e,Q-1)return m,Q+1 end;Q=Q+1 end;G(C,o,"expected closing quote for string")end;local function T(C,o)local R=B(C,o,x)local M=C:sub(o,R-1)local n=tonumber(M)if not n then G(C,o,"invalid number '"..M.."'")end;return n,R end;local function U(C,o)local R=B(C,o,x)local V=C:sub(o,R-1)if not z[V]then G(C,o,"invalid literal '"..V.."'")end;return A[V],R end;local function W(C,o)local m={}local n=1;o=o+1;while 1 do local R;o=B(C,o,w,true)if C:sub(o,o)=="]"then o=o+1;break end;R,o=u(C,o)m[n]=R;n=n+1;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="]"then break end;if X~=","then G(C,o,"expected ']' or ','")end end;return m,o end;local function Y(C,o)local m={}o=o+1;while 1 do local Z,j;o=B(C,o,w,true)if C:sub(o,o)=="}"then o=o+1;break end;if C:sub(o,o)~='"'then G(C,o,"expected string for key")end;Z,o=u(C,o)o=B(C,o,w,true)if C:sub(o,o)~=":"then G(C,o,"expected ':' after key")end;o=B(C,o+1,w,true)j,o=u(C,o)m[Z]=j;o=B(C,o,w,true)local X=C:sub(o,o)o=o+1;if X=="}"then break end;if X~=","then G(C,o,"expected '}' or ','")end end;return m,o end;local _={['"']=P,["0"]=T,["1"]=T,["2"]=T,["3"]=T,["4"]=T,["5"]=T,["6"]=T,["7"]=T,["8"]=T,["9"]=T,["-"]=T,["t"]=U,["f"]=U,["n"]=U,["["]=W,["{"]=Y}u=function(C,D)local X=C:sub(D,D)local t=_[X]if t then return t(C,D)end;G(C,D,"unexpected character '"..X.."'")end;function a.decode(C)if type(C)~="string"then error("expected argument of type string, got "..type(C))end;local m,D=u(C,B(C,1,w,true))D=B(C,D,w,true)if D<=#C then G(C,D,"trailing garbage")end;return m end;return a
-30
View File
@@ -1,30 +0,0 @@
local fs = require("filesystem")
local computer = require("computer")
local log = {}
function log.add(text, logType)
checkArg(1, text, "string")
checkArg(2, logType, "string", "nil")
if logType ~= "debug" and logType ~= "info" and logType ~= "warning" and logType ~= "error" and logType then
error("Log type must either be debug, info, warning or error.")
end
if not logType then
logType = "debug"
end
local handle = fs.open("/halyde/system.log", "a")
local time = computer.uptime()
local logText = string.format("[%02d:%02d:%02d:%02d] " .. text, math.floor(time / 86400), math.floor(time / 3600 % 24), math.floor(time / 60 % 60), math.floor(time % 60)) .. "\n"
if logType == "debug" then
handle:write("\27[37m" .. logText)
elseif logType == "info" then
handle:write("\27[97m" .. logText)
elseif logType == "warning" then
handle:write("\27[93m" .. logText)
else
handle:write("\27[91m" .. logText)
end
handle:close()
end
return log
-432
View File
@@ -1,432 +0,0 @@
local raster = {
["units"]={},
["defaultBackgroundColor"]=0x000000,
["defaultForegroundColor"]=0xFFFFFF,
["displayWidth"]=0,
["displayHeight"]=0,
["charWidth"]=0,
["charHeight"]=0,
["backgroundColor"]=0xFFFFFF
}
local component = require("component")
-- local ocelot = component.proxy(component.list("ocelot")())
local gpu = component.gpu
local display = {}
local chunksAffected = {}
local renderBuffer = nil
-- braille rendering
function raster.units.charToBraille(x,y)
return x*2,y*4
end
function raster.units.brailleToChar(x,y)
return math.ceil(x/2),math.ceil(y/4)
end
function raster.init(width, height, bgcolor)
-- NOTE: Width and height are in characters, not pixels in braille.
-- If the width and height are nil, the entire screen will be used.
if width==nil and height==nil then
width, height = gpu.getResolution()
end
raster.charWidth = width
raster.charHeight = height
width, height = raster.units.charToBraille(width, height)
bgcolor = bgcolor or raster.defaultBackgroundColor
if bgcolor~=0 then
for i=1,width*height do
display[i]=bgcolor
end
end
raster.displayWidth = width
raster.displayHeight = height
raster.backgroundColor = bgcolor
pcall(function()
renderBuffer = gpu.allocateBuffer()
end)
raster.clear()
end
function raster.set(x, y, color)
if x<1 or x>raster.displayWidth or y<1 or y>raster.displayHeight then
return false
end
color = color or raster.defaultForegroundColor
local i = x+y*raster.displayWidth
display[i] = color
local ci = math.floor((x-1)/2)+math.floor((y-1)/4)*raster.charWidth+1
-- ocelot.log(x..","..y..":"..ci)
chunksAffected[ci] = true
return true
end
function raster.get(x, y)
local i = x+y*raster.displayWidth
return display[i] or raster.backgroundColor
end
local function stats(arr)
local out = {}
for i=1,#arr do
local v = arr[i]
if out[v]==nil then
out[v]=1
else
out[v] = out[v] + 1
end
end
return out
end
local function getKeys(t)
local keys = {}
for k,v in pairs(t) do
table.insert(keys,{k,v})
end
table.sort(keys,function(a,b)
return a[2]>b[2]
end)
for i=1,#keys do
keys[i] = keys[i][1]
end
return keys
end
local function colorDifference(a,b)
return ((a>>16)&255)-((b>>16)&255)+((a>>8)&255)-((b>>8)&255)+(a&255)-(b&255)
end
local function limitTwoColors(arr)
local colors = getKeys(stats(arr))
for i=1,#arr do
local v=arr[i]
if v==colors[1] then
arr[i]=0
goto continue
elseif v==colors[2] then
arr[i]=1
goto continue
else
--error("Pixel is not in the two colors (raster.lua:90)")
-- get closest color so atleast it kinda shows
if colorDifference(v,colors[1])<colorDifference(v,colors[2]) then
arr[i]=0
else
arr[i]=1
end
end
::continue::
end
return arr,colors[1] or 0,colors[2] or 0
end
local function arrayToBraille(arr)
local codePoint = 0x2800
for i=1,8 do
codePoint = codePoint | arr[i]<<(i-1)
end
if codePoint==0x2800 then return " " end
return utf8.char(codePoint)
end
function raster.update()
if renderBuffer~=nil then
gpu.setActiveBuffer(renderBuffer)
end
for y=1,raster.displayHeight,4 do
-- gpu.set(0,0,tostring(y))
for x=1,raster.displayWidth,2 do
local ci = math.floor(x/2)+math.floor(y/4)*raster.charWidth+1
if chunksAffected[ci] then
local chunk = {
raster.get(x,y),
raster.get(x,y+1),
raster.get(x,y+2),
raster.get(x+1,y),
raster.get(x+1,y+1),
raster.get(x+1,y+2),
raster.get(x,y+3),
raster.get(x+1,y+3)
}
local colorA = nil
local colorB = nil
chunk,colorA,colorB = limitTwoColors(chunk)
-- print(tostring(colorA)..","..tostring(colorB))
cx,cy=raster.units.brailleToChar(x,y)
gpu.setBackground(colorA)
gpu.setForeground(colorB)
-- gpu.set(cx,cy,tostring(colorB/0xFFFFFF))
gpu.set(cx,cy,arrayToBraille(chunk))
chunksAffected[ci] = false
end
end
end
if renderBuffer~=nil then
gpu.bitblt()
gpu.setActiveBuffer(0)
end
end
function raster.clear()
if renderBuffer~=nil then
gpu.setActiveBuffer(renderBuffer)
end
-- clear()
local bgcolor = raster.backgroundColor
gpu.setBackground(bgcolor)
gpu.fill(1,1,raster.displayWidth,raster.displayHeight," ")
display = {}
end
function raster.free()
if renderBuffer==nil then
return true
else
return gpu.freeBuffer(renderBuffer)
end
end
-- advanced rendering
function raster.drawLine(x1, y1, x2, y2, color)
x1, y1, x2, y2 = math.floor(x1), math.floor(y1), math.floor(x2), math.floor(y2)
local dx = math.abs(x2 - x1)
local dy = math.abs(y2 - y1)
local sx = x1 < x2 and 1 or -1
local sy = y1 < y2 and 1 or -1
local err = dx - dy
while true do
raster.set(x1, y1, color)
if x1 == x2 and y1 == y2 then
break
end
local e2 = 2 * err
if e2 > -dy then
err = err - dy
x1 = x1 + sx
end
if e2 < dx then
err = err + dx
y1 = y1 + sy
end
end
end
function raster.drawRect(x1,y1,x2,y2,col)
x1, y1, x2, y2 = math.floor(x1), math.floor(y1), math.floor(x2), math.floor(y2)
if x1 > x2 then x1, x2 = x2, x1 end
if y1 > y2 then y1, y2 = y2, y1 end
for x=x1,x2 do
raster.set(x,y1,col)
raster.set(x,y2,col)
end
for y=y1+1,y2-1 do
raster.set(x1,y,col)
raster.set(x2,y,col)
end
end
function raster.fillRect(x1,y1,x2,y2,col)
x1, y1, x2, y2 = math.floor(x1), math.floor(y1), math.floor(x2), math.floor(y2)
if x1 > x2 then x1, x2 = x2, x1 end
if y1 > y2 then y1, y2 = y2, y1 end
for x=x1,x2 do
for y=y1,y2 do
raster.set(x,y,col)
end
end
end
function raster.drawCircle(xc, yc, radius, color)
xc=math.floor(xc)
yc=math.floor(yc)
radius=math.floor(radius)
local x = 0
local y = radius
local d = 3 - 2 * radius
while y >= x do
-- Draw 8 symmetric points
raster.set(xc + x, yc + y, color)
raster.set(xc - x, yc + y, color)
raster.set(xc + x, yc - y, color)
raster.set(xc - x, yc - y, color)
raster.set(xc + y, yc + x, color)
raster.set(xc - y, yc + x, color)
raster.set(xc + y, yc - x, color)
raster.set(xc - y, yc - x, color)
if d < 0 then
d = d + 4 * x + 6
else
d = d + 4 * (x - y) + 10
y = y - 1
end
x = x + 1
end
end
function raster.drawEllipse(x1, y1, x2, y2, color)
if x1 > x2 then x1, x2 = x2, x1 end
if y1 > y2 then y1, y2 = y2, y1 end
local xc = math.floor((x1 + x2) / 2)
local yc = math.floor((y1 + y2) / 2)
local a = math.floor((x2 - x1) / 2)
local b = math.floor((y2 - y1) / 2)
if a <= 0 or b <= 0 then
return
end
if a == b then
raster.drawCircle(xc, yc, a, color)
return
end
if a <= 1 and b <= 1 then
raster.set(xc, yc, color)
return
elseif a <= 1 then
for y = yc - b, yc + b do
raster.set(xc, y, color)
end
return
elseif b <= 1 then
for x = xc - a, xc + a do
raster.set(x, yc, color)
end
return
end
local x = 0
local y = b
local a2 = a * a
local b2 = b * b
local d1 = b2 - (a2 * b) + (0.25 * a2)
local dx = 2 * b2 * x
local dy = 2 * a2 * y
while dx < dy do
raster.set(xc + x, yc + y, color)
raster.set(xc - x, yc + y, color)
raster.set(xc + x, yc - y, color)
if d1 < 0 then
x = x + 1
dx = dx + (2 * b2)
d1 = d1 + dx + b2
else
x = x + 1
y = y - 1
dx = dx + (2 * b2)
dy = dy - (2 * a2)
d1 = d1 + dx - dy + b2
end
end
local d2 = b2 * (x + 0.5) * (x + 0.5) + a2 * (y - 1) * (y - 1) - a2 * b2
while y >= 0 do
raster.set(xc + x, yc + y, color)
raster.set(xc - x, yc + y, color)
raster.set(xc + x, yc - y, color)
raster.set(xc - x, yc - y, color)
if d2 > 0 then
y = y - 1
dy = dy - (2 * a2)
d2 = d2 - dy + a2
else
y = y - 1
x = x + 1
dx = dx + (2 * b2)
dy = dy - (2 * a2)
d2 = d2 + dx - dy + a2
end
end
end
function raster.fillCircle(x, y, r, color)
x, y = math.floor(x + 0.5), math.floor(y + 0.5)
r = math.floor(r + 0.5)
if r <= 0 then return end
local minX, maxX = x - r, x + r
local minY, maxY = y - r, y + r
for py = minY, maxY do
for px = minX, maxX do
local dx, dy = px - x, py - y
local distSquared = dx*dx + dy*dy
if distSquared <= r*r then
raster.set(px, py, color)
end
end
end
end
function raster.fillEllipse(x1, y1, x2, y2, color)
local centerX = (x1 + x2) / 2
local centerY = (y1 + y2) / 2
local a = math.abs(x2 - x1) / 2
local b = math.abs(y2 - y1) / 2
centerX = math.floor(centerX + 0.5)
centerY = math.floor(centerY + 0.5)
a = math.floor(a + 0.5)
b = math.floor(b + 0.5)
if a <= 0 or b <= 0 then return end
if a == b then
raster.fillCircle(centerX, centerY, a, color)
return
end
local minX = centerX - a
local maxX = centerX + a
local minY = centerY - b
local maxY = centerY + b
for y = minY, maxY do
for x = minX, maxX do
local dx = x - centerX
local dy = y - centerY
local value = (dx*dx)/(a*a) + (dy*dy)/(b*b)
if value <= 1 then
raster.set(x, y, color)
end
end
end
end
return raster
-125
View File
@@ -1,125 +0,0 @@
local serialize = {}
function serialize.string(str)
return '"'..str:gsub("[%z\1-\31\34\92\127-\159]",function(c)
local byte = c:byte()
if byte== 7 then return "\\a" end
if byte== 8 then return "\\b" end
if byte== 9 then return "\\t" end
if byte==10 then return "\\n" end
if byte==11 then return "\\v" end
if byte==12 then return "\\f" end
if byte==13 then return "\\r" end
if byte==34 then return "\\\"" end
if byte==92 then return "\\\\" end
return string.format("\\x%02x",byte)
end)..'"'
end
function serialize.table(tbl,colors,stack)
stack = table.copy(stack or {})
table.insert(stack,tbl)
local keyAmount = 0
local keyNumber = true
local out = ""
local first = true
for key,val in pairs(tbl) do
if not first then out=out..",\n" end
first=false
out=out.." "
if type(key)=="string" then
if key:match("^[%a_][%w_]*$") then
out=out..key.."="
else
out=out..'['..serialize.string(key)..']='
end
else
out=out.."["..tostring(key).."]="
end
if type(key)~="number" then
keyNumber=false
end
local success,reason = pcall(function()
local valStr = ""
if type(val)=="table" then
if #stack>4 or table.find(stack,val) then
valStr="..."
else
valStr=serialize.table(val,colors,stack)
end
elseif type(val)=="string" then
local lines = {}
for line in (val.."\n"):gmatch("([^\n]*)\n") do table.insert(lines,line) end
if #lines[#lines]==0 then
lines[#lines]=nil
lines[#lines]=lines[#lines].."\n"
end
for i=1,#lines do
if i<#lines then
lines[i]=serialize.string(lines[i].."\n")
else
lines[i]=serialize.string(lines[i])
end
end
valStr=table.concat(lines," ..\n ")
else
valStr=tostring(val)
end
local lines = {}
for line in (valStr.."\n"):gmatch("([^\n]*)\n") do table.insert(lines,line) end
out=out..table.concat(lines,"\n ")
lines = nil
keyAmount=keyAmount+1
end)
if not success then
if colors then out=out.."\x1b[91m" end
out=out.."["..tostring(reason).."]"
if colors then out=out.."\x1b[39m" end
end
coroutine.yield()
end
local metatbl = getmetatable(tbl)
local metakeys = {}
if type(metatbl)=="table" then
for i,v in pairs(metatbl) do
keyNumber=false
table.insert(metakeys,i)
end
end
if #metakeys>0 then
out=out.."\n "
if colors then out=out.."\x1b[92m" end
if table.find(metakeys,"__tostring") then
out=out.."tostring: "..serialize.string(tostring(tbl)).."\n "
table.remove(metakeys,table.find(metakeys,"__tostring"))
end
out=out..table.concat(metakeys,", ")
if colors then out=out.."\x1b[39m" end
end
if keyAmount==0 then return "{}" end
if keyNumber then
-- fix strings not being serialised
local vals = {}
for _,v in pairs(tbl) do
if #vals>=5 and #stack>1 then
table.insert(vals,"...")
break
end
if type(v)=="table" then
table.insert(vals,serialize.table(v,colors,stack))
elseif type(v)=="string" then
table.insert(vals,serialize.string(v))
else
table.insert(vals,tostring(v))
end
end
return "{"..table.concat(vals,", ").."}"
end
return "{\n"..out.."\n}"
end
return serialize
-102
View File
@@ -1,102 +0,0 @@
local unicodeLib
local LLunicode
if table.copy then
unicodeLib = table.copy(unicode)
LLunicode = table.copy(unicode)
else
unicodeLib = {}
LLunicode = unicode
end
function unicodeLib.readCodePoint(readByte)
checkArg(1,readByte,"function")
local function inRange(min,max,...)
for _,v in ipairs({...}) do
if not (v and v>=min and v<max) then return false end
end
return true
end
local byte = readByte()
if byte==nil then return end
if byte < 0x80 then
-- ASCII character (0xxxxxxx)
return byte
elseif byte < 0xC0 then
-- Continuation byte (10xxxxxx), invalid at start position
return nil
elseif byte < 0xE0 then
-- 2-byte sequence (110xxxxx 10xxxxxx)
local byte2 = readByte()
if byte2==nil then return nil end
if inRange(0x80,0xC0,byte2) then
local code_point = ((byte & 0x1F) << 6) | (byte2 & 0x3F)
return code_point
end
elseif byte < 0xF0 then
-- 3-byte sequence (1110xxxx 10xxxxxx 10xxxxxx)
local byte2, byte3 = readByte(), readByte()
if byte2==nil and byte3==nil then return nil end
if inRange(0x80,0xC0,byte2,byte3)then
local code_point = ((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F)
return code_point
end
elseif byte < 0xF8 then
-- 4-byte sequence (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
local byte2, byte3, byte4 = readByte(), readByte(), readByte()
if byte2==nil and byte3==nil and byte4==nil then return nil end
if inRange(0x80,0xC0,byte2,byte3,byte4) then
local code_point = ((byte & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F)
return code_point
end
end
-- Invalid UTF-8 byte sequence
return nil
end
function unicodeLib.readChar(readByte)
checkArg(1,readByte,"function")
return LLunicode.char(unicodeLib.readCodePoint(readByte))
end
function unicodeLib.codepoint(chr)
checkArg(1,chr,"string")
local ptr = 1
return unicode.readCodePoint(function()
local byte = chr:byte(ptr)
ptr=ptr+1
return byte
end),ptr-1
end
function unicodeLib.iterate(readByte)
checkArg(1,readByte,"string","function")
if type(readByte)=="string" then
local str,ptr = readByte,0
readByte = function()
ptr=ptr+1
return str:byte(ptr)
end
end
return function()
local point = unicodeLib.readCodePoint(readByte)
if point==nil then return nil end
return LLunicode.char(point),point
end
end
unicodeLib.char = LLunicode.char
unicodeLib.charWidth = LLunicode.charWidth
unicodeLib.isWide = LLunicode.isWide
unicodeLib.len = LLunicode.len
unicodeLib.lower = LLunicode.lower
unicodeLib.reverse = LLunicode.reverse
unicodeLib.sub = LLunicode.sub
unicodeLib.upper = LLunicode.upper
unicodeLib.wlen = LLunicode.wlen
unicodeLib.wtrunc = LLunicode.wtrunc
return unicodeLib
+1 -308
View File
File diff suppressed because one or more lines are too long