1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-26 19:37:39 +00:00

Relocate all resource files

- textures/{block,item}s -> textures/{block,item}
 - assets/*/{advancements,lua,recipes} -> data/*/...
This commit is contained in:
SquidDev
2019-03-31 10:18:59 +01:00
parent 1fd0b40776
commit 5e462adc5c
479 changed files with 0 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
-- Colors
white = 1
orange = 2
magenta = 4
lightBlue = 8
yellow = 16
lime = 32
pink = 64
gray = 128
lightGray = 256
cyan = 512
purple = 1024
blue = 2048
brown = 4096
green = 8192
red = 16384
black = 32768
function combine( ... )
local r = 0
for n,c in ipairs( { ... } ) do
if type( c ) ~= "number" then
error( "bad argument #"..n.." (expected number, got " .. type( c ) .. ")", 2 )
end
r = bit32.bor(r,c)
end
return r
end
function subtract( colors, ... )
if type( colors ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( colors ) .. ")", 2 )
end
local r = colors
for n,c in ipairs( { ... } ) do
if type( c ) ~= "number" then
error( "bad argument #"..tostring( n+1 ).." (expected number, got " .. type( c ) .. ")", 2 )
end
r = bit32.band(r, bit32.bnot(c))
end
return r
end
function test( colors, color )
if type( colors ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( colors ) .. ")", 2 )
end
if type( color ) ~= "number" then
error( "bad argument #2 (expected number, got " .. type( color ) .. ")", 2 )
end
return bit32.band(colors, color) == color
end
function packRGB( r, g, b )
if type( r ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( r ) .. ")", 2 )
end
if type( g ) ~= "number" then
error( "bad argument #2 (expected number, got " .. type( g ) .. ")", 2 )
end
if type( b ) ~= "number" then
error( "bad argument #3 (expected number, got " .. type( b ) .. ")", 2 )
end
return
bit32.band( r * 255, 0xFF ) * 2^16 +
bit32.band( g * 255, 0xFF ) * 2^8 +
bit32.band( b * 255, 0xFF )
end
function unpackRGB( rgb )
if type( rgb ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( rgb ) .. ")", 2 )
end
return
bit32.band( bit32.rshift( rgb, 16 ), 0xFF ) / 255,
bit32.band( bit32.rshift( rgb, 8 ), 0xFF ) / 255,
bit32.band( rgb, 0xFF ) / 255
end
function rgb8( r, g, b )
if g == nil and b == nil then
return unpackRGB( r )
else
return packRGB( r, g, b )
end
end

View File

@@ -0,0 +1,11 @@
-- Colours (for lovers of british spelling)
local colours = _ENV
for k,v in pairs(colors) do
colours[k] = v
end
colours.grey = colors.gray
colours.gray = nil
colours.lightGrey = colors.lightGray
colours.lightGray = nil

View File

@@ -0,0 +1,49 @@
if not commands then
error( "Cannot load command API on normal computer", 2 )
end
native = commands.native or commands
local function collapseArgs( bJSONIsNBT, ... )
local args = table.pack(...)
for i = 1, #args do
local arg = args[i]
if type(arg) == "boolean" or type(arg) == "number" or type(arg) == "string" then
args[i] = tostring(arg)
elseif type(arg) == "table" then
args[i] = textutils.serialiseJSON( arg, bJSONIsNBT )
else
error( "Expected string, number, boolean or table", 3 )
end
end
return table.concat(args, " ")
end
-- Put native functions into the environment
local env = _ENV
for k,v in pairs( native ) do
env[k] = v
end
-- Create wrapper functions for all the commands
local tAsync = {}
local tNonNBTJSONCommands = {
[ "tellraw" ] = true,
[ "title" ] = true
}
local tCommands = native.list()
for n,sCommandName in ipairs(tCommands) do
if env[ sCommandName ] == nil then
local bJSONIsNBT = (tNonNBTJSONCommands[ sCommandName ] == nil)
env[ sCommandName ] = function( ... )
local sCommand = collapseArgs( bJSONIsNBT, sCommandName, ... )
return native.exec( sCommand )
end
tAsync[ sCommandName ] = function( ... )
local sCommand = collapseArgs( bJSONIsNBT, sCommandName, ... )
return native.execAsync( sCommand )
end
end
end
env.async = tAsync

View File

@@ -0,0 +1,87 @@
local function isDrive( name )
if type( name ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( name ) .. ")", 3 )
end
return peripheral.getType( name ) == "drive"
end
function isPresent( name )
if isDrive( name ) then
return peripheral.call( name, "isDiskPresent" )
end
return false
end
function getLabel( name )
if isDrive( name ) then
return peripheral.call( name, "getDiskLabel" )
end
return nil
end
function setLabel( name, label )
if isDrive( name ) then
peripheral.call( name, "setDiskLabel", label )
end
end
function hasData( name )
if isDrive( name ) then
return peripheral.call( name, "hasData" )
end
return false
end
function getMountPath( name )
if isDrive( name ) then
return peripheral.call( name, "getMountPath" )
end
return nil
end
function hasAudio( name )
if isDrive( name ) then
return peripheral.call( name, "hasAudio" )
end
return false
end
function getAudioTitle( name )
if isDrive( name ) then
return peripheral.call( name, "getAudioTitle" )
end
return nil
end
function playAudio( name )
if isDrive( name ) then
peripheral.call( name, "playAudio" )
end
end
function stopAudio( name )
if not name then
for n,sName in ipairs( peripheral.getNames() ) do
stopAudio( sName )
end
else
if isDrive( name ) then
peripheral.call( name, "stopAudio" )
end
end
end
function eject( name )
if isDrive( name ) then
peripheral.call( name, "ejectDisk" )
end
end
function getID( name )
if isDrive( name ) then
return peripheral.call( name, "getDiskID" )
end
return nil
end

View File

@@ -0,0 +1,167 @@
CHANNEL_GPS = 65534
local function trilaterate( A, B, C )
local a2b = B.vPosition - A.vPosition
local a2c = C.vPosition - A.vPosition
if math.abs( a2b:normalize():dot( a2c:normalize() ) ) > 0.999 then
return nil
end
local d = a2b:length()
local ex = a2b:normalize( )
local i = ex:dot( a2c )
local ey = (a2c - (ex * i)):normalize()
local j = ey:dot( a2c )
local ez = ex:cross( ey )
local r1 = A.nDistance
local r2 = B.nDistance
local r3 = C.nDistance
local x = (r1*r1 - r2*r2 + d*d) / (2*d)
local y = (r1*r1 - r3*r3 - x*x + (x-i)*(x-i) + j*j) / (2*j)
local result = A.vPosition + (ex * x) + (ey * y)
local zSquared = r1*r1 - x*x - y*y
if zSquared > 0 then
local z = math.sqrt( zSquared )
local result1 = result + (ez * z)
local result2 = result - (ez * z)
local rounded1, rounded2 = result1:round( 0.01 ), result2:round( 0.01 )
if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then
return rounded1, rounded2
else
return rounded1
end
end
return result:round( 0.01 )
end
local function narrow( p1, p2, fix )
local dist1 = math.abs( (p1 - fix.vPosition):length() - fix.nDistance )
local dist2 = math.abs( (p2 - fix.vPosition):length() - fix.nDistance )
if math.abs(dist1 - dist2) < 0.01 then
return p1, p2
elseif dist1 < dist2 then
return p1:round( 0.01 )
else
return p2:round( 0.01 )
end
end
function locate( _nTimeout, _bDebug )
if _nTimeout ~= nil and type( _nTimeout ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( _nTimeout ) .. ")", 2 )
end
if _bDebug ~= nil and type( _bDebug ) ~= "boolean" then
error( "bad argument #2 (expected boolean, got " .. type( _bDebug) .. ")", 2 )
end
-- Let command computers use their magic fourth-wall-breaking special abilities
if commands then
return commands.getBlockPosition()
end
-- Find a modem
local sModemSide = nil
for n,sSide in ipairs( rs.getSides() ) do
if peripheral.getType( sSide ) == "modem" and peripheral.call( sSide, "isWireless" ) then
sModemSide = sSide
break
end
end
if sModemSide == nil then
if _bDebug then
print( "No wireless modem attached" )
end
return nil
end
if _bDebug then
print( "Finding position..." )
end
-- Open a channel
local modem = peripheral.wrap( sModemSide )
local bCloseChannel = false
if not modem.isOpen( os.getComputerID() ) then
modem.open( os.getComputerID() )
bCloseChannel = true
end
-- Send a ping to listening GPS hosts
modem.transmit( CHANNEL_GPS, os.getComputerID(), "PING" )
-- Wait for the responses
local tFixes = {}
local pos1, pos2 = nil, nil
local timeout = os.startTimer( _nTimeout or 2 )
while true do
local e, p1, p2, p3, p4, p5 = os.pullEvent()
if e == "modem_message" then
-- We received a reply from a modem
local sSide, sChannel, sReplyChannel, tMessage, nDistance = p1, p2, p3, p4, p5
if sSide == sModemSide and sChannel == os.getComputerID() and sReplyChannel == CHANNEL_GPS and nDistance then
-- Received the correct message from the correct modem: use it to determine position
if type(tMessage) == "table" and #tMessage == 3 and tonumber(tMessage[1]) and tonumber(tMessage[2]) and tonumber(tMessage[3]) then
local tFix = { vPosition = vector.new( tMessage[1], tMessage[2], tMessage[3] ), nDistance = nDistance }
if _bDebug then
print( tFix.nDistance.." metres from "..tostring( tFix.vPosition ) )
end
if tFix.nDistance == 0 then
pos1, pos2 = tFix.vPosition, nil
else
table.insert( tFixes, tFix )
if #tFixes >= 3 then
if not pos1 then
pos1, pos2 = trilaterate( tFixes[1], tFixes[2], tFixes[#tFixes] )
else
pos1, pos2 = narrow( pos1, pos2, tFixes[#tFixes] )
end
end
end
if pos1 and not pos2 then
break
end
end
end
elseif e == "timer" then
-- We received a timeout
local timer = p1
if timer == timeout then
break
end
end
end
-- Close the channel, if we opened one
if bCloseChannel then
modem.close( os.getComputerID() )
end
-- Return the response
if pos1 and pos2 then
if _bDebug then
print( "Ambiguous position" )
print( "Could be "..pos1.x..","..pos1.y..","..pos1.z.." or "..pos2.x..","..pos2.y..","..pos2.z )
end
return nil
elseif pos1 then
if _bDebug then
print( "Position is "..pos1.x..","..pos1.y..","..pos1.z )
end
return pos1.x, pos1.y, pos1.z
else
if _bDebug then
print( "Could not determine position" )
end
return nil
end
end

View File

@@ -0,0 +1,78 @@
local sPath = "/rom/help"
function path()
return sPath
end
function setPath( _sPath )
if type( _sPath ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sPath ) .. ")", 2 )
end
sPath = _sPath
end
function lookup( _sTopic )
if type( _sTopic ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sTopic ) .. ")", 2 )
end
-- Look on the path variable
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = fs.combine( sPath, _sTopic )
if fs.exists( sPath ) and not fs.isDir( sPath ) then
return sPath
elseif fs.exists( sPath..".txt" ) and not fs.isDir( sPath..".txt" ) then
return sPath..".txt"
end
end
-- Not found
return nil
end
function topics()
-- Add index
local tItems = {
[ "index" ] = true
}
-- Add topics from the path
for sPath in string.gmatch(sPath, "[^:]+") do
if fs.isDir( sPath ) then
local tList = fs.list( sPath )
for n,sFile in pairs( tList ) do
if string.sub( sFile, 1, 1 ) ~= "." then
if not fs.isDir( fs.combine( sPath, sFile ) ) then
if #sFile > 4 and sFile:sub(-4) == ".txt" then
sFile = sFile:sub(1,-5)
end
tItems[ sFile ] = true
end
end
end
end
end
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
table.insert( tItemList, sItem )
end
table.sort( tItemList )
return tItemList
end
function completeTopic( sText )
if type( sText ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sText ) .. ")", 2 )
end
local tTopics = topics()
local tResults = {}
for n=1,#tTopics do
local sTopic = tTopics[n]
if #sTopic > #sText and string.sub( sTopic, 1, #sText ) == sText then
table.insert( tResults, string.sub( sTopic, #sText + 1 ) )
end
end
return tResults
end

View File

@@ -0,0 +1,249 @@
-- Definition for the IO API
local typeOf = _G.type
--- If we return nil then close the file, as we've reached the end.
-- We use this weird wrapper function as we wish to preserve the varargs
local function checkResult(handle, ...)
if ... == nil and handle._autoclose and not handle._closed then handle:close() end
return ...
end
local handleMetatable
handleMetatable = {
__name = "FILE*",
__tostring = function(self)
if self._closed then
return "file (closed)"
else
local hash = tostring(self._handle):match("table: (%x+)")
return "file (" .. hash .. ")"
end
end,
__index = {
close = function(self)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if handle.close then
self._closed = true
handle.close()
return true
else
return nil, "attempt to close standard stream"
end
end,
flush = function(self)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if handle.flush then handle.flush() end
end,
lines = function(self, ...)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if not handle.read then return nil, "file is not readable" end
local args = table.pack(...)
return function() return checkResult(self, self:read(table.unpack(args, 1, args.n))) end
end,
read = function(self, ...)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if not handle.read and not handle.readLine then return nil, "Not opened for reading" end
local n = select('#', ...)
local output = {}
for i = 1, n do
local arg = select(i, ...)
local res
if typeOf(arg) == "number" then
if handle.read then res = handle.read(arg) end
elseif typeOf(arg) == "string" then
local format = arg:gsub("^%*", ""):sub(1, 1)
if format == "l" then
if handle.readLine then res = handle.readLine() end
elseif format == "L" and handle.readLine then
if handle.readLine then res = handle.readLine(true) end
elseif format == "a" then
if handle.readAll then res = handle.readAll() or "" end
elseif format == "n" then
res = nil -- Skip this format as we can't really handle it
else
error("bad argument #" .. i .. " (invalid format)", 2)
end
else
error("bad argument #" .. i .. " (expected string, got " .. typeOf(arg) .. ")", 2)
end
output[i] = res
if not res then break end
end
-- Default to "l" if possible
if n == 0 and handle.readLine then return handle.readLine() end
return table.unpack(output, 1, n)
end,
seek = function(self, whence, offset)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if not handle.seek then return nil, "file is not seekable" end
-- It's a tail call, so error positions are preserved
return handle.seek(whence, offset)
end,
setvbuf = function(self, mode, size) end,
write = function(self, ...)
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
end
if self._closed then error("attempt to use a closed file", 2) end
local handle = self._handle
if not handle.write then return nil, "file is not writable" end
local n = select("#", ...)
for i = 1, n do handle.write(select(i, ...)) end
return self
end,
},
}
local defaultInput = setmetatable({
_handle = { readLine = _G.read }
}, handleMetatable)
local defaultOutput = setmetatable({
_handle = { write = _G.write }
}, handleMetatable)
local defaultError = setmetatable({
_handle = {
write = function(...)
local oldColour
if term.isColour() then
oldColour = term.getTextColour()
term.setTextColour(colors.red)
end
_G.write(...)
if term.isColour() then term.setTextColour(oldColour) end
end,
}
}, handleMetatable)
local currentInput = defaultInput
local currentOutput = defaultOutput
stdin = defaultInput
stdout = defaultOutput
stderr = defaultError
function close(_file)
if _file == nil then return currentOutput:close() end
if typeOf(_file) ~= "table" or getmetatable(_file) ~= handleMetatable then
error("bad argument #1 (FILE expected, got " .. typeOf(_file) .. ")", 2)
end
return _file:close()
end
function flush()
return currentOutput:flush()
end
function input(_arg)
if typeOf(_arg) == "string" then
local res, err = open(_arg, "rb")
if not res then error(err, 2) end
currentInput = res
elseif typeOf(_arg) == "table" and getmetatable(_arg) == handleMetatable then
currentInput = _arg
elseif _arg ~= nil then
error("bad argument #1 (FILE expected, got " .. typeOf(_arg) .. ")", 2)
end
return currentInput
end
function lines(_sFileName)
if _sFileName ~= nil and typeOf(_sFileName) ~= "string" then
error("bad argument #1 (expected string, got " .. typeOf(_sFileName) .. ")", 2)
end
if _sFileName then
local ok, err = open(_sFileName, "rb")
if not ok then error(err, 2) end
-- We set this magic flag to mark this file as being opened by io.lines and so should be
-- closed automatically
ok._autoclose = true
return ok:lines()
else
return currentInput:lines()
end
end
function open(_sPath, _sMode)
if typeOf(_sPath) ~= "string" then
error("bad argument #1 (expected string, got " .. typeOf(_sPath) .. ")", 2)
end
if _sMode ~= nil and typeOf(_sMode) ~= "string" then
error("bad argument #2 (expected string, got " .. typeOf(_sMode) .. ")", 2)
end
local sMode = _sMode and _sMode:gsub("%+", "") or "rb"
local file, err = fs.open(_sPath, sMode)
if not file then return nil, err end
return setmetatable({ _handle = file }, handleMetatable)
end
function output(_arg)
if typeOf(_arg) == "string" then
local res, err = open(_arg, "w")
if not res then error(err, 2) end
currentOutput = res
elseif typeOf(_arg) == "table" and getmetatable(_arg) == handleMetatable then
currentOutput = _arg
elseif _arg ~= nil then
error("bad argument #1 (FILE expected, got " .. typeOf(_arg) .. ")", 2)
end
return currentOutput
end
function read(...)
return currentInput:read(...)
end
function type(handle)
if typeOf(handle) == "table" and getmetatable(handle) == handleMetatable then
if handle._closed then
return "closed file"
else
return "file"
end
end
return nil
end
function write(...)
return currentOutput:write(...)
end

View File

@@ -0,0 +1,65 @@
-- Minecraft key code bindings
-- See http://www.minecraftwiki.net/wiki/Key_codes for more info
local tKeys = {
nil, "one", "two", "three", "four", -- 1
"five", "six", "seven", "eight", "nine", -- 6
"zero", "minus", "equals", "backspace","tab", -- 11
"q", "w", "e", "r", "t", -- 16
"y", "u", "i", "o", "p", -- 21
"leftBracket","rightBracket","enter","leftCtrl","a", -- 26
"s", "d", "f", "g", "h", -- 31
"j", "k", "l", "semiColon","apostrophe", -- 36
"grave", "leftShift","backslash","z", "x", -- 41
"c", "v", "b", "n", "m", -- 46
"comma", "period", "slash", "rightShift","multiply", -- 51
"leftAlt", "space", "capsLock", "f1", "f2", -- 56
"f3", "f4", "f5", "f6", "f7", -- 61
"f8", "f9", "f10", "numLock", "scrollLock", -- 66
"numPad7", "numPad8", "numPad9", "numPadSubtract","numPad4", -- 71
"numPad5", "numPad6", "numPadAdd","numPad1", "numPad2", -- 76
"numPad3", "numPad0", "numPadDecimal",nil, nil, -- 81
nil, "f11", "f12", nil, nil, -- 86
nil, nil, nil, nil, nil, -- 91
nil, nil, nil, nil, "f13", -- 96
"f14", "f15", nil, nil, nil, -- 101
nil, nil, nil, nil, nil, -- 106
nil, "kana", nil, nil, nil, -- 111
nil, nil, nil, nil, nil, -- 116
"convert", nil, "noconvert",nil, "yen", -- 121
nil, nil, nil, nil, nil, -- 126
nil, nil, nil, nil, nil, -- 131
nil, nil, nil, nil, nil, -- 136
"numPadEquals",nil, nil, "circumflex","at", -- 141
"colon", "underscore","kanji", "stop", "ax", -- 146
nil, nil, nil, nil, nil, -- 151
"numPadEnter","rightCtrl",nil, nil, nil, -- 156
nil, nil, nil, nil, nil, -- 161
nil, nil, nil, nil, nil, -- 166
nil, nil, nil, nil, nil, -- 171
nil, nil, nil, "numPadComma",nil, -- 176
"numPadDivide",nil, nil, "rightAlt", nil, -- 181
nil, nil, nil, nil, nil, -- 186
nil, nil, nil, nil, nil, -- 191
nil, "pause", nil, "home", "up", -- 196
"pageUp", nil, "left", nil, "right", -- 201
nil, "end", "down", "pageDown", "insert", -- 206
"delete" -- 211
}
local keys = _ENV
for nKey, sKey in pairs( tKeys ) do
keys[sKey] = nKey
end
keys["return"] = keys.enter
--backwards compatibility to earlier, typo prone, versions
keys.scollLock = keys.scrollLock
keys.cimcumflex = keys.circumflex
function getName( _nKey )
if type( _nKey ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( _nKey ) .. ")", 2 )
end
return tKeys[ _nKey ]
end

View File

@@ -0,0 +1,213 @@
local function drawPixelInternal( xPos, yPos )
term.setCursorPos( xPos, yPos )
term.write(" ")
end
local tColourLookup = {}
for n=1,16 do
tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
end
local function parseLine( tImageArg, sLine )
local tLine = {}
for x=1,sLine:len() do
tLine[x] = tColourLookup[ string.byte(sLine,x,x) ] or 0
end
table.insert( tImageArg, tLine )
end
function parseImage( sRawData )
if type( sRawData ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sRawData ) .. ")" )
end
local tImage = {}
for sLine in ( sRawData .. "\n" ):gmatch( "(.-)\n" ) do -- read each line like original file handling did
parseLine( tImage, sLine )
end
return tImage
end
function loadImage( sPath )
if type( sPath ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 )
end
if fs.exists( sPath ) then
local file = io.open( sPath, "r" )
local sContent = file:read("*a")
file:close()
return parseImage( sContent ) -- delegate image parse to parseImage
end
return nil
end
function drawPixel( xPos, yPos, nColour )
if type( xPos ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( xPos ) .. ")", 2 ) end
if type( yPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( yPos ) .. ")", 2 ) end
if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nColour ) .. ")", 2 ) end
if nColour then
term.setBackgroundColor( nColour )
end
drawPixelInternal( xPos, yPos )
end
function drawLine( startX, startY, endX, endY, nColour )
if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end
if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end
if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end
if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end
if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end
startX = math.floor(startX)
startY = math.floor(startY)
endX = math.floor(endX)
endY = math.floor(endY)
if nColour then
term.setBackgroundColor( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal( startX, startY )
return
end
local minX = math.min( startX, endX )
local maxX, minY, maxY
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
-- TODO: clip to screen rectangle?
local xDiff = maxX - minX
local yDiff = maxY - minY
if xDiff > math.abs(yDiff) then
local y = minY
local dy = yDiff / xDiff
for x=minX,maxX do
drawPixelInternal( x, math.floor( y + 0.5 ) )
y = y + dy
end
else
local x = minX
local dx = xDiff / yDiff
if maxY >= minY then
for y=minY,maxY do
drawPixelInternal( math.floor( x + 0.5 ), y )
x = x + dx
end
else
for y=minY,maxY,-1 do
drawPixelInternal( math.floor( x + 0.5 ), y )
x = x - dx
end
end
end
end
function drawBox( startX, startY, endX, endY, nColour )
if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end
if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end
if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end
if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end
if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end
startX = math.floor(startX)
startY = math.floor(startY)
endX = math.floor(endX)
endY = math.floor(endY)
if nColour then
term.setBackgroundColor( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal( startX, startY )
return
end
local minX = math.min( startX, endX )
local maxX, minY, maxY
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
for x=minX,maxX do
drawPixelInternal( x, minY )
drawPixelInternal( x, maxY )
end
if (maxY - minY) >= 2 then
for y=(minY+1),(maxY-1) do
drawPixelInternal( minX, y )
drawPixelInternal( maxX, y )
end
end
end
function drawFilledBox( startX, startY, endX, endY, nColour )
if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end
if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end
if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end
if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end
if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end
startX = math.floor(startX)
startY = math.floor(startY)
endX = math.floor(endX)
endY = math.floor(endY)
if nColour then
term.setBackgroundColor( nColour )
end
if startX == endX and startY == endY then
drawPixelInternal( startX, startY )
return
end
local minX = math.min( startX, endX )
local maxX, minY, maxY
if minX == startX then
minY = startY
maxX = endX
maxY = endY
else
minY = endY
maxX = startX
maxY = startY
end
for x=minX,maxX do
for y=minY,maxY do
drawPixelInternal( x, y )
end
end
end
function drawImage( tImage, xPos, yPos )
if type( tImage ) ~= "table" then error( "bad argument #1 (expected table, got " .. type( tImage ) .. ")", 2 ) end
if type( xPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( xPos ) .. ")", 2 ) end
if type( yPos ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( yPos ) .. ")", 2 ) end
for y=1,#tImage do
local tLine = tImage[y]
for x=1,#tLine do
if tLine[x] > 0 then
term.setBackgroundColor( tLine[x] )
drawPixelInternal( x + xPos - 1, y + yPos - 1 )
end
end
end
end

View File

@@ -0,0 +1,66 @@
local function create( ... )
local tFns = table.pack(...)
local tCos = {}
for i = 1, tFns.n, 1 do
local fn = tFns[i]
if type( fn ) ~= "function" then
error( "bad argument #" .. i .. " (expected function, got " .. type( fn ) .. ")", 3 )
end
tCos[i] = coroutine.create(fn)
end
return tCos
end
local function runUntilLimit( _routines, _limit )
local count = #_routines
local living = count
local tFilters = {}
local eventData = { n = 0 }
while true do
for n=1,count do
local r = _routines[n]
if r then
if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then
local ok, param = coroutine.resume( r, table.unpack( eventData, 1, eventData.n ) )
if not ok then
error( param, 0 )
else
tFilters[r] = param
end
if coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
end
end
for n=1,count do
local r = _routines[n]
if r and coroutine.status( r ) == "dead" then
_routines[n] = nil
living = living - 1
if living <= _limit then
return n
end
end
end
eventData = table.pack( os.pullEventRaw() )
end
end
function waitForAny( ... )
local routines = create( ... )
return runUntilLimit( routines, #routines - 1 )
end
function waitForAll( ... )
local routines = create( ... )
runUntilLimit( routines, 0 )
end

View File

@@ -0,0 +1,124 @@
local native = peripheral
function getNames()
local tResults = {}
for n,sSide in ipairs( rs.getSides() ) do
if native.isPresent( sSide ) then
table.insert( tResults, sSide )
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
local tRemote = native.call( sSide, "getNamesRemote" )
for n,sName in ipairs( tRemote ) do
table.insert( tResults, sName )
end
end
end
end
return tResults
end
function isPresent( _sSide )
if type( _sSide ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 )
end
if native.isPresent( _sSide ) then
return true
end
for n,sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return true
end
end
end
return false
end
function getType( _sSide )
if type( _sSide ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 )
end
if native.isPresent( _sSide ) then
return native.getType( _sSide )
end
for n,sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "getTypeRemote", _sSide )
end
end
end
return nil
end
function getMethods( _sSide )
if type( _sSide ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 )
end
if native.isPresent( _sSide ) then
return native.getMethods( _sSide )
end
for n,sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "getMethodsRemote", _sSide )
end
end
end
return nil
end
function call( _sSide, _sMethod, ... )
if type( _sSide ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 )
end
if type( _sSide ) ~= "string" then
error( "bad argument #2 (expected string, got " .. type( _sMethod ) .. ")", 2 )
end
if native.isPresent( _sSide ) then
return native.call( _sSide, _sMethod, ... )
end
for n,sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "callRemote", _sSide, _sMethod, ... )
end
end
end
return nil
end
function wrap( _sSide )
if type( _sSide ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 )
end
if peripheral.isPresent( _sSide ) then
local tMethods = peripheral.getMethods( _sSide )
local tResult = {}
for n,sMethod in ipairs( tMethods ) do
tResult[sMethod] = function( ... )
return peripheral.call( _sSide, sMethod, ... )
end
end
return tResult
end
return nil
end
function find( sType, fnFilter )
if type( sType ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sType ) .. ")", 2 )
end
if fnFilter ~= nil and type( fnFilter ) ~= "function" then
error( "bad argument #2 (expected function, got " .. type( fnFilter ) .. ")", 2 )
end
local tResults = {}
for n,sName in ipairs( peripheral.getNames() ) do
if peripheral.getType( sName ) == sType then
local wrapped = peripheral.wrap( sName )
if fnFilter == nil or fnFilter( sName, wrapped ) then
table.insert( tResults, wrapped )
end
end
end
return table.unpack( tResults )
end

View File

@@ -0,0 +1,289 @@
CHANNEL_BROADCAST = 65535
CHANNEL_REPEAT = 65533
local tReceivedMessages = {}
local tReceivedMessageTimeouts = {}
local tHostnames = {}
function open( sModem )
if type( sModem ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sModem ) .. ")", 2 )
end
if peripheral.getType( sModem ) ~= "modem" then
error( "No such modem: "..sModem, 2 )
end
peripheral.call( sModem, "open", os.getComputerID() )
peripheral.call( sModem, "open", CHANNEL_BROADCAST )
end
function close( sModem )
if sModem then
-- Close a specific modem
if type( sModem ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sModem ) .. ")", 2 )
end
if peripheral.getType( sModem ) ~= "modem" then
error( "No such modem: "..sModem, 2 )
end
peripheral.call( sModem, "close", os.getComputerID() )
peripheral.call( sModem, "close", CHANNEL_BROADCAST )
else
-- Close all modems
for n,sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
close( sModem )
end
end
end
end
function isOpen( sModem )
if sModem then
-- Check if a specific modem is open
if type( sModem ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sModem ) .. ")", 2 )
end
if peripheral.getType( sModem ) == "modem" then
return peripheral.call( sModem, "isOpen", os.getComputerID() ) and peripheral.call( sModem, "isOpen", CHANNEL_BROADCAST )
end
else
-- Check if any modem is open
for n,sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
return true
end
end
end
return false
end
function send( nRecipient, message, sProtocol )
if type( nRecipient ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( nRecipient ) .. ")", 2 )
end
if sProtocol ~= nil and type( sProtocol ) ~= "string" then
error( "bad argument #3 (expected string, got " .. type( sProtocol ) .. ")", 2 )
end
-- Generate a (probably) unique message ID
-- We could do other things to guarantee uniqueness, but we really don't need to
-- Store it to ensure we don't get our own messages back
local nMessageID = math.random( 1, 2147483647 )
tReceivedMessages[ nMessageID ] = true
tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = nMessageID
-- Create the message
local nReplyChannel = os.getComputerID()
local tMessage = {
nMessageID = nMessageID,
nRecipient = nRecipient,
message = message,
sProtocol = sProtocol,
}
local sent = false
if nRecipient == os.getComputerID() then
-- Loopback to ourselves
os.queueEvent( "rednet_message", nReplyChannel, message, sProtocol )
sent = true
else
-- Send on all open modems, to the target and to repeaters
for n,sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
peripheral.call( sModem, "transmit", nRecipient, nReplyChannel, tMessage );
peripheral.call( sModem, "transmit", CHANNEL_REPEAT, nReplyChannel, tMessage );
sent = true
end
end
end
return sent
end
function broadcast( message, sProtocol )
if sProtocol ~= nil and type( sProtocol ) ~= "string" then
error( "bad argument #2 (expected string, got " .. type( sProtocol ) .. ")", 2 )
end
send( CHANNEL_BROADCAST, message, sProtocol )
end
function receive( sProtocolFilter, nTimeout )
-- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
if type(sProtocolFilter) == "number" and nTimeout == nil then
sProtocolFilter, nTimeout = nil, sProtocolFilter
end
if sProtocolFilter ~= nil and type( sProtocolFilter ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sProtocolFilter ) .. ")", 2 )
end
if nTimeout ~= nil and type( nTimeout ) ~= "number" then
error( "bad argument #2 (expected number, got " .. type( nTimeout ) .. ")", 2 )
end
-- Start the timer
local timer = nil
local sFilter = nil
if nTimeout then
timer = os.startTimer( nTimeout )
sFilter = nil
else
sFilter = "rednet_message"
end
-- Wait for events
while true do
local sEvent, p1, p2, p3 = os.pullEvent( sFilter )
if sEvent == "rednet_message" then
-- Return the first matching rednet_message
local nSenderID, message, sProtocol = p1, p2, p3
if sProtocolFilter == nil or sProtocol == sProtocolFilter then
return nSenderID, message, sProtocol
end
elseif sEvent == "timer" then
-- Return nil if we timeout
if p1 == timer then
return nil
end
end
end
end
function host( sProtocol, sHostname )
if type( sProtocol ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sProtocol ) .. ")", 2 )
end
if type( sHostname ) ~= "string" then
error( "bad argument #2 (expected string, got " .. type( sHostname ) .. ")", 2 )
end
if sHostname == "localhost" then
error( "Reserved hostname", 2 )
end
if tHostnames[ sProtocol ] ~= sHostname then
if lookup( sProtocol, sHostname ) ~= nil then
error( "Hostname in use", 2 )
end
tHostnames[ sProtocol ] = sHostname
end
end
function unhost( sProtocol )
if type( sProtocol ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sProtocol ) .. ")", 2 )
end
tHostnames[ sProtocol ] = nil
end
function lookup( sProtocol, sHostname )
if type( sProtocol ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sProtocol ) .. ")", 2 )
end
if sHostname ~= nil and type( sHostname ) ~= "string" then
error( "bad argument #2 (expected string, got " .. type( sHostname ) .. ")", 2 )
end
-- Build list of host IDs
local tResults = nil
if sHostname == nil then
tResults = {}
end
-- Check localhost first
if tHostnames[ sProtocol ] then
if sHostname == nil then
table.insert( tResults, os.getComputerID() )
elseif sHostname == "localhost" or sHostname == tHostnames[ sProtocol ] then
return os.getComputerID()
end
end
if not isOpen() then
if tResults then
return table.unpack( tResults )
end
return nil
end
-- Broadcast a lookup packet
broadcast( {
sType = "lookup",
sProtocol = sProtocol,
sHostname = sHostname,
}, "dns" )
-- Start a timer
local timer = os.startTimer( 2 )
-- Wait for events
while true do
local event, p1, p2, p3 = os.pullEvent()
if event == "rednet_message" then
-- Got a rednet message, check if it's the response to our request
local nSenderID, tMessage, sMessageProtocol = p1, p2, p3
if sMessageProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup response" then
if tMessage.sProtocol == sProtocol then
if sHostname == nil then
table.insert( tResults, nSenderID )
elseif tMessage.sHostname == sHostname then
return nSenderID
end
end
end
else
-- Got a timer event, check it's the end of our timeout
if p1 == timer then
break
end
end
end
if tResults then
return table.unpack( tResults )
end
return nil
end
local bRunning = false
function run()
if bRunning then
error( "rednet is already running", 2 )
end
bRunning = true
while bRunning do
local sEvent, p1, p2, p3, p4 = os.pullEventRaw()
if sEvent == "modem_message" then
-- Got a modem message, process it and add it to the rednet event queue
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
if isOpen( sModem ) and ( nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST ) then
if type( tMessage ) == "table" and tMessage.nMessageID then
if not tReceivedMessages[ tMessage.nMessageID ] then
tReceivedMessages[ tMessage.nMessageID ] = true
tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = tMessage.nMessageID
os.queueEvent( "rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol )
end
end
end
elseif sEvent == "rednet_message" then
-- Got a rednet message (queued from above), respond to dns lookup
local nSenderID, tMessage, sProtocol = p1, p2, p3
if sProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup" then
local sHostname = tHostnames[ tMessage.sProtocol ]
if sHostname ~= nil and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then
rednet.send( nSenderID, {
sType = "lookup response",
sHostname = sHostname,
sProtocol = tMessage.sProtocol,
}, "dns" )
end
end
elseif sEvent == "timer" then
-- Got a timer event, use it to clear the event queue
local nTimer = p1
local nMessage = tReceivedMessageTimeouts[ nTimer ]
if nMessage then
tReceivedMessageTimeouts[ nTimer ] = nil
tReceivedMessages[ nMessage ] = nil
end
end
end
end

View File

@@ -0,0 +1,103 @@
local tSettings = {}
function set( sName, value )
if type( sName ) ~= "string" then error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 ) end
local sValueTy = type(value)
if sValueTy ~= "number" and sValueTy ~= "string" and sValueTy ~= "boolean" and sValueTy ~= "table" then
error( "bad argument #2 (expected value, got " .. sValueTy .. ")", 2 )
end
if sValueTy == "table" then
-- Ensure value is serializeable
value = textutils.unserialize( textutils.serialize(value) )
end
tSettings[ sName ] = value
end
local copy
function copy( value )
if type(value) == "table" then
local result = {}
for k,v in pairs(value) do
result[k] = copy(v)
end
return result
else
return value
end
end
function get( sName, default )
if type(sName) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 )
end
local result = tSettings[ sName ]
if result ~= nil then
return copy(result)
else
return default
end
end
function unset( sName )
if type(sName) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 )
end
tSettings[ sName ] = nil
end
function clear()
tSettings = {}
end
function getNames()
local result = {}
for k,v in pairs( tSettings ) do
result[ #result + 1 ] = k
end
table.sort(result)
return result
end
function load( sPath )
if type(sPath) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 )
end
local file = fs.open( sPath, "r" )
if not file then
return false
end
local sText = file.readAll()
file.close()
local tFile = textutils.unserialize( sText )
if type(tFile) ~= "table" then
return false
end
for k,v in pairs(tFile) do
if type(k) == "string" and
(type(v) == "string" or type(v) == "number" or type(v) == "boolean" or type(v) == "table") then
set( k, v )
end
end
return true
end
function save( sPath )
if type(sPath) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 )
end
local file = fs.open( sPath, "w" )
if not file then
return false
end
file.write( textutils.serialize( tSettings ) )
file.close()
return true
end

View File

@@ -0,0 +1,61 @@
local native = (term.native and term.native()) or term
local redirectTarget = native
local function wrap( _sFunction )
return function( ... )
return redirectTarget[ _sFunction ]( ... )
end
end
local term = {}
term.redirect = function( target )
if type( target ) ~= "table" then
error( "bad argument #1 (expected table, got " .. type( target ) .. ")", 2 )
end
if target == term then
error( "term is not a recommended redirect target, try term.current() instead", 2 )
end
for k,v in pairs( native ) do
if type( k ) == "string" and type( v ) == "function" then
if type( target[k] ) ~= "function" then
target[k] = function()
error( "Redirect object is missing method "..k..".", 2 )
end
end
end
end
local oldRedirectTarget = redirectTarget
redirectTarget = target
return oldRedirectTarget
end
term.current = function()
return redirectTarget
end
term.native = function()
-- NOTE: please don't use this function unless you have to.
-- If you're running in a redirected or multitasked enviorment, term.native() will NOT be
-- the current terminal when your program starts up. It is far better to use term.current()
return native
end
-- Some methods shouldn't go through redirects, so we move them to the main
-- term API.
for _, method in ipairs { "nativePaletteColor", "nativePaletteColour"} do
term[method] = native[method]
native[method] = nil
end
for k,v in pairs( native ) do
if type( k ) == "string" and type( v ) == "function" and term[k] == nil then
term[k] = wrap( k )
end
end
local env = _ENV
for k,v in pairs( term ) do
env[k] = v
end

View File

@@ -0,0 +1,455 @@
function slowWrite( sText, nRate )
if nRate ~= nil and type( nRate ) ~= "number" then
error( "bad argument #2 (expected number, got " .. type( nRate ) .. ")", 2 )
end
nRate = nRate or 20
if nRate < 0 then
error( "Rate must be positive", 2 )
end
local nSleep = 1 / nRate
sText = tostring( sText )
local x,y = term.getCursorPos()
local len = string.len( sText )
for n=1,len do
term.setCursorPos( x, y )
sleep( nSleep )
local nLines = write( string.sub( sText, 1, n ) )
local newX, newY = term.getCursorPos()
y = newY - nLines
end
end
function slowPrint( sText, nRate )
slowWrite( sText, nRate )
print()
end
function formatTime( nTime, bTwentyFourHour )
if type( nTime ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( nTime ) .. ")", 2 )
end
if bTwentyFourHour ~= nil and type( bTwentyFourHour ) ~= "boolean" then
error( "bad argument #2 (expected boolean, got " .. type( bTwentyFourHour ) .. ")", 2 )
end
local sTOD = nil
if not bTwentyFourHour then
if nTime >= 12 then
sTOD = "PM"
else
sTOD = "AM"
end
if nTime >= 13 then
nTime = nTime - 12
end
end
local nHour = math.floor(nTime)
local nMinute = math.floor((nTime - nHour)*60)
if sTOD then
return string.format( "%d:%02d %s", nHour, nMinute, sTOD )
else
return string.format( "%d:%02d", nHour, nMinute )
end
end
local function makePagedScroll( _term, _nFreeLines )
local nativeScroll = _term.scroll
local nFreeLines = _nFreeLines or 0
return function( _n )
for n=1,_n do
nativeScroll( 1 )
if nFreeLines <= 0 then
local w,h = _term.getSize()
_term.setCursorPos( 1, h )
_term.write( "Press any key to continue" )
os.pullEvent( "key" )
_term.clearLine()
_term.setCursorPos( 1, h )
else
nFreeLines = nFreeLines - 1
end
end
end
end
function pagedPrint( _sText, _nFreeLines )
if _nFreeLines ~= nil and type( _nFreeLines ) ~= "number" then
error( "bad argument #2 (expected number, got " .. type( _nFreeLines ) .. ")", 2 )
end
-- Setup a redirector
local oldTerm = term.current()
local newTerm = {}
for k,v in pairs( oldTerm ) do
newTerm[k] = v
end
newTerm.scroll = makePagedScroll( oldTerm, _nFreeLines )
term.redirect( newTerm )
-- Print the text
local result
local ok, err = pcall( function()
if _sText ~= nil then
result = print( _sText )
else
result = print()
end
end )
-- Removed the redirector
term.redirect( oldTerm )
-- Propogate errors
if not ok then
error( err, 0 )
end
return result
end
local function tabulateCommon( bPaged, ... )
local tAll = { ... }
for k,v in ipairs( tAll ) do
if type( v ) ~= "number" and type( v ) ~= "table" then
error( "bad argument #"..k.." (expected number or table, got " .. type( v ) .. ")", 3 )
end
end
local w,h = term.getSize()
local nMaxLen = w / 8
for n, t in ipairs( tAll ) do
if type(t) == "table" then
for nu, sItem in pairs(t) do
if type( sItem ) ~= "string" then
error( "bad argument #"..n.."."..nu.." (expected string, got " .. type( sItem ) .. ")", 3 )
end
nMaxLen = math.max( string.len( sItem ) + 1, nMaxLen )
end
end
end
local nCols = math.floor( w / nMaxLen )
local nLines = 0
local function newLine()
if bPaged and nLines >= (h-3) then
pagedPrint()
else
print()
end
nLines = nLines + 1
end
local function drawCols( _t )
local nCol = 1
for n, s in ipairs( _t ) do
if nCol > nCols then
nCol = 1
newLine()
end
local cx, cy = term.getCursorPos()
cx = 1 + ((nCol - 1) * nMaxLen)
term.setCursorPos( cx, cy )
term.write( s )
nCol = nCol + 1
end
print()
end
for n, t in ipairs( tAll ) do
if type(t) == "table" then
if #t > 0 then
drawCols( t )
end
elseif type(t) == "number" then
term.setTextColor( t )
end
end
end
function tabulate( ... )
tabulateCommon( false, ... )
end
function pagedTabulate( ... )
tabulateCommon( true, ... )
end
local g_tLuaKeywords = {
[ "and" ] = true,
[ "break" ] = true,
[ "do" ] = true,
[ "else" ] = true,
[ "elseif" ] = true,
[ "end" ] = true,
[ "false" ] = true,
[ "for" ] = true,
[ "function" ] = true,
[ "if" ] = true,
[ "in" ] = true,
[ "local" ] = true,
[ "nil" ] = true,
[ "not" ] = true,
[ "or" ] = true,
[ "repeat" ] = true,
[ "return" ] = true,
[ "then" ] = true,
[ "true" ] = true,
[ "until" ] = true,
[ "while" ] = true,
}
local function serializeImpl( t, tTracking, sIndent )
local sType = type(t)
if sType == "table" then
if tTracking[t] ~= nil then
error( "Cannot serialize table with recursive entries", 0 )
end
tTracking[t] = true
if next(t) == nil then
-- Empty tables are simple
return "{}"
else
-- Other tables take more work
local sResult = "{\n"
local sSubIndent = sIndent .. " "
local tSeen = {}
for k,v in ipairs(t) do
tSeen[k] = true
sResult = sResult .. sSubIndent .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
for k,v in pairs(t) do
if not tSeen[k] then
local sEntry
if type(k) == "string" and not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
sEntry = k .. " = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
else
sEntry = "[ " .. serializeImpl( k, tTracking, sSubIndent ) .. " ] = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
sResult = sResult .. sSubIndent .. sEntry
end
end
sResult = sResult .. sIndent .. "}"
return sResult
end
elseif sType == "string" then
return string.format( "%q", t )
elseif sType == "number" or sType == "boolean" or sType == "nil" then
return tostring(t)
else
error( "Cannot serialize type "..sType, 0 )
end
end
empty_json_array = {}
local function serializeJSONImpl( t, tTracking, bNBTStyle )
local sType = type(t)
if t == empty_json_array then
return "[]"
elseif sType == "table" then
if tTracking[t] ~= nil then
error( "Cannot serialize table with recursive entries", 0 )
end
tTracking[t] = true
if next(t) == nil then
-- Empty tables are simple
return "{}"
else
-- Other tables take more work
local sObjectResult = "{"
local sArrayResult = "["
local nObjectSize = 0
local nArraySize = 0
for k,v in pairs(t) do
if type(k) == "string" then
local sEntry
if bNBTStyle then
sEntry = tostring(k) .. ":" .. serializeJSONImpl( v, tTracking, bNBTStyle )
else
sEntry = string.format( "%q", k ) .. ":" .. serializeJSONImpl( v, tTracking, bNBTStyle )
end
if nObjectSize == 0 then
sObjectResult = sObjectResult .. sEntry
else
sObjectResult = sObjectResult .. "," .. sEntry
end
nObjectSize = nObjectSize + 1
end
end
for n,v in ipairs(t) do
local sEntry = serializeJSONImpl( v, tTracking, bNBTStyle )
if nArraySize == 0 then
sArrayResult = sArrayResult .. sEntry
else
sArrayResult = sArrayResult .. "," .. sEntry
end
nArraySize = nArraySize + 1
end
sObjectResult = sObjectResult .. "}"
sArrayResult = sArrayResult .. "]"
if nObjectSize > 0 or nArraySize == 0 then
return sObjectResult
else
return sArrayResult
end
end
elseif sType == "string" then
return string.format( "%q", t )
elseif sType == "number" or sType == "boolean" then
return tostring(t)
else
error( "Cannot serialize type "..sType, 0 )
end
end
function serialize( t )
local tTracking = {}
return serializeImpl( t, tTracking, "" )
end
function unserialize( s )
if type( s ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( s ) .. ")", 2 )
end
local func = load( "return "..s, "unserialize", "t", {} )
if func then
local ok, result = pcall( func )
if ok then
return result
end
end
return nil
end
function serializeJSON( t, bNBTStyle )
if type( t ) ~= "table" and type( t ) ~= "string" and type( t ) ~= "number" and type( t ) ~= "boolean" then
error( "bad argument #1 (expected table/string/number/boolean, got " .. type( t ) .. ")", 2 )
end
if bNBTStyle ~= nil and type( bNBTStyle ) ~= "boolean" then
error( "bad argument #2 (expected boolean, got " .. type( bNBTStyle ) .. ")", 2 )
end
local tTracking = {}
return serializeJSONImpl( t, tTracking, bNBTStyle or false )
end
function urlEncode( str )
if type( str ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( str ) .. ")", 2 )
end
if str then
str = string.gsub(str, "\n", "\r\n")
str = string.gsub(str, "([^A-Za-z0-9 %-%_%.])", function(c)
local n = string.byte(c)
if n < 128 then
-- ASCII
return string.format("%%%02X", n)
else
-- Non-ASCII (encode as UTF-8)
return
string.format("%%%02X", 192 + bit32.band( bit32.arshift(n,6), 31 ) ) ..
string.format("%%%02X", 128 + bit32.band( n, 63 ) )
end
end )
str = string.gsub(str, " ", "+")
end
return str
end
local tEmpty = {}
function complete( sSearchText, tSearchTable )
if type( sSearchText ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sSearchText ) .. ")", 2 )
end
if tSearchTable ~= nil and type( tSearchTable ) ~= "table" then
error( "bad argument #2 (expected table, got " .. type( tSearchTable ) .. ")", 2 )
end
if g_tLuaKeywords[sSearchText] then return tEmpty end
local nStart = 1
local nDot = string.find( sSearchText, ".", nStart, true )
local tTable = tSearchTable or _ENV
while nDot do
local sPart = string.sub( sSearchText, nStart, nDot - 1 )
local value = tTable[ sPart ]
if type( value ) == "table" then
tTable = value
nStart = nDot + 1
nDot = string.find( sSearchText, ".", nStart, true )
else
return tEmpty
end
end
local nColon = string.find( sSearchText, ":", nStart, true )
if nColon then
local sPart = string.sub( sSearchText, nStart, nColon - 1 )
local value = tTable[ sPart ]
if type( value ) == "table" then
tTable = value
nStart = nColon + 1
else
return tEmpty
end
end
local sPart = string.sub( sSearchText, nStart )
local nPartLength = string.len( sPart )
local tResults = {}
local tSeen = {}
while tTable do
for k,v in pairs( tTable ) do
if not tSeen[k] and type(k) == "string" then
if string.find( k, sPart, 1, true ) == 1 then
if not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
local sResult = string.sub( k, nPartLength + 1 )
if nColon then
if type(v) == "function" then
table.insert( tResults, sResult .. "(" )
elseif type(v) == "table" then
local tMetatable = getmetatable( v )
if tMetatable and ( type( tMetatable.__call ) == "function" or type( tMetatable.__call ) == "table" ) then
table.insert( tResults, sResult .. "(" )
end
end
else
if type(v) == "function" then
sResult = sResult .. "("
elseif type(v) == "table" and next(v) ~= nil then
sResult = sResult .. "."
end
table.insert( tResults, sResult )
end
end
end
end
tSeen[k] = true
end
local tMetatable = getmetatable( tTable )
if tMetatable and type( tMetatable.__index ) == "table" then
tTable = tMetatable.__index
else
tTable = nil
end
end
table.sort( tResults )
return tResults
end
-- GB versions
serialise = serialize
unserialise = unserialize
serialiseJSON = serializeJSON

View File

@@ -0,0 +1,34 @@
if not turtle then
error( "Cannot load turtle API on computer", 2 )
end
native = turtle.native or turtle
local function addCraftMethod( object )
if peripheral.getType( "left" ) == "workbench" then
object.craft = function( ... )
return peripheral.call( "left", "craft", ... )
end
elseif peripheral.getType( "right" ) == "workbench" then
object.craft = function( ... )
return peripheral.call( "right", "craft", ... )
end
else
object.craft = nil
end
end
-- Put commands into environment table
local env = _ENV
for k,v in pairs( native ) do
if k == "equipLeft" or k == "equipRight" then
env[k] = function( ... )
local result, err = v( ... )
addCraftMethod( turtle )
return result, err
end
else
env[k] = v
end
end
addCraftMethod( env )

View File

@@ -0,0 +1,85 @@
local vector = {
add = function( self, o )
return vector.new(
self.x + o.x,
self.y + o.y,
self.z + o.z
)
end,
sub = function( self, o )
return vector.new(
self.x - o.x,
self.y - o.y,
self.z - o.z
)
end,
mul = function( self, m )
return vector.new(
self.x * m,
self.y * m,
self.z * m
)
end,
div = function( self, m )
return vector.new(
self.x / m,
self.y / m,
self.z / m
)
end,
unm = function( self )
return vector.new(
-self.x,
-self.y,
-self.z
)
end,
dot = function( self, o )
return self.x*o.x + self.y*o.y + self.z*o.z
end,
cross = function( self, o )
return vector.new(
self.y*o.z - self.z*o.y,
self.z*o.x - self.x*o.z,
self.x*o.y - self.y*o.x
)
end,
length = function( self )
return math.sqrt( self.x*self.x + self.y*self.y + self.z*self.z )
end,
normalize = function( self )
return self:mul( 1 / self:length() )
end,
round = function( self, nTolerance )
nTolerance = nTolerance or 1.0
return vector.new(
math.floor( (self.x + (nTolerance * 0.5)) / nTolerance ) * nTolerance,
math.floor( (self.y + (nTolerance * 0.5)) / nTolerance ) * nTolerance,
math.floor( (self.z + (nTolerance * 0.5)) / nTolerance ) * nTolerance
)
end,
tostring = function( self )
return self.x..","..self.y..","..self.z
end,
}
local vmetatable = {
__index = vector,
__add = vector.add,
__sub = vector.sub,
__mul = vector.mul,
__div = vector.div,
__unm = vector.unm,
__tostring = vector.tostring,
}
function new( x, y, z )
local v = {
x = tonumber(x) or 0,
y = tonumber(y) or 0,
z = tonumber(z) or 0
}
setmetatable( v, vmetatable )
return v
end

View File

@@ -0,0 +1,480 @@
local tHex = {
[ colors.white ] = "0",
[ colors.orange ] = "1",
[ colors.magenta ] = "2",
[ colors.lightBlue ] = "3",
[ colors.yellow ] = "4",
[ colors.lime ] = "5",
[ colors.pink ] = "6",
[ colors.gray ] = "7",
[ colors.lightGray ] = "8",
[ colors.cyan ] = "9",
[ colors.purple ] = "a",
[ colors.blue ] = "b",
[ colors.brown ] = "c",
[ colors.green ] = "d",
[ colors.red ] = "e",
[ colors.black ] = "f",
}
local type = type
local string_rep = string.rep
local string_sub = string.sub
local table_unpack = table.unpack
function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
if type( parent ) ~= "table" then error( "bad argument #1 (expected table, got " .. type( parent ) .. ")", 2 ) end
if type( nX ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( nX ) .. ")", 2 ) end
if type( nY ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nY ) .. ")", 2 ) end
if type( nWidth ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( nWidth ) .. ")", 2 ) end
if type( nHeight ) ~= "number" then error( "bad argument #5 (expected number, got " .. type( nHeight ) .. ")", 2 ) end
if bStartVisible ~= nil and type( bStartVisible ) ~= "boolean" then error( "bad argument #6 (expected boolean, got " .. type( bStartVisible ) .. ")", 2 ) end
if parent == term then
error( "term is not a recommended window parent, try term.current() instead", 2 )
end
local sEmptySpaceLine
local tEmptyColorLines = {}
local function createEmptyLines( nWidth )
sEmptySpaceLine = string_rep( " ", nWidth )
for n=0,15 do
local nColor = 2^n
local sHex = tHex[nColor]
tEmptyColorLines[nColor] = string_rep( sHex, nWidth )
end
end
createEmptyLines( nWidth )
-- Setup
local bVisible = (bStartVisible ~= false)
local nCursorX = 1
local nCursorY = 1
local bCursorBlink = false
local nTextColor = colors.white
local nBackgroundColor = colors.black
local tLines = {}
local tPalette = {}
do
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
for y=1,nHeight do
tLines[y] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor,
}
end
for i=0,15 do
local c = 2 ^ i
tPalette[c] = { parent.getPaletteColour( c ) }
end
end
-- Helper functions
local function updateCursorPos()
if nCursorX >= 1 and nCursorY >= 1 and
nCursorX <= nWidth and nCursorY <= nHeight then
parent.setCursorPos( nX + nCursorX - 1, nY + nCursorY - 1 )
else
parent.setCursorPos( 0, 0 )
end
end
local function updateCursorBlink()
parent.setCursorBlink( bCursorBlink )
end
local function updateCursorColor()
parent.setTextColor( nTextColor )
end
local function redrawLine( n )
local tLine = tLines[ n ]
parent.setCursorPos( nX, nY + n - 1 )
parent.blit( tLine.text, tLine.textColor, tLine.backgroundColor )
end
local function redraw()
for n=1,nHeight do
redrawLine( n )
end
end
local function updatePalette()
for k,v in pairs( tPalette ) do
parent.setPaletteColour( k, v[1], v[2], v[3] )
end
end
local function internalBlit( sText, sTextColor, sBackgroundColor )
local nStart = nCursorX
local nEnd = nStart + #sText - 1
if nCursorY >= 1 and nCursorY <= nHeight then
if nStart <= nWidth and nEnd >= 1 then
-- Modify line
local tLine = tLines[ nCursorY ]
if nStart == 1 and nEnd == nWidth then
tLine.text = sText
tLine.textColor = sTextColor
tLine.backgroundColor = sBackgroundColor
else
local sClippedText, sClippedTextColor, sClippedBackgroundColor
if nStart < 1 then
local nClipStart = 1 - nStart + 1
local nClipEnd = nWidth - nStart + 1
sClippedText = string_sub( sText, nClipStart, nClipEnd )
sClippedTextColor = string_sub( sTextColor, nClipStart, nClipEnd )
sClippedBackgroundColor = string_sub( sBackgroundColor, nClipStart, nClipEnd )
elseif nEnd > nWidth then
local nClipEnd = nWidth - nStart + 1
sClippedText = string_sub( sText, 1, nClipEnd )
sClippedTextColor = string_sub( sTextColor, 1, nClipEnd )
sClippedBackgroundColor = string_sub( sBackgroundColor, 1, nClipEnd )
else
sClippedText = sText
sClippedTextColor = sTextColor
sClippedBackgroundColor = sBackgroundColor
end
local sOldText = tLine.text
local sOldTextColor = tLine.textColor
local sOldBackgroundColor = tLine.backgroundColor
local sNewText, sNewTextColor, sNewBackgroundColor
if nStart > 1 then
local nOldEnd = nStart - 1
sNewText = string_sub( sOldText, 1, nOldEnd ) .. sClippedText
sNewTextColor = string_sub( sOldTextColor, 1, nOldEnd ) .. sClippedTextColor
sNewBackgroundColor = string_sub( sOldBackgroundColor, 1, nOldEnd ) .. sClippedBackgroundColor
else
sNewText = sClippedText
sNewTextColor = sClippedTextColor
sNewBackgroundColor = sClippedBackgroundColor
end
if nEnd < nWidth then
local nOldStart = nEnd + 1
sNewText = sNewText .. string_sub( sOldText, nOldStart, nWidth )
sNewTextColor = sNewTextColor .. string_sub( sOldTextColor, nOldStart, nWidth )
sNewBackgroundColor = sNewBackgroundColor .. string_sub( sOldBackgroundColor, nOldStart, nWidth )
end
tLine.text = sNewText
tLine.textColor = sNewTextColor
tLine.backgroundColor = sNewBackgroundColor
end
-- Redraw line
if bVisible then
redrawLine( nCursorY )
end
end
end
-- Move and redraw cursor
nCursorX = nEnd + 1
if bVisible then
updateCursorColor()
updateCursorPos()
end
end
-- Terminal implementation
local window = {}
function window.write( sText )
sText = tostring( sText )
internalBlit( sText, string_rep( tHex[ nTextColor ], #sText ), string_rep( tHex[ nBackgroundColor ], #sText ) )
end
function window.blit( sText, sTextColor, sBackgroundColor )
if type( sText ) ~= "string" then error( "bad argument #1 (expected string, got " .. type( sText ) .. ")", 2 ) end
if type( sTextColor ) ~= "string" then error( "bad argument #2 (expected string, got " .. type( sTextColor ) .. ")", 2 ) end
if type( sBackgroundColor ) ~= "string" then error( "bad argument #3 (expected string, got " .. type( sBackgroundColor ) .. ")", 2 ) end
if #sTextColor ~= #sText or #sBackgroundColor ~= #sText then
error( "Arguments must be the same length", 2 )
end
internalBlit( sText, sTextColor, sBackgroundColor )
end
function window.clear()
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
for y=1,nHeight do
tLines[y] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor,
}
end
if bVisible then
redraw()
updateCursorColor()
updateCursorPos()
end
end
function window.clearLine()
if nCursorY >= 1 and nCursorY <= nHeight then
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
tLines[ nCursorY ] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor,
}
if bVisible then
redrawLine( nCursorY )
updateCursorColor()
updateCursorPos()
end
end
end
function window.getCursorPos()
return nCursorX, nCursorY
end
function window.setCursorPos( x, y )
if type( x ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( x ) .. ")", 2 ) end
if type( y ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( y ) .. ")", 2 ) end
nCursorX = math.floor( x )
nCursorY = math.floor( y )
if bVisible then
updateCursorPos()
end
end
function window.setCursorBlink( blink )
if type( blink ) ~= "boolean" then error( "bad argument #1 (expected boolean, got " .. type( blink ) .. ")", 2 ) end
bCursorBlink = blink
if bVisible then
updateCursorBlink()
end
end
function window.getCursorBlink()
return bCursorBlink
end
local function isColor()
return parent.isColor()
end
function window.isColor()
return isColor()
end
function window.isColour()
return isColor()
end
local function setTextColor( color )
if type( color ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( color ) .. ")", 2 )
elseif tHex[color] == nil then
error( "Invalid color (got " .. color .. ")" , 2 )
end
nTextColor = color
if bVisible then
updateCursorColor()
end
end
window.setTextColor = setTextColor
window.setTextColour = setTextColor
function window.setPaletteColour( colour, r, g, b )
if type( colour ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( colour ) .. ")", 2 ) end
if tHex[colour] == nil then
error( "Invalid color (got " .. colour .. ")" , 2 )
end
local tCol
if type(r) == "number" and g == nil and b == nil then
tCol = { colours.unpackRGB( r ) }
tPalette[ colour ] = tCol
else
if type( r ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( r ) .. ")", 2 ) end
if type( g ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( g ) .. ")", 2 ) end
if type( b ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( b ) .. ")", 2 ) end
tCol = tPalette[ colour ]
tCol[1] = r
tCol[2] = g
tCol[3] = b
end
if bVisible then
return parent.setPaletteColour( colour, tCol[1], tCol[2], tCol[3] )
end
end
window.setPaletteColor = window.setPaletteColour
function window.getPaletteColour( colour )
if type( colour ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( colour ) .. ")", 2 ) end
if tHex[colour] == nil then
error( "Invalid color (got " .. colour .. ")" , 2 )
end
local tCol = tPalette[ colour ]
return tCol[1], tCol[2], tCol[3]
end
window.getPaletteColor = window.getPaletteColour
local function setBackgroundColor( color )
if type( color ) ~= "number" then
error( "bad argument #1 (expected number, got " .. type( color ) .. ")", 2 )
elseif tHex[color] == nil then
error( "Invalid color (got " .. color .. ")", 2 )
end
nBackgroundColor = color
end
window.setBackgroundColor = setBackgroundColor
window.setBackgroundColour = setBackgroundColor
function window.getSize()
return nWidth, nHeight
end
function window.scroll( n )
if type( n ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( n ) .. ")", 2 ) end
if n ~= 0 then
local tNewLines = {}
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
for newY=1,nHeight do
local y = newY + n
if y >= 1 and y <= nHeight then
tNewLines[newY] = tLines[y]
else
tNewLines[newY] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor,
}
end
end
tLines = tNewLines
if bVisible then
redraw()
updateCursorColor()
updateCursorPos()
end
end
end
function window.getTextColor()
return nTextColor
end
function window.getTextColour()
return nTextColor
end
function window.getBackgroundColor()
return nBackgroundColor
end
function window.getBackgroundColour()
return nBackgroundColor
end
-- Other functions
function window.setVisible( bVis )
if type( bVis ) ~= "boolean" then error( "bad argument #1 (expected boolean, got " .. type( bVis ) .. ")", 2 ) end
if bVisible ~= bVis then
bVisible = bVis
if bVisible then
window.redraw()
end
end
end
function window.redraw()
if bVisible then
redraw()
updatePalette()
updateCursorBlink()
updateCursorColor()
updateCursorPos()
end
end
function window.restoreCursor()
if bVisible then
updateCursorBlink()
updateCursorColor()
updateCursorPos()
end
end
function window.getPosition()
return nX, nY
end
function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight )
if type( nNewX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( nNewX ) .. ")", 2 ) end
if type( nNewY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( nNewY ) .. ")", 2 ) end
if nNewWidth ~= nil or nNewHeight ~= nil then
if type( nNewWidth ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nNewWidth ) .. ")", 2 ) end
if type( nNewHeight ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( nNewHeight ) .. ")", 2 ) end
end
nX = nNewX
nY = nNewY
if nNewWidth and nNewHeight then
local tNewLines = {}
createEmptyLines( nNewWidth )
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
local sEmptyBackgroundColor = tEmptyColorLines[ nBackgroundColor ]
for y=1,nNewHeight do
if y > nHeight then
tNewLines[y] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor
}
else
local tOldLine = tLines[y]
if nNewWidth == nWidth then
tNewLines[y] = tOldLine
elseif nNewWidth < nWidth then
tNewLines[y] = {
text = string_sub( tOldLine.text, 1, nNewWidth ),
textColor = string_sub( tOldLine.textColor, 1, nNewWidth ),
backgroundColor = string_sub( tOldLine.backgroundColor, 1, nNewWidth ),
}
else
tNewLines[y] = {
text = tOldLine.text .. string_sub( sEmptyText, nWidth + 1, nNewWidth ),
textColor = tOldLine.textColor .. string_sub( sEmptyTextColor, nWidth + 1, nNewWidth ),
backgroundColor = tOldLine.backgroundColor .. string_sub( sEmptyBackgroundColor, nWidth + 1, nNewWidth ),
}
end
end
end
nWidth = nNewWidth
nHeight = nNewHeight
tLines = tNewLines
end
if bVisible then
window.redraw()
end
end
if bVisible then
window.redraw()
end
return window
end

View File

@@ -0,0 +1,4 @@
--[[
Alright then, don't ignore me. This file is to ensure the existence of the "autorun" folder, files placed in this folder
using resource packs will always run when computers startup.
]]

View File

@@ -0,0 +1 @@
adventure is a text adventure game for CraftOS. To navigate around the world of adventure, type simple instructions to the interpreter, for example: "go north", "punch tree", "craft planks", "mine coal with pickaxe", "hit creeper with sword"

View File

@@ -0,0 +1,6 @@
alias assigns shell commands to run other programs.
ex:
"alias dir ls" will make the "dir" command run the "ls" program
"alias dir" will remove the alias set on "dir"
"alias" will list all current aliases.

View File

@@ -0,0 +1,4 @@
apis lists the currently loaded APIs available to programs in CraftOS.
Type "help <api>" to see help for a specific api.
Call os.loadAPI( path ) to load extra apis.

View File

@@ -0,0 +1,5 @@
bg is a program for Advanced Computers which opens a new tab in the background.
ex:
"bg" will open a background tab running the shell
"bg worm" will open a background tab running the "worm" program

View File

@@ -0,0 +1,7 @@
Functions in the bit manipulation API (NOTE: This API will be removed in a future version. Use bit32 instead):
bit.bnot(n) -- bitwise not (~n)
bit.band(m, n) -- bitwise and (m & n)
bit.bor(m, n) -- bitwise or (m | n)
bit.bxor(m, n) -- bitwise xor (m ^ n)
bit.brshift(n, bits) -- right shift (n >> bits)
bit.blshift(n, bits) -- left shift (n << bits)

View File

@@ -0,0 +1,15 @@
To set bundled outputs:
c = colors.combine( colors.red, colors.blue )
rs.setBundledOutput( "left", c )
c = colors.combine( c, colors.green )
rs.setBundledOutput( "left", c )
c = colors.subtract( c, colors.blue )
rs.setBundledOutput( "left", c )
To get bundled inputs:
c = rs.getBundledInput( "right" )
red = colors.test( c, colors.red )
Type "help colors" for the list of wire colors.

View File

@@ -0,0 +1,6 @@
cd changes the directory you're in.
ex:
"cd rom" will move to "rom" folder.
"cd .." will move up one folder.
"cd /" will move to the root.

View File

@@ -0,0 +1,368 @@
New Features in ComputerCraft 1.80:
* Added .getResponseHeaders() to HTTP responses.
* Return a HTTP response when a HTTP error occurs.
* Added a GUI to change ComputerCraft config options.
* os.time() and os.day() now accept parameters to give the real world time.
* Added os.epoch()
* Monitor text now glows in the dark.
* Added a "Pocket Computer upgrade API" so mod developers can add their own pocket upgrades.
* Added pocket.equipBack()/pocket.unequipBack() to add/remove pocket upgrades.
* Added term.setPaletteColor()/term.getPaletteColor() to change/check colors
* Added colors.rgb8()/colours.rgb8()
* Performance improvements to fs.find
* Requires the player to be interacting with the computer when typing
* Disk labels are limited to 32 characters
* Labels can now only include characters within the printable range ( to ~)
* Various model improvements
* There is now a configurable file descriptor limit
* Threads are now daemon threads
* Termination signals are now sent unless the computer is off
* Fixed compilation errors
* Now handles tile entity changes
* GPS coordinates now have to be numbers
* Turtle upgrades now act as tools and peripherals
* The Filesystem.list result is now sorted
* The number of values to unpack can now be manually specified
* Small terminal & monitor rendering improvements
* General improvements to the documentation
* Redstone inputs are no longer reset when adding peripherals
* Turtles now use tinting
* shell.resolveProgram now picks up on *.lua files
* Fixed a handful of bugs in ComputerCraft
* Added speaker block, turtle upgrade, pocket upgrade, and peripheral api
* Startup can now be a directory containing multiple startup files
* Added .getLabel to the computer peripheral
New Features in ComputerCraft 1.79:
* Ported ComputerCraftEdu to Minecraft 1.8.9
* Fixed a handful of bugs in ComputerCraft
New Features in ComputerCraft 1.77:
* Ported to Minecraft 1.8.9
* Added "settings" API
* Added "set" and "wget" programs
* Added settings to disable multishell, startup scripts, and tab completion on a per-computer basis. The default values for these settings can be customised in ComputerCraft.cfg
* All Computer and Turtle items except Command Computers can now be mounted in Disk Drives
New Features in ComputerCraft 1.76:
* Ported to Minecraft 1.8
* Added Ender Modems for cross-dimensional communication
* Fixed handling of 8-bit characters. All the characters in the ISO 8859-1 codepage can now be displayed
* Added some extra graphical characters in the unused character positions, including a suite of characters for Teletext style drawing
* Added support for the new commands in Minecraft 1.8 to the Command Computer
* The return values of turtle.inspect() and commands.getBlockInfo() now include blockstate information
* Added commands.getBlockInfos() function for Command Computers
* Added new "peripherals" program
* Replaced the "_CC_VERSION" and "_MC_VERSION" constants with a new "_HOST" constant
* Shortened the length of time that "Ctrl+T", "Ctrl+S" and "Ctrl+R" must be held down for to terminate, shutdown and reboot the computer
* textutils.serialiseJSON() now takes an optional parameter allowing it to produce JSON text with unquoted object keys. This is used by all autogenerated methods in the "commands" api except for "title" and "tellraw"
* Fixed many bugs
New Features in ComputerCraft 1.75:
* Fixed monitors sometimes rendering without part of their text.
* Fixed a regression in the "bit" API.
New Features in ComputerCraft 1.74:
* Added tab completion to "edit", "lua" and the shell.
* Added textutils.complete(), fs.complete(), shell.complete(), shell.setCompletionFunction() and help.complete().
* Added tab completion options to read().
* Added "key_up" and "mouse_up" events.
* Non-advanced terminals now accept both grey colours.
* Added term.getTextColour(), term.getBackgroundColour() and term.blit().
* Improved the performance of text rendering on Advanced Computers.
* Added a "Run" button to the edit program on Advanced Computers.
* Turtles can now push players and entities (configurable).
* Turtles now respect server spawn protection (configurable).
* Added a turtle permissions API for mod authors.
* Implemented a subset of the Lua 5.2 API so programs can be written against it now, ahead of a future Lua version upgrade.
* Added a config option to disable parts of the Lua 5.1 API which will be removed when a future Lua version upgrade happens.
* Command Computers can no longer be broken by survival players.
* Fixed the "pick block" key not working on ComputerCraft items in creative mode.
* Fixed the "edit" program being hard to use on certain European keyboards.
* Added "_CC_VERSION" and "_MC_VERSION" constants.
New Features in ComputerCraft 1.73:
* The "exec" program, commands.exec() and all related Command Computer functions now return the console output of the command.
* Fixed two multiplayer crash bugs.
New Features in ComputerCraft 1.7:
* Added Command Computers
* Added new API: commands
* Added new programs: commands, exec
* Added textutils.serializeJSON()
* Added ILuaContext.executeMainThreadTask() for peripheral developers
* Disk Drives and Printers can now be renamed with Anvils
* Fixed various bugs, crashes and exploits
* Fixed problems with HD texture packs
* Documented the new features in the in-game help
New Features in ComputerCraft 1.65:
* Fixed a multiplayer-only crash with turtle.place()
* Fixed some problems with http.post()
* Fixed fs.getDrive() returning incorrect results on remote peripherals
New Features in ComputerCraft 1.64:
* Ported to Minecraft 1.7.10
* New turtle functions: turtle.inspect(), turtle.inspectUp(), turtle.inspectDown(), turtle.getItemDetail()
* Lots of bug and crash fixes, a huge stability improvement over previous versions
New Features in ComputerCraft 1.63:
* Turtles can now be painted with dyes, and cleaned with water buckets
* Added a new game: Redirection - ComputerCraft Edition
* Turtle label nameplates now only show when the Turtle is moused-over
* The HTTP API is now enabled by default, and can be configured with a whitelist of permitted domains
* http.get() and http.post() now accept parameters to control the request headers
* New fs function: fs.getDir( path )
* Fixed some bugs
New Features in ComputerCraft 1.62:
* Added IRC-style commands to the "chat" program
* Fixed some bugs and crashes
New Features in ComputerCraft 1.6:
* Added Pocket Computers
* Added a multi-tasking system for Advanced Computers and Turtles
* Turtles can now swap out their tools and peripherals at runtime
* Turtles can now carry two tools or peripherals at once in any combination
* Turtles and Computers can now be labelled using Name Tags and Anvils
* Added a configurable fuel limit for Turtles
* Added hostnames, protocols and long distance routing to the rednet API
* Added a peer-to-peer chat program to demonstrate new rednet capabilities
* Added a new game, only on Pocket Computers: "falling" by GopherATL
* File system commands in the shell now accept wildcard arguments
* The shell now accepts long arguments in quotes
* Terminal redirection now no longer uses a stack-based system. Instead: term.current() gets the current terminal object and term.redirect() replaces it. term.restore() has been removed.
* Added a new Windowing API for addressing sub-areas of the terminal
* New programs: fg, bg, multishell, chat, repeat, redstone, equip, unequip
* Improved programs: copy, move, delete, rename, paint, shell
* Removed programs: redset, redprobe, redpulse
* New APIs: window, multishell
* New turtle functions: turtle.equipLeft() and turtle.equipRight()
* New peripheral functions: peripheral.find( [type] )
* New rednet functions: rednet.host( protocol, hostname ), rednet.unhost( protocol ), rednet.locate( protocol, [hostname] )
* New fs function: fs.find( wildcard )
* New shell functions: shell.openTab(), shell.switchTab( [number] )
* New event "term_resize" fired when the size of a terminal changes
* Improved rednet functions: rednet.send(), rednet.broadcast() and rednet.receive() now take optional protocol parameters
* turtle.craft(0) and turtle.refuel(0) now return true if there is a valid recipe or fuel item, but do not craft of refuel anything
* turtle.suck( [limit] ) can now be used to limit the number of items picked up
* Users of turtle.dig() and turtle.attack() can now specify which side of the turtle to look for a tool to use (by default, both will be considered)
* textutils.serialise( text ) now produces human-readable output
* Refactored most of the codebase and fixed many old bugs and instabilities, turtles should never ever lose their content now
* Fixed the "turtle_inventory" event firing when it shouldn't have
* Added error messages to many more turtle functions after they return false
* Documented all new programs and API changes in the "help" system
New Features in ComputerCraft 1.58:
* Fixed a long standing bug where turtles could lose their identify if they travel too far away
* Fixed use of deprecated code, ensuring mod compatibility with the latest versions of Minecraft Forge, and world compatibility with future versions of Minecraft
New Features in ComputerCraft 1.57:
* Ported to Minecraft 1.6.4
* Added two new Treasure Disks: Conway's Game of Life by vilsol and Protector by fredthead
* Fixed a very nasty item duplication bug
New Features in ComputerCraft 1.56:
* Added Treasure Disks: Floppy Disks in dungeons which contain interesting community made programs. Find them all!
* All turtle functions now return additional error messages when they fail.
* Resource Packs with Lua Programs can now be edited when extracted to a folder, for easier editing.
New Features in ComputerCraft 1.55:
* Ported to Minecraft 1.6.2
* Added Advanced Turtles
* Added "turtle_inventory" event. Fires when any change is made to the inventory of a turtle
* Added missing functions io.close, io.flush, io.input, io.lines, io.output
* Tweaked the screen colours used by Advanced Computers, Monitors and Turtles
* Added new features for Peripheral authors
* Lua programs can now be included in Resource Packs
New Features in ComputerCraft 1.52:
* Ported to Minecraft 1.5.1
New Features in ComputerCraft 1.51:
* Ported to Minecraft 1.5
* Added Wired Modems
* Added Networking Cables
* Made Wireless Modems more expensive to craft
* New redstone API functions: getAnalogInput(), setAnalogOutput(), getAnalogOutput()
* Peripherals can now be controlled remotely over wired networks. New peripheral API function: getNames()
* New event: "monitor_resize" when the size of a monitor changes
* Except for labelled computers and turtles, ComputerCraft blocks no longer drop items in creative mode
* The pick block function works in creative mode now works for all ComputerCraft blocks
* All blocks and items now use the IDs numbers assigned by FTB by default
* Fixed turtles sometimes placing blocks with incorrect orientations
* Fixed Wireless modems being able to send messages to themselves
* Fixed turtle.attack() having a very short range
* Various bugfixes
New Features in ComputerCraft 1.5:
* Redesigned Wireless Modems; they can now send and receive on multiple channels, independent of the computer ID. To use these features, interface with modem peripherals directly. The rednet API still functions as before
* Floppy Disks can now be dyed with multiple dyes, just like armour
* The "excavate" program now retains fuel in it's inventory, so can run unattended
* turtle.place() now tries all possible block orientations before failing
* turtle.refuel(0) returns true if a fuel item is selected
* turtle.craft(0) returns true if the inventory is a valid recipe
* The in-game help system now has documentation for all the peripherals and their methods, including the new modem functionality
* A romantic surprise
New Features in ComputerCraft 1.48:
* Ported to Minecraft 1.4.6
* Advanced Monitors now emit a "monitor_touch" event when right clicked
* Advanced Monitors are now cheaper to craft
* Turtles now get slightly less fuel from items
* Computers can now interact with Command Blocks (if enabled in ComputerCraft.cfg)
* New API function: os.day()
* A christmas surprise
New Features in ComputerCraft 1.45:
* Added Advanced Computers
* Added Advanced Monitors
* New program: paint by nitrogenfingers
* New API: paintutils
* New term functions: term.setBackgroundColor, term.setTextColor, term.isColor
* New turtle function: turtle.transferTo
New Features in ComputerCraft 1.43:
* Added Printed Pages
* Added Printed Books
* Fixed incompatibility with Forge 275 and above
* Labelled Turtles now keep their fuel when broken
New Features in ComputerCraft 1.42:
* Ported to Minecraft 1.3.2
* Added Printers
* Floppy Disks can be dyed different colours
* Wireless Crafty Turtles can now be crafted
* New textures
* New forge config file
* Bug fixes
New Features in ComputerCraft 1.4:
* Ported to Forge Mod Loader. ComputerCraft can now be ran directly from the .zip without extraction
* Added Farming Turtles
* Added Felling Turtles
* Added Digging Turtles
* Added Melee Turtles
* Added Crafty Turtles
* Added 14 new Turtle Combinations accessible by combining the turtle upgrades above
* Labelled computers and turtles can now be crafted into turtles or other turtle types without losing their ID, label and data
* Added a "Turtle Upgrade API" for mod developers to create their own tools and peripherals for turtles
* Turtles can now attack entities with turtle.attack(), and collect their dropped items
* Turtles can now use turtle.place() with any item the player can, and can interact with entities
* Turtles can now craft items with turtle.craft()
* Turtles can now place items into inventories with turtle.drop()
* Changed the behaviour of turtle.place() and turtle.drop() to only consider the currently selected slot
* Turtles can now pick up items from the ground, or from inventories, with turtle.suck()
* Turtles can now compare items in their inventories
* Turtles can place signs with text on them with turtle.place( [signText] )
* Turtles now optionally require fuel items to move, and can refuel themselves
* The size of the the turtle inventory has been increased to 16
* The size of the turtle screen has been increased
* New turtle functions: turtle.compareTo( [slotNum] ), turtle.craft(), turtle.attack(), turtle.attackUp(), turtle.attackDown(), turtle.dropUp(), turtle.dropDown(), turtle.getFuelLevel(), turtle.refuel()
* New disk function: disk.getID()
* New turtle programs: craft, refuel
* "excavate" program now much smarter: Will return items to a chest when full, attack mobs, and refuel itself automatically
* New API: keys
* Added optional Floppy Disk and Hard Drive space limits for computers and turtles
* New fs function: fs.getFreeSpace( path ), also fs.getDrive() works again
* The send and receive range of wireless modems now increases with altitude, allowing long range networking from high-altitude computers (great for GPS networks)
* http.request() now supports https:// URLs
* Right clicking a Disk Drive with a Floppy Disk or a Record when sneaking will insert the item into the Disk Drive automatically
* The default size of the computer screen has been increased
* Several stability and security fixes. LuaJ can now no longer leave dangling threads when a computer is unloaded, turtles can no longer be destroyed by tree leaves or walking off the edge of the loaded map. Computers no longer crash when used with RedPower frames.
New Features in ComputerCraft 1.31:
* Ported to Minecraft 1.2.3
* Added Monitors (thanks to Cloudy)
* Updated LuaJ to a newer, less memory hungry version
* rednet_message event now has a third parameter, "distance", to support position triangulation.
* New programs: gps, monitor, pastebin.
* Added a secret program. Use with large monitors!
* New apis: gps, vector
* New turtle functions: turtle.compare(), turtle.compareUp(), turtle.compareDown(), turtle.drop( quantity )
* New http functions: http.post().
* New term functions: term.redirect(), term.restore()
* New textutils functions: textutils.urlEncode()
* New rednet functions: rednet.isOpen()
* New config options: modem_range, modem_rangeDuringStorm
* Bug fixes, program tweaks, and help updates
New Features in ComputerCraft 1.3:
* Ported to Minecraft Forge
* Added Turtles
* Added Wireless Modems
* Added Mining Turtles
* Added Wireless Turtles
* Added Wireless Mining Turtles
* Computers and Disk Drives no longer get destroyed by water.
* Computers and Turtles can now be labelled with the label program, and labelled devices keep their state when destroyed.
* Computers/Turtles can connect to adjacent devices, and turn them on and off
* User programs now give line numbers in their error messages
* New APIs: turtle, peripheral
* New programs for turtles: tunnel, excavate, go, turn, dance
* New os functions: os.getComputerLabel(), os.setComputerLabel()
* Added "filter" parameter to os.pullEvent()
* New shell function: shell.getCurrentProgram()
* New textutils functions: textutils.serialize(), textutils.unserialize(), textutils.tabulate(), textutils.pagedTabulate(), textutils.slowWrite()
* New io file function: file:lines()
* New fs function: fs.getSize()
* Disk Drives can now play records from other mods
* Bug fixes, program tweaks, and help updates
New Features in ComputerCraft 1.2:
* Added Disk Drives and Floppy Disks
* Added Ctrl+T shortcut to terminate the current program (hold)
* Added Ctrl+S shortcut to shutdown the computer (hold)
* Added Ctrl+R shortcut to reboot the computer (hold)
* New Programs: alias, apis, copy, delete, dj, drive, eject, id, label, list, move, reboot, redset, rename, time, worm.
* New APIs: bit, colours, disk, help, rednet, parallel, textutils.
* New color functions: colors.combine(), colors.subtract(), colors.test()
* New fs functions: fs.getName(), new modes for fs.open()
* New os functions: os.loadAPI(), os.unloadAPI(),
os.clock(), os.time(), os.setAlarm(),
os.reboot(), os.queueEvent()
* New redstone function: redstone.getSides()
* New shell functions: shell.setPath(), shell.programs(), shell.resolveProgram(), shell.setAlias()
* Lots of updates to the help pages
* Bug fixes
New Features in ComputerCraft 1.1:
* Added Multiplayer support throughout.
* Added connectivity with RedPower bundled cables
* Added HTTP api, enabled via the mod config, to allow computers to access the real world internet
* Added command history to the shell.
* Programs which spin in an infinite loop without yielding will no longer freeze minecraft
* Help updates and bug fixes
New Features in ComputerCraft 1.0:
* First Release!

View File

@@ -0,0 +1,5 @@
Surf the rednet superhighway with "chat", the networked chat program for CraftOS! Host chatrooms and invite your friends! Requires a Wired or Wireless Modem on each computer. When running chat, type "/help" to see a list of available commands.
ex:
"chat host forgecraft" will create a chatroom with the name "forgecraft"
"chat join forgecraft direwolf20" will connect to the chatroom with the name "forgecraft", using the nickname "direwolf20"

View File

@@ -0,0 +1 @@
clear clears the screen.

View File

@@ -0,0 +1,9 @@
Functions in the colors api
(used for redstone.setBundledOutput):
colors.combine( color1, color2, color3, ... )
colors.subtract( colors, color1, color2, ... )
colors.test( colors, color )
colors.rgb8( r, g, b )
Color constants in the colors api, in ascending bit order:
colors.white, colors.orange, colors.magenta, colors.lightBlue, colors.yellow, colors.lime, colors.pink, colors.gray, colors.lightGray, colors.cyan, colors.purple, colors.blue, colors.brown, colors.green, colors.red, colors.black.

View File

@@ -0,0 +1,9 @@
Functions in the colours api
(used for redstone.setBundledOutput):
colours.combine( colour1, colour2, colour3, ...)
colours.subtract( colours, colour1, colour2, ...)
colours.test( colours, colour )
colours.rgb8( r, g, b )
Colour constants in the colours api, in ascending bit order:
colours.white, colours.orange, colours.magenta, colours.lightBlue, colours.yellow, colours.lime, colours.pink, colours.grey, colours.lightGrey, colours.cyan, colours.purple, colours.blue, colours.brown, colours.green, colours.red, colours.black.

View File

@@ -0,0 +1,2 @@
On a Command Computer, "commands" will list all the commands available for use. Use "exec" to execute them.
Type "help commandsapi" for help using commands in lua programs.

View File

@@ -0,0 +1,15 @@
Functions in the commands API:
commands.exec( command )
commands.execAsync( command )
commands.list()
commands.getBlockPosition()
commands.getBlockInfo( x, y, z )
commands.getBlockInfos( minx, miny, minz, maxx, maxy, maxz )
The commands API can also be used to invoke commands directly, like so:
commands.say( "Hello World" )
commands.give( "dan200", "minecraft:diamond", 64 )
This works with any command. Use "commands.async" instead of "commands" to execute asynchronously.
The commands API is only available on Command Computers.
Visit http://minecraft.gamepedia.com/Commands for documentation on all commands.

View File

@@ -0,0 +1,6 @@
cp copies a file or directory from one location to another.
ex:
"cp rom myrom" copies "rom" to "myrom".
"cp rom mystuff/rom" copies "rom" to "mystuff/rom".
"cp disk/* disk2" copies the contents of one disk to another

View File

@@ -0,0 +1,2 @@
coroutine is a standard Lua5.1 API.
Refer to http://www.lua.org/manual/5.1/ for more information.

View File

@@ -0,0 +1,5 @@
craft is a program for Crafty Turtles. Craft will craft a stack of items using the current inventory.
ex:
"craft" will craft as many items as possible
"craft 5" will craft at most 5 times

View File

@@ -0,0 +1,16 @@
ComputerCraft was created by Daniel "dan200" Ratcliffe, with additional code by Aaron "Cloudy" Mills.
Thanks to nitrogenfingers, GopherATL and RamiLego for program contributions.
Thanks to Mojang, the Forge team, and the MCP team.
Uses LuaJ from http://luaj.sourceforge.net/
The ComputerCraft 1.76 update was sponsored by MinecraftU and Deep Space.
Visit http://www.minecraftu.org and http://www.deepspace.me/space-cadets to find out more.
Join the ComputerCraft community online at http://www.computercraft.info
Follow @DanTwoHundred on Twitter!
To help contribute to ComputerCraft, browse the source code at https://github.com/dan200/ComputerCraft.
GitHub Contributors:
${gitcontributors}

View File

@@ -0,0 +1 @@
dance is a program for Turtles. Turtles love to get funky.

View File

@@ -0,0 +1,5 @@
rm deletes a file or a directory and its contents.
ex:
"rm foo" will delete the file foo.
"rm disk/*" will delete the contents of a disk.

View File

@@ -0,0 +1,17 @@
Functions in the disk API. These functions are for interacting with disk drives:
disk.isPresent( drive )
disk.setLabel( drive, label )
disk.getLabel( drive )
disk.hasData( drive )
disk.getMountPath( drive )
disk.hasAudio( drive )
disk.getAudioTitle( drive )
disk.playAudio( drive )
disk.stopAudio( )
disk.eject( drive )
disk.getID( drive )
Events fired by the disk API:
"disk" when a disk or other item is inserted into a disk drive. Argument is the name of the drive
"disk_eject" when a disk is removed from a disk drive. Argument is the name of the drive
Type "help events" to learn about the event system.

View File

@@ -0,0 +1,6 @@
dj plays Music Discs from disk drives attached to the computer.
ex:
"dj" or "dj play" plays a random disc.
"dj play left" plays the disc in the drive on the left of the computer.
"dj stop" stops the current disc.

View File

@@ -0,0 +1,5 @@
drive tells you which disk drive the current or specified directory is located in.
ex:
"drive" tell you the disk drive of the current directory.
"drive foo" tells you the disk drive of the subdirectory "foo"

View File

@@ -0,0 +1,19 @@
The Disk Drive is a peripheral device available for CraftOS. Type "help peripheral" to learn about using the Peripheral API to connect with peripherals. When a Disk Drive is connected, peripheral.getType() will return "drive".
Methods exposed by the Disk Drive:
isDiskPresent()
getDiskLabel()
setDiskLabel( label )
hasData()
getMountPath()
hasAudio()
getAudioTitle()
playAudio()
stopAudio()
ejectDisk()
getDiskID()
Events fired by the Disk Drive:
"disk" when a disk or other item is inserted into the drive. Argument is the name of the drive.
"disk_eject" when a disk is removed from a drive. Argument is the name of the drive.
Type "help events" to learn about the event system.

View File

@@ -0,0 +1 @@
Mostly harmless.

View File

@@ -0,0 +1,4 @@
edit is a text editor for creating or modifying programs or text files. After creating a program with edit, type its filename in the shell to run it. You can open any of the builtin programs with edit to learn how to program.
ex:
"edit hello" opens a file called "hello" for editing.

View File

@@ -0,0 +1,4 @@
eject ejects the contents of an attached disk drive.
ex:
"eject left" ejects the contents of the disk drive to the left of the computer.

View File

@@ -0,0 +1,5 @@
equip is a program for Turtles and Pocket Computer. equip will equip an item from the Turtle's inventory for use as a tool of peripheral. On a Pocket Computer you don't need to write a side.
ex:
"equip 5 left" will equip the item from slot 5 of the turtle onto the left side of the turtle
"equip" on a Pocket Computer will equip the first item from your inventory.

View File

@@ -0,0 +1,15 @@
The function os.pullEvent() will yield the program until a system event occurs. The first return value is the event name, followed by any arguments.
Some events which can occur are:
"char" when text is typed on the keyboard. Argument is the character typed.
"key" when a key is pressed on the keyboard. Arguments are the keycode and whether the key is a repeat. Compare the keycode to the values in keys API to see which key was pressed.
"key_up" when a key is released on the keyboard. Argument is the numerical keycode. Compare to the values in keys API to see which key was released.
"paste" when text is pasted from the users keyboard. Argument is the line of text pasted.
Events only on advanced computers:
"mouse_click" when a user clicks the mouse. Arguments are button, xPos, yPos.
"mouse_drag" when a user moves the mouse when held. Arguments are button, xPos, yPos.
"mouse_up" when a user releases the mouse button. Arguments are button, xPos, yPos.
"mouse_scroll" when a user uses the scrollwheel on the mouse. Arguments are direction, xPos, yPos.
Other APIs and peripherals will emit their own events. See their respective help pages for details.

View File

@@ -0,0 +1,4 @@
excavate is a program for Mining Turtles. When excavate is run, the turtle will mine a rectangular shaft into the ground, collecting blocks as it goes, and return to the surface once bedrock is hit.
ex:
"excavate 3" will mine a 3x3 shaft.

View File

@@ -0,0 +1,7 @@
On a Command Computer, "exec" will execute a command as if entered on a command block. Use "commands" to list all the available commands.
ex:
"exec say Hello World"
"exec setblock ~0 ~1 ~0 minecraft:dirt"
Type "help commandsapi" for help using commands in lua programs.

View File

@@ -0,0 +1 @@
exit will exit the current shell.

View File

@@ -0,0 +1 @@
"From Russia with Fun" comes a fun, new, suspiciously-familiar falling block game for CraftOS. Only on Pocket Computers!

View File

@@ -0,0 +1,5 @@
fg is a program for Advanced Computers which opens a new tab in the foreground.
ex:
"fg" will open a foreground tab running the shell
"fg worm" will open a foreground tab running the "worm" program

View File

@@ -0,0 +1,40 @@
Functions in the Filesystem API:
fs.list( path )
fs.find( wildcard )
fs.exists( path )
fs.isDir( path )
fs.isReadOnly( path )
fs.getDir( path )
fs.getName( path )
fs.getSize( path )
fs.getDrive( path )
fs.getFreeSpace( path )
fs.makeDir( path )
fs.move( path, path )
fs.copy( path, path )
fs.delete( path )
fs.combine( path, localpath )
fs.open( path, mode )
fs.complete( path, location )
Available fs.open() modes are "r", "w", "a", "rb", "wb" and "ab".
Functions on files opened with mode "r":
readLine()
readAll()
close()
read( number )
Functions on files opened with mode "w" or "a":
write( string )
writeLine( string )
flush()
close()
Functions on files opened with mode "rb":
read()
close()
Functions on files opened with mode "wb" or "ab":
write( byte )
flush()
close()

View File

@@ -0,0 +1,6 @@
go is a program for Turtles, used to control the turtle without programming. It accepts one or more commands as a direction followed by a distance.
ex:
"go forward" moves the turtle 1 space forward.
"go forward 3" moves the turtle 3 spaces forward.
"go forward 3 up left 2" moves the turtle 3 spaces forward, 1 spaces up, then left 180 degrees.

View File

@@ -0,0 +1,10 @@
gps can be used to host a GPS server, or to determine a position using trilateration.
Type "help gpsapi" for help using GPS functions in lua programs.
ex:
"gps locate" will connect to nearby GPS servers, and try to determine the position of the computer or turtle.
"gps host" will try to determine the position, and host a GPS server if successful.
"gps host 10 20 30" will host a GPS server, using the manually entered position 10,20,30.
Take care when manually entering host positions. If the positions entered into multiple GPS hosts
are not consistent, the results of locate calls will be incorrect.

View File

@@ -0,0 +1,4 @@
Functions in the GPS API:
gps.locate( timeout )
The locate function will send a signal to nearby gps servers, and wait for responses before the timeout. If it receives enough responses to determine this computers position then x, y and z co-ordinates will be returned, otherwise it will return nil. If GPS hosts do not have their positions configured correctly, results will be inaccurate.

View File

@@ -0,0 +1 @@
hello prints the text "Hello World!" to the screen.

View File

@@ -0,0 +1,4 @@
help is the help tool you're currently using.
Type "help index" to see all help topics.
Type "help" to see the help intro.
Type "help helpapi" for information on the help Lua API.

View File

@@ -0,0 +1,5 @@
Functions in the help API:
help.setPath( path )
help.lookup( topic )
help.topics()
help.completeTopic( topic )

View File

@@ -0,0 +1,9 @@
Functions in the HTTP API:
http.checkURL( url )
http.checkURLAsync( url )
http.request( url, [postData], [headers] )
http.get( url, [headers] )
http.post( url, postData, [headers] )
The HTTP API may be disabled in ComputerCraft.cfg
A period of time after a http.request() call is made, a "http_success" or "http_failure" event will be raised. Arguments are the url and a file handle if successful. Arguments are nil, an error message, and (optionally) a file handle if the request failed. http.get() and http.post() block until this event fires instead.

View File

@@ -0,0 +1,5 @@
id prints the unique identifier of this computer, or a Disk in an attached Disk Drive.
ex:
"id" will print this Computers ID and label
"id left" will print the ID and label of the disk in the Disk Drive on the left

View File

@@ -0,0 +1,7 @@
Welcome to CraftOS!
Type "programs" to see the programs you can run.
Type "help <program>" to see help for a specific program.
Type "help programming" to learn about programming.
Type "help whatsnew" to find out about new features.
Type "help credits" to learn who made all this.
Type "help index" to see all help topics.

View File

@@ -0,0 +1,2 @@
io is a standard Lua5.1 API, reimplemented for CraftOS. Not all the features are availiable.
Refer to http://www.lua.org/manual/5.1/ for more information.

View File

@@ -0,0 +1,9 @@
The keys API contains constants for all the key codes that can be returned by the "key" event:
Example usage:
local sEvent, nKey = os.pullEvent()
if sEvent == "key" and nKey == keys.enter then
-- Do something
end
See http://www.minecraftwiki.net/wiki/Key_codes, or the source code, for a complete reference.

View File

@@ -0,0 +1,9 @@
label gets or sets the label of the Computer, or of Floppy Disks in attached disk drives.
ex:
"label get" prints the label of the computer.
"label get left" prints the label of the disk in the left drive.
"label set "My Computer"" set the label of the computer to "My Computer".
"label set left "My Programs"" - sets the label of the disk in the left drive to "My Programs".
"label clear" clears the label of the computer.
"label clear left" clears the label of the disk in the left drive.

View File

@@ -0,0 +1 @@
ls will list all the directories and files in the current location. Use "type" to find out if an item is a file or a directory.

View File

@@ -0,0 +1 @@
lua is an interactive prompt for the lua programming language. It's a useful tool for learning the language.

View File

@@ -0,0 +1,2 @@
math is a standard Lua5.1 API.
Refer to http://www.lua.org/manual/5.1/ for more information.

View File

@@ -0,0 +1,5 @@
mkdir creates a directory in the current location.
ex:
"mkdir foo" creates a directory named "foo".
"mkdir ../foo" creates a directory named "foo" in the directory above the current directory.

View File

@@ -0,0 +1,12 @@
Wired and Wireless Modems are peripheral devices available for CraftOS. Type "help peripheral" to learn about using the Peripheral API to connect with peripherals. When a Modem is connected, peripheral.getType() will return "modem".
Methods exposed by Modems:
open( channel )
isOpen( channel )
close( channel )
closeAll()
transmit( channel, replyChannel, message )
isWireless()
Events fired by Modems:
"modem_message" when a message is received on an open channel. Arguments are name, channel, replyChannel, message, distance

View File

@@ -0,0 +1,6 @@
monitor will connect to an attached Monitor peripheral, and run a program on its display.
Type "help monitors" for help using monitors as peripherals in lua programs.
ex:
"monitor left hello" will run the "hello" program on the monitor to the left of the computer.
"monitor top edit foo" will run the edit program on the top monitor, editing the file "foo".

View File

@@ -0,0 +1,23 @@
The Monitor is a peripheral device available for CraftOS. Type "help peripheral" to learn about using the Peripheral API to connect with peripherals. When a Monitor is connected, peripheral.getType() will return "monitor". A wrapped monitor can be used with term.redirect() to send all terminal output to the monitor.
Methods exposed by the Monitor:
write( text )
blit( text, textColor, backgroundColor )
clear()
clearLine()
getCursorPos()
setCursorPos( x, y )
setCursorBlink( blink )
isColor()
setTextColor( color )
setBackgroundColor( color )
getTextColor()
getBackgroundColor()
getSize()
scroll( n )
setPaletteColor( color, r, g, b )
getPaletteColor( color )
Events fired by the Monitor:
"monitor_touch" when an Advanced Monitor is touched by the player. Arguments are name, x, y
"monitor_resize" when the size of a Monitor changes. Argument is the name of the monitor.

View File

@@ -0,0 +1,6 @@
mv moves a file or directory from one location to another.
ex:
"mv foo bar" renames the file "foo" to "bar".
"mv foo bar/foo" moves the file "foo" to a folder called "bar".
"mv disk/* disk2" moves the contents of one disk to another

View File

@@ -0,0 +1,2 @@
multishell is the toplevel program on Advanced Computers which manages background tabs.
Type "help shellapi" for information about the shell lua api.

View File

@@ -0,0 +1,26 @@
Functions in the os (Operating System) API:
os.version()
os.getComputerID()
os.getComputerLabel()
os.setComputerLabel()
os.run( environment, programpath, arguments )
os.loadAPI( path )
os.unloadAPI( name )
os.pullEvent( [filter] )
os.queueEvent( event, arguments )
os.clock()
os.startTimer( timeout )
os.cancelTimer( token )
os.sleep( timeout )
os.time( [source] )
os.day( [source] )
os.epoch( [source] )
os.setAlarm( time )
os.cancelAlarm( token )
os.shutdown()
os.reboot()
Events emitted by the os API:
"timer" when a timeout started by os.startTimer() completes. Argument is the token returned by os.startTimer().
"alarm" when a time passed to os.setAlarm() is reached. Argument is the token returned by os.setAlarm().
Type "help events" to learn about the event system.

View File

@@ -0,0 +1,4 @@
paint is a program for creating images on Advanced Computers. Select colors from the color pallette on the right, and click on the canvas to draw. Press Ctrl to access the menu and save your pictures.
ex:
"edit mario" opens an image called "mario" for editing.

View File

@@ -0,0 +1,7 @@
Functions in the Paint Utilities API:
paintutils.drawPixel( x, y, colour )
paintutils.drawLine( startX, startY, endX, endY, colour )
paintutils.drawBox( startX, startY, endX, endY, colour )
paintutils.drawFilledBox( startX, startY, endX, endY, colour )
paintutils.loadImage( path )
paintutils.drawImage( image, x, y )

View File

@@ -0,0 +1,4 @@
Functions in the Parallel API:
parallel.waitForAny( function1, function2, ... )
parallel.waitForAll( function1, function2, ... )
These methods provide an easy way to run multiple lua functions simultaneously.

View File

@@ -0,0 +1,7 @@
pastebin is a program for uploading files to and downloading files from pastebin.com. This is useful for sharing programs with other players.
The HTTP API must be enabled in ComputerCraft.cfg to use this program.
ex:
"pastebin put foo" will upload the file "foo" to pastebin.com, and print the URL.
"pastebin get xq5gc7LB foo" will download the file from the URL http://pastebin.com/xq5gc7LB, and save it as "foo".
"pastebin run CxaWmPrX" will download the file from the URL http://pastebin.com/CxaWmPrX, and immediately run it.

View File

@@ -0,0 +1,15 @@
The peripheral API is for interacting with external peripheral devices. Type "help peripherals" to learn about the peripherals available.
Functions in the peripheral API:
peripheral.getNames()
peripheral.isPresent( name )
peripheral.getType( name )
peripheral.getMethods( name )
peripheral.call( name, methodName, param1, param2, etc )
peripheral.wrap( name )
peripheral.find( type, [fnFilter] )
Events fired by the peripheral API:
"peripheral" when a new peripheral is attached. Argument is the name.
"peripheral_detach" when a peripheral is removed. Argument is the name.
Type "help events" to learn about the event system.

View File

@@ -0,0 +1,7 @@
The "peripherals" program will list all of the peripheral devices accessible from this computer.
Peripherals are external devices which CraftOS Computers and Turtles can interact with using the peripheral API.
Type "help peripheral" to learn about using the peripheral API.
Type "help drives" to learn about using Disk Drives.
Type "help modems" to learn about using Modems.
Type "help monitors" to learn about using Monitors.
Type "help printers" to learn about using Printers.

View File

@@ -0,0 +1,6 @@
pocket is an API available on pocket computers, which allows modifying its upgrades.
Functions in the pocket API:
pocket.equipBack()
pocket.unequipBack()
When equipping upgrades, it will search your inventory for a suitable upgrade, starting in the selected slot. If one cannot be found then it will check your offhand.

View File

@@ -0,0 +1,12 @@
The Printer is a peripheral device available for CraftOS. Type "help peripheral" to learn about using the Peripheral API to connect with peripherals. When a Printer is connected, peripheral.getType() will return "printer".
Methods exposed by the Printer:
getInkLevel()
getPaperLevel()
newPage()
setPageTitle( title )
getPageSize()
setCursorPos( x, y )
getCursorPos()
write( text )
endPage()

View File

@@ -0,0 +1,11 @@
To learn the lua programming language, visit http://lua-users.org/wiki/TutorialDirectory.
To experiment with lua in CraftOS, run the "lua" program and start typing code.
To create programs, use "edit" to create files, then type their names in the shell to run them. If you name a program "startup" and place it in the root or on a disk drive, it will run automatically when the computer starts.
To terminate a program stuck in a loop, hold Ctrl+T for 1 second.
To quickly shutdown a computer, hold Ctrl+S for 1 second.
To quickly reboot a computer, hold Ctrl+R for 1 second.
To learn about the programming APIs availiable, type "apis" or "help apis".
If you get stuck, visit the forums at http://www.computercraft.info/ for advice and tutorials.

View File

@@ -0,0 +1 @@
programs lists all the programs on the rom of the computer.

View File

@@ -0,0 +1,2 @@
reboot will turn the computer off and on again.
You can also hold Ctrl+R at any time to quickly reboot.

View File

@@ -0,0 +1,2 @@
Redirection ComputerCraft Edition is the CraftOS version of a fun new puzzle game by Dan200, the author of ComputerCraft.
Play it on any Advanced Computer, then visit http://www.redirectiongame.com to play the full game!

View File

@@ -0,0 +1,18 @@
The rednet API provides a simple computer networking model using modems.
Functions in the rednet API:
rednet.open( side )
rednet.close( [side] )
rednet.isOpen( [side] )
rednet.send( receiverID, message, [protocol] ) -- Send to a specific computer
rednet.broadcast( message, [protocol] ) -- Send to all computers
rednet.receive( [protocol], [timeout] ) -- Returns: senderID, message, protocol
rednet.host( protocol, hostname )
rednet.unhost( protocol )
rednet.lookup( protocol, [hostname] ) -- Returns: ID
Events fired by the rednet API:
"rednet_message" when a message is received. Arguments are senderID, message, protocol
Type "help events" to learn about the event system.
Rednet is not the only way to use modems for networking. Interfacing with the modem directly using the peripheral API and listening for the "modem_message" event allows for lower level control, at the expense of powerful high level networking features.

View File

@@ -0,0 +1,9 @@
The redstone program can be used to get, set or pulse redstone inputs and outputs from the computer.
ex:
"redstone probe" will list all the redstone inputs to the computer
"redstone set left true" turns on the left redstone output.
"redstone set right blue false" turns off the blue wire in the bundled cable on the right redstone output.
"redstone pulse front 10 1" emits 10 one second redstone pulses on the front redstone output.
Type "help redstoneapi" or "help rs" for information on the redstone Lua API.

View File

@@ -0,0 +1,19 @@
Functions in the Redstone API:
redstone.getSides( )
redstone.getInput( side )
redstone.setOutput( side, boolean )
redstone.getOutput( side )
redstone.getAnalogInput( side )
redstone.setAnalogOutput( side, number )
redstone.getAnalogOutput( side )
Functions in the Redstone API for working with bundled cables:
redstone.getBundledInput( side )
redstone.testBundledInput( side, color )
redstone.setBundledOutput( side, colors )
redstone.getBundledOutput( side )
Type "help bundled" for usage examples.
Events emitted by the redstone API:
"redstone", when the state of any redstone input changes. Use getInput() or getBundledInput() to inspect the changes
Type "help events" to learn about the event system.

View File

@@ -0,0 +1,6 @@
refuel is a program for Turtles. Refuel will consume items from the inventory as fuel for turtle.
ex:
"refuel" will refuel with at most one fuel item
"refuel 10" will refuel with at most 10 fuel items
"refuel all" will refuel with as many fuel items as possible

View File

@@ -0,0 +1,4 @@
rename renames a file or directory.
ex:
"rename foo bar" renames the file "foo" to "bar".

View File

@@ -0,0 +1 @@
repeat is a program for repeating rednet messages across long distances. To use, connect 2 or more modems to a computer and run the "repeat" program; from then on, any rednet message sent from any computer in wireless range or connected by networking cable to either of the modems will be repeated to those on the other side.

View File

@@ -0,0 +1,19 @@
Functions in the Redstone API:
rs.getSides( )
rs.getInput( side )
rs.setOutput( side, boolean )
rs.getOutput( side )
rs.getAnalogInput( side )
rs.setAnalogOutput( side, number )
rs.getAnalogOutput( side )
Functions in the Redstone API for working with RedPower bundled cables:
rs.getBundledInput( side )
rs.testBundledInput( side, color )
rs.setBundledOutput( side, colors )
rs.getBundledOutput( side )
Type "help bundled" for usage examples.
Events emitted by the redstone API:
"redstone", when the state of any redstone input changes. Use getInput() or getBundledInput() to inspect the changes
Type "help events" to learn about the event system.

View File

@@ -0,0 +1,6 @@
The set program can be used to inspect and change system settings.
Usage:
"set" will print all the system settings and their values
"set foo" will print the value of the system setting "foo"
"set foo bar" will set the value of the system setting "foo" to "bar"

View File

@@ -0,0 +1,19 @@
Functions in the Settings API:
settings.get( name, [default] )
settings.set( name, value )
settings.unset( name )
settings.load( path )
settings.save( path )
settings.clear()
settings.getNames()
Default Settings:
shell.autocomplete - enables auto-completion in the Shell.
lua.autocomplete - enables auto-completion in the Lua program.
edit.autocomplete - enables auto-completion in the Edit program.
edit.default_extension - sets the default file extension for files created with the Edit program
paint.default_extension - sets the default file extension for files created with the Paint program
bios.use_multishell - enables Multishell on Advanced Computers, Turtles, Pocket Computers and Command Computers.
shell.allow_disk_startup - if a Disk Drive with a Disk inside that has a 'startup' script is attached to a computer, this setting allows to automatically run that script when the computer starts.
shell.allow_startup - if there is a 'startup' script in a computer's root, this setting allow to automatically run that script when the computer runs.
list.show_hidden - determines, whether the List program will list hidden files or not.

View File

@@ -0,0 +1,2 @@
shell is the toplevel program which interprets commands and runs program.
Type "help shellapi" for information about the shell lua api.

View File

@@ -0,0 +1,19 @@
Functions in the Shell API:
shell.exit()
shell.dir()
shell.setDir( path )
shell.path()
shell.setPath( path )
shell.resolve( localpath )
shell.resolveProgram( name )
shell.aliases()
shell.setAlias( alias, command )
shell.clearAlias( alias )
shell.programs()
shell.run( program, arguments )
shell.getRunningProgram()
shell.complete( line )
shell.completeProgram( program )
shell.setCompletionFunction( program, fnComplete )
shell.openTab( program, arguments ) (Advanced Computer required)
shell.switchTab( n ) (Advanced Computer required)

Some files were not shown because too many files have changed in this diff Show More