diff --git a/MetroOS/MetroOS b/MetroOS/MetroOS new file mode 100644 index 0000000..b45ecb9 --- /dev/null +++ b/MetroOS/MetroOS @@ -0,0 +1,353 @@ +local files = { + ["init"] = "require \"UIButton\"\ +require \"UIContainer\"\ +require \"UIText\"\ +require \"UILabel\"\ +require \"UITextInput\"\ +require \"UIMenu\"\ +require \"UITabs\"\ +require \"UIFileDialogue\"\ +\ +application.terminateable = false\ +\ +local blocksize = 5\ +local bit32 = 2 ^ 32\ +local prime1 = 8747\ +local prime2 = 2147483647\ +local bit32half = bit32/2\ +local floor = math.floor\ +local function keygen( seed, length ) local count = 1 local keys, garbage = {}, {} for i = 1, length, blocksize do seed = ( seed * ( seed > bit32half and prime2 or prime1 ) + 1 ) % bit32 + count count = count + 1 garbage[i] = math.max( 0, ( seed - 1 ) % 10 - 4 ) keys[i] = seed % 256 end return keys, garbage end\ +local h = {}\ +for i = 0, 15 do h[i] = (\"%X\"):format( i ) end\ +local hl = {}\ +for i = 0, 15 do hl[(\"%X\"):format( i )] = i end\ +local function tohex2( n ) return h[math.floor( n / 16 )] .. h[n % 16] end\ +local function fromhex2( h ) return hl[h:sub( 1, 1 )] * 16 + hl[h:sub( 2, 2 )] end\ +local function numbertochars( n ) local s = tohex2( n % 256 ) for i = 1, 3 do n = math.floor( n / 256 ) s = tohex2( n % 256 ) .. s end return s end\ +local function charstonumber( c ) local n = 0 for i = 1, 4 do n = n * 256 + fromhex2( c:sub( i * 2 - 1 ) ) end return n end\ +local function newgarbage( length ) if length == 0 then return \"\" end return tohex2( math.random( 0, 255 ) ) .. newgarbage( length - 1 ) end\ +local function stringkey( str ) local key = 0 for i = 1, #str do key = key * 256 + str:byte( i ) end return key end\ +local encrypt = {}\ +function encrypt.encrypt( text, key ) key = type( key ) == \"string\" and stringkey( key ) or key text = textutils.serialize( text ) if type( key ) ~= \"number\" then return error( \"expected number/string key, got \" .. type( key ) ) end local keys, garbage = keygen( key, #text ) local cipher = { numbertochars( #text ) } math.randomseed( os.clock() ) for i = 1, #text, blocksize do for n = 0, blocksize - 1 do if i + n <= #text then cipher[#cipher + 1] = tohex2( bit.bxor( text:byte( i + n ), keys[i] ) ) else break end end cipher[#cipher + 1] = newgarbage( garbage[i] ) end return table.concat( cipher ) end\ +function encrypt.decrypt( cipher, key ) key = type( key ) == \"string\" and stringkey( key ) or key if type( cipher ) ~= \"string\" then return error( \"expected string cipher, got \" .. type( cipher ) ) end if type( key ) ~= \"number\" then return error( \"expected number/string key, got \" .. type( key ) ) end local length = charstonumber( cipher:sub( 1, 8 ) ) cipher = cipher:sub( 9 ) local keys, garbage = keygen( key, length ) local text = {} local i = 1 while #cipher > 0 do local block = cipher:sub( 1, math.min( #cipher - garbage[i] * 2, blocksize * 2 ) ) for n = 1, #block, 2 do text[#text + 1] = string.char( bit.bxor( fromhex2( block:sub( n ) ), keys[i] ) ) end cipher = cipher:sub( blocksize * 2 + garbage[i] * 2 + 1 ) i = i + blocksize end return textutils.unserialize( table.concat( text ) ) end\ +local MOD = 2^32\ +local MODM = MOD-1\ +local function memoize(f) local mt = {} local t = setmetatable({}, mt) function mt:__index(k) local v = f(k) t[k] = v return v end return t end\ +local function make_bitop_uncached(t, m) local function bitop(a, b) local res,p = 0,1 while a ~= 0 and b ~= 0 do local am, bm = a % m, b % m res = res + t[am][bm] * p a = (a - am) / m b = (b - bm) / m p = p*m end res = res + (a + b) * p return res end return bitop end\ +local function make_bitop(t) local op1 = make_bitop_uncached(t,2^1) local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end) return make_bitop_uncached(op2, 2 ^ (t.n or 1)) end\ +local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})\ +local function bxor(a, b, c, ...) local z = nil if b then a = a % MOD b = b % MOD z = bxor1(a, b) if c then z = bxor(z, c, ...) end return z elseif a then return a % MOD else return 0 end end\ +local function band(a, b, c, ...) local z if b then a = a % MOD b = b % MOD z = ((a + b) - bxor1(a,b)) / 2 if c then z = bit32_band(z, c, ...) end return z elseif a then return a % MOD else return MODM end end\ +local function bnot(x) return (-1 - x) % MOD end\ +local function rshift1(a, disp) if disp < 0 then return lshift(a,-disp) end return math.floor(a % 2 ^ 32 / 2 ^ disp) end\ +local function rshift(x, disp) if disp > 31 or disp < -31 then return 0 end return rshift1(x % MOD, disp) end\ +local function lshift(a, disp) if disp < 0 then return rshift(a,-disp) end return (a * 2 ^ disp) % 2 ^ 32 end\ +local function rrotate(x, disp) x = x % MOD disp = disp % 32 local low = band(x, 2 ^ disp - 1) return rshift(x, disp) + lshift(low, 32 - disp) end\ +local k = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, }\ +local function str2hexa(s) return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end)) end\ +local function num2s(l, n) local s = \"\"for i = 1, n do local rem = l % 256 s = string.char(rem) .. s l = (l - rem) / 256 end return s end\ +local function s232num(s, i) local n = 0 for i = i, i + 3 do n = n*256 + string.byte(s, i) end return n end\ +local function preproc(msg, len) local extra = 64 - ((len + 9) % 64) len = num2s(8 * len, 8) msg = msg .. \"\\128\" .. string.rep(\"\\0\", extra) .. len assert(#msg % 64 == 0) return msg end\ +local function initH256(H) H[1] = 0x6a09e667 H[2] = 0xbb67ae85 H[3] = 0x3c6ef372 H[4] = 0xa54ff53a H[5] = 0x510e527f H[6] = 0x9b05688c H[7] = 0x1f83d9ab H[8] = 0x5be0cd19 return H end\ +local function digestblock(msg, i, H) local w = {} for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end for j = 17, 64 do local v = w[j - 15] local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3)) v = w[j - 2] w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10)) end local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8] for i = 1, 64 do local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22)) local maj = bxor(band(a, b), band(a, c), band(b, c)) local t2 = s0 + maj local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25)) local ch = bxor (band(e, f), band(bnot(e), g)) local t1 = h + s1 + ch + k[i] + w[i] h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2 end H[1] = band(H[1] + a) H[2] = band(H[2] + b) H[3] = band(H[3] + c) H[4] = band(H[4] + d) H[5] = band(H[5] + e) H[6] = band(H[6] + f) H[7] = band(H[7] + g) H[8] = band(H[8] + h) end\ +local function sha256(msg) msg = preproc(msg, #msg) local H = initH256({}) for i = 1, #msg, 64 do digestblock(msg, i, H) end return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) .. num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4)) end\ +local tKeys = {\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } --, \"&\", \"%\", \"#\", \"$\", \"!\", \"@\", \"?\", \"=\", \"/\", \"\\\\\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\" }\ +table.size = function( tbl ) local count = 0 for k,v in pairs( tbl ) do count = count + 1 end return count end\ +\ +local function GenerateSalt()\ +\9local Count = 0\ +\9local Salt = \"\"\ +\9local function RandomKey()\ +\9\9local key = false\ +\9\9key = tKeys[ math.random( 1, table.size( tKeys ) ) ]\ +\9\9if type( key ) ~= \"number\" then\ +\9\9\9local x = math.random( 1, 2 )\ +\9\9\9if x == 1 then\ +\9\9\9\9key\9= string.lower( key )\ +\9\9\9elseif x == 2 then\ +\9\9\9\9key = string.upper( key )\ +\9\9\9end\ +\9\9end\ +\9\9return key\ +\9end\ +\9for SaltCount = 1, 32 do\ +\9\9Salt = Salt .. RandomKey()\ +\9\9Count = Count + 1\ +\9\9if Count == 16 then\ +\9\9\9sleep( 0 )\ +\9\9\9Count = 0\ +\9\9end\ +\9end\ +\9return Salt\ +end\ +local locSalt = GenerateSalt()\ +\ +local lock = {\ +\9name = \"Metro Secure OS Login\",\ +\9authorized = \"MetroOS - Computer unlocked\",\ +\9authorized2 = os.version(),\ +\9author = \"Outraged Security .INC\",\ +\9config = \".MetroOSSecureLock.cfg\",\ +}\ +local framerate = .05\ +local config = {}\ +\ +local loadFrame = application.view:addChild( UIContainer( 0, 0, application.view.width, application.view.height ) )\ +loadFrame.colour = colors.blue\ +loadFrame.transitionTime = 1\ +local note = loadFrame:addChild( UIText( 0, -math.floor( application.view.height / 3.5 ), 20, 5, \"\\n@acThis program\\ncannot be @teterminated\" ) )\ +note.colour = colors.lime\ +local blackFrame = application.view:addChild( UIContainer( 0, -application.view.height, application.view.width, application.view.height ) )\ +blackFrame.colour = colours.black\ +blackFrame.transitionTime = .75\ +\ +application.view:createShortcut( \"Terminate\", \"ctrl-t\", function()\ +\9note.y = -note.height\ +\9note.text = \"\\n@acThis program\\ncannot be \\n@teterminated\"\ +\9note.animatedY = 0\ +\9Timer.queue( 2.5, function()\ +\9\9note.animatedY = -note.height\ +\9end )\ +end )\ +application.view:createShortcut( \"Reboot\", \"ctrl-r\", function()\ +\9note.y = -note.height\ +\9note.text = \"\\n@acRebooting computer in @te1 second\"\ +\9note.animatedY = 0\ +\9Timer.queue( 1, function()\ +\9\9os.reboot()\ +\9end )\ +end )\ +\ +local tOName = blackFrame:addChild( UILabel( 0, 1, lock.authorized ) )\ +tOName.x = math.floor( application.view.width / 2 - #lock.authorized / 2 )\ +local tOName2 = blackFrame:addChild( UILabel( 0, 2, lock.authorized2 ) )\ +tOName2.x = math.floor( application.view.width / 2 - #lock.authorized2 / 2 )\ +\ +local tName = loadFrame:addChild( UILabel( 0, 1, lock.name ) )\ +tName.x = math.floor( application.view.width / 2 - #lock.name / 2 )\ +local tBy = loadFrame:addChild( UILabel( 0, application.view.height-2, \"By \" .. lock.author ) )\ +tBy.x = math.floor( application.view.width / 2 - #lock.author / 2 )\ +local tP = {}\ +\ +local function checkConfig()\ +\9if not fs.exists( lock.config ) then\ +\9\9local newPass = loadFrame:addChild( UILabel( 0, math.floor( application.view.height / 2 ) - 1, \"Enter new password\" ) )\ +\9\9newPass.transitionTime = .5\ +\9\9newPass.animatedX = math.floor( application.view.width / 2 - newPass.width / 2 )\ +\9\9inputPass = loadFrame:addChild( UITextInput( 0, math.floor( application.view.height / 2 ), application.view.width / 2 ) )\ +\9\9inputPass.transitionTime = .5\ +\9\9inputPass.focussed = true\ +\9\9inputPass.colour = colors.lime\ +\9\9inputPass.mask = \"#\"\ +\9\9inputPass.animatedX = math.floor( application.view.width / 2 - inputPass.width / 2 )\ +\9\9function inputPass:onEnter()\ +\9\9\9if not tP[1] then\ +\9\9\9\9tP[1] = sha256( locSalt .. inputPass.text )\ +\9\9\9\9inputPass.text = \"\"\ +\9\9\9\9inputPass.focussed = true\ +\9\9\9\9newPass.text = \"Re-enter password\"\ +\9\9\9\9newPass.animatedX = math.floor( application.view.width / 2 - newPass.width / 2 )\ +\9\9\9\9newPass.text\ = colours.orange\ +\9\9\9else\ +\9\9\9\9tP[2] = sha256( locSalt .. inputPass.text )\ +\9\9\9\9inputPass.text = \"\"\ +\9\9\9\9inputPass.focussed = true\ +\9\9\9\9if tP[1] ~= tP[2] then\ +\9\9\9\9\9tP = {}\ +\9\9\9\9\9newPass.text = \"Passwords did not match\"\ +\9\9\9\9\9newPass.animatedX = math.floor( application.view.width / 2 - newPass.width / 2 )\ +\9\9\9\9\9newPass.textColour = colours.red\ +\9\9\9\9\9Timer.queue( 1, function()\ +\9\9\9\9\9\9newPass:remove()\ +\9\9\9\9\9\9inputPass:remove()\ +\9\9\9\9\9\9checkConfig()\ +\9\9\9\9\9end )\ +\9\9\9\9else\ +\9\9\9\9\9inputPass.focussed = false\ +\9\9\9\9\9newPass.text = \"Passwords matching!\"\ +\9\9\9\9\9newPass.animatedX = math.floor( application.view.width / 2 - newPass.width / 2 )\ +\9\9\9\9\9newPass.textColour = colours.lime\ +\9\9\9\9\9config.pass = tP[1]\ +\9\9\9\9\9config.salt = locSalt\ +\9\9\9\9\9Timer.queue( 1, function()\ +\9\9\9\9\9\9newPass:transitionOutRight()\ +\9\9\9\9\9\9inputPass:transitionOutBottom()\ +\9\9\9\9\9\9Timer.queue( .3, function()\ +\9\9\9\9\9\9\9tP = {}\ +\9\9\9\9\9\9\9newPass:remove()\ +\9\9\9\9\9\9\9inputPass:remove()\ +\9\9\9\9\9\9end )\ +\9\9\9\9\9end )\ +\9\9\9\9\9Timer.queue( 1, function()\ +\9\9\9\9\9\9local doorSettings = loadFrame:addChild( UILabel( 0, math.floor( application.view.height / 2 ) - 5, \"Choose redstone output side\" ) )\ +\9\9\9\9\9\9local doorSettings1 = loadFrame:addChild( UILabel( 0, math.floor( application.view.height / 2 ) - 4, \"\\\"None\\\" = Unlock computer shell\" ) )\ +\9\9\9\9\9\9local redstoneside = loadFrame:addChild( UITabs( 0, math.floor( application.view.height / 2 ) - 2, math.floor( application.view.width / 2.25 ), { \"None\", \"Top\", \"Bottom\", \"Right\", \"Left\", \"Front\", \"Back\" } ) )\ +\9\9\9\9\9\9redstoneside:select(1)\ +\9\9\9\9\9\9redstoneside.transitionTime = .2\ +\9\9\9\9\9\9redstoneside.colour = colors.blue\ +\9\9\9\9\9\9redstoneside.textColour = colours.white\ +\9\9\9\9\9\9local continue = loadFrame:addChild( UIButton( 0, math.floor( application.view.height / 2 ) + 3, math.floor( application.view.width / 3 ), 3, \"Continue\" ) )\ +\9\9\9\9\9\9continue.colour = colors.lime\ +\9\9\9\9\9\9continue.animatedX = math.floor( application.view.width / 2 - continue.width / 2 )\ +\9\9\9\9\9\9redstoneside.animatedX = math.floor( application.view.width / 2 - redstoneside.width / 2 )\ +\9\9\9\9\9\9doorSettings.animatedX = math.floor( application.view.width / 2 - doorSettings.width / 2 )\ +\9\9\9\9\9\9doorSettings1.animatedX = math.floor( application.view.width / 2 - doorSettings1.width / 2 )\ +\9\9\9\9\9\9function continue:onClick()\ +\9\9\9\9\9\9\9if redstoneside.selected ~= 0 and redstoneside.selected ~= 1 then\ +\9\9\9\9\9\9\9\9config.redstone = redstoneside.options[ redstoneside.selected ] or false\ +\9\9\9\9\9\9\9else\ +\9\9\9\9\9\9\9\9config.redstone = false\ +\9\9\9\9\9\9\9end\ +\9\9\9\9\9\9\9doorSettings:transitionOutTop()\ +\9\9\9\9\9\9\9doorSettings1:transitionOutRight()\ +\9\9\9\9\9\9\9redstoneside:transitionOutLeft()\ +\9\9\9\9\9\9\9continue:transitionOutBottom()\ +\9\9\9\9\9\9\9Timer.queue( .5, function()\ +\9\9\9\9\9\9\9\9doorSettings:remove()\ +\9\9\9\9\9\9\9\9doorSettings1:remove()\ +\9\9\9\9\9\9\9\9redstoneside:remove()\ +\9\9\9\9\9\9\9\9continue:remove()\ +\9\9\9\9\9\9\9\9ok, err = pcall(function() \ +\9\9\9\9\9\9\9\9\9local SaveFile = fs.open( lock.config, \"w\" )\ +\9\9\9\9\9\9\9\9\9SaveFile.writeLine( encrypt.encrypt( textutils.serialize( config ), config.pass ) )\ +\9\9\9\9\9\9\9\9\9SaveFile.close()\ +\9\9\9\9\9\9\9\9end )\ +\9\9\9\9\9\9\9\9checkConfig()\ +\9\9\9\9\9\9\9end )\ +\9\9\9\9\9\9end\ +\9\9\9\9\9end )\ +\9\9\9\9end\ +\9\9\9end\ +\9\9end\ +\9else\ +\9\9\ +\9\9main()\ +\9end\ +end\ +\ +function main()\ +\9local inputTextPass = loadFrame:addChild( UILabel( 0, math.floor( application.view.height / 2 )-1, \"Password\" ) )\ +\9inputTextPass.transitionTime = .25\ +\9inputTextPass.animatedX = math.floor( application.view.width/2 - inputTextPass.width/2 )\ +\9local inputFieldPass = loadFrame:addChild( UITextInput( 0, math.floor( application.view.height / 2 ), application.view.width/2 ) )\ +\9inputFieldPass.transitionTime = .25\ +\9inputFieldPass.colour = colors.lime\ +\9inputFieldPass.mask = \"#\"\ +\9inputFieldPass.focussed = true\ +\9inputFieldPass.animatedX = math.floor( application.view.width/2 - inputFieldPass.width/2 )\ +\9function inputFieldPass:onEnter()\ +\9\9inputTextPass.text = \"Validating\"\ +\9\9inputTextPass.animatedX = math.floor( application.view.width/2 - inputTextPass.width/2 )\ +\9\9local file = fs.open( lock.config, \"r\" )\ +\9\9local config = textutils.unserialize( encrypt.decrypt( file.readAll(), sha256( inputFieldPass.text ) ) )\ +\9\9file.close()\ +\9\9if sha256( config.salt .. inputFieldPass.text ) == config.pass then\ +\9\9\9inputFieldPass.text = \"\"\ +\9\9\9inputTextPass.text = \"Password correct\"\ +\9\9\9inputTextPass.textColour = colours.lime\ +\9\9\9inputTextPass.animatedX = math.floor( application.view.width/2 - inputTextPass.width/2 )\ +\9\9\9if config.redstone then\ +\9\9\9\9rs.setOutput( config.redstone:lower(), true )\ +\9\9\9\9Timer.queue( 5, function() \ +\9\9\9\9\9rs.setOutput( config.redstone:lower(), false )\ +\9\9\9\9\9inputTextPass:remove()\ +\9\9\9\9\9inputFieldPass:remove()\ +\9\9\9\9\9main()\ +\9\9\9\9end )\ +\9\9\9else\ +\9\9\9\9Timer.queue( .25, function()\ +\9\9\9\9\9inputTextPass:transitionOutLeft()\ +\9\9\9\9\9inputFieldPass:transitionOutBottom()\ +\9\9\9\9\9Timer.queue( .5, function()\ +\9\9\9\9\9\9loadFrame.colour = colors.lime\ +\9\9\9\9\9\9loadFrame:transitionOutBottom()\ +\9\9\9\9\9\9blackFrame:transitionInTop()\ +\9\9\9\9\9\9Timer.queue( .8, function() \ +\9\9\9\9\9\9\9term.setCursorPos( 1, 5 )\ +\9\9\9\9\9\9\9application:stop()\ +\9\9\9\9\9\9end )\ +\9\9\9\9\9end )\ +\9\9\9\9end )\ +\9\9\9end\ +\9\9else\ +\9\9\9inputTextPass.text = \"Password incorrect\"\ +\9\9\9inputTextPass.textColour = colours.red\ +\9\9\9inputTextPass.animatedX = math.floor( application.view.width/2 - inputTextPass.width/2 )\ +\9\9\9Timer.queue( 1, function()\ +\9\9\9\9inputTextPass:remove()\ +\9\9\9\9inputFieldPass:remove()\ +\9\9\9\9main()\ +\9\9\9end )\ +\9\9end\ +\9end\ +end\ +local _ok, result = pcall( checkConfig )"; +} +if shell.getRunningProgram() ~= "startup" then + if fs.exists( "startup" ) then + fs.move( "startup", "__oldstartup" ) + end + fs.move( shell.getRunningProgram(), "startup" ) + os.reboot() +--[[else + local protecting = { "startup", ".MetroOSSecureLock.cfg" } + local oldCopy = fs.copy + local oldMove = fs.move + local oldDelete = fs.delete + local oldEdit = fs.open + fs.delete = function( path ) + for k, v in pairs( protecting ) do + if fs.getName( path ) == v then + return error( "Cannot remove MetroOS", 0 ) + end + end + return oldDelete( path ) + end + fs.open = function( path, method, pass ) + if method == "r" then + return oldEdit( path, method ) + else + return error( "Cannot edit MetroOS", 0 ) + end + end + fs.move = function( path, newPath ) + for k, v in pairs( protecting ) do + if fs.getName( path ) == v then + return error( "Cannot move MetroOS", 0 ) + end + end + return oldMove( path, newPath ) + end + fs.copy = function( path, newPath ) + for k, v in pairs( protecting ) do + if fs.getName( path ) == v then + return error( "Cannot copy MetroOS", 0 ) + end + end + return oldCopy( path, newPath ) + end--]] +end +if not fs.exists "Flare" then + print "Downloading Flare" + local h = http.get "https://pastebin.com/raw/SD25GhYf" + if h then + local f, err = load( h.readAll(), "installer", nil, _ENV or getfenv() ) + h.close() + f() + else + return error( "Cannot install Flare", 0 ) + end +end +local loader +local h = fs.open( "Flare/run.lua", "r" ) +if h then + loader = h.readAll() + h.close() +else + error( "failed to read Flare", 0 ) +end +local f, err = load( loader, "Flare", nil, _ENV or getfenv() ) +if not f then + error( "there was a problem with Flare!: " .. err, 0 ) +end +f( files, "init" ) diff --git a/README.md b/README.md index fbe12b7..d157c09 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -darkprograms +Outraged Programs ============ -Programs witten by Darkrising for use with the Minecraft mod: Computercraft. +Programs witten by Outraged Security .INC for use with the Minecraft mod: Computercraft. These Files are written in: Lua diff --git a/Secure OS/apis/processes.lua b/Secure OS/apis/processes.lua new file mode 100644 index 0000000..9772cff --- /dev/null +++ b/Secure OS/apis/processes.lua @@ -0,0 +1,194 @@ +local userEvents = {"mouse_click", "mouse_up", "mouse_drag", "char", "key", "monitor_touch", "key_up", "paste", "terminate"} +local parentTerm = term.current() +local parentWidth, parentHeight = parentTerm.getSize() +local defaultProperties = { + x = math.ceil(parentWidth/2-parentWidth/4), + y = math.ceil(parentHeight/2-parentHeight/4), + w = math.ceil(parentWidth/2), h = math.ceil(parentHeight/2), + noWindow = false, noBar = false, noInteraction = false, + name = "Unnamed Window" +} + +local isUserEvent = function(event) + for userEventNum = 1, #userEvents do + local userEvent = userEvents[userEventNum] + if event == userEvent then + return true + end + end +end + +local createProcessCoroutine = function(func) + return coroutine.create(function() + local succ, mess = pcall(func) + if not succ and mess then + while true do + term.setBackgroundColor(colors.black) + term.setTextColor(colors.orange) + term.clear() + term.setCursorPos(1, 1) + print("The program crashed!") + write(mess) + coroutine.yield() + end + end + end) +end + +return { + drawWindowDecorations = function(self, processNum, event, var1, var2, var3) + local process = self[processNum] + if not process.noWindow and not process.noBar then + local pw, ph = process.term.getSize() + + paintutils.drawLine(process.x, process.y-1, process.x+pw-1, process.y-1, colors.lightGray) + term.setTextColor(colors.gray) + + term.setCursorPos(process.x+pw-1, process.y-1) + term.write("x") + term.setCursorPos(process.x, process.y-1) + term.write(process.name) + end + end, + handleInputOfProcess = function(self, processNum, event, var1, var2, var3) + local process = self[processNum] + if not process.noWindow and not process.noInteraction then + local px, py = process.term.getPosition() + local pw, ph = process.term.getSize() + local mx, my + if var3 then + mx, my = var2-px+1, var3-py+1 + end + + if event == "mouse_click" then + process.resizeX, process.resizeY = nil, nil + if mx>0 and my==0 and mx0 and my>0 and mx#self.name and h>3 then + local oldX, oldY = self.term.getPosition() + self.term.reposition(oldX, oldY, w, h) + os.queueEvent("term_resize") + end + end + } + + for k, v in pairs(defaultProperties) do + process[k] = properties[k] or v + end + + process.term = window.create( + parentTerm, process.x, process.y, process.w, process.h + ) + + table.insert(self, process) + end, + -- update all processes + update = function(self, event, var1, var2, var3) + for processNum, process in ipairs(self) do + self:updateProcess(processNum, event, var1, var2, var3) + end + end +} diff --git a/Secure OS/apis/ui.lua b/Secure OS/apis/ui.lua new file mode 100644 index 0000000..edc369a --- /dev/null +++ b/Secure OS/apis/ui.lua @@ -0,0 +1,3 @@ +local ui = {} + +return ui diff --git a/Secure OS/doorlock b/Secure OS/doorlock new file mode 100644 index 0000000..1ad7091 --- /dev/null +++ b/Secure OS/doorlock @@ -0,0 +1,1348 @@ +tArgs = {...} + +if OneOS then + --running under OneOS + OneOS.ToolBarColour = colours.white + OneOS.ToolBarTextColour = colours.grey +end + +local _w, _h = term.getSize() + +local round = function(num, idp) + local mult = 10^(idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +InterfaceElements = {} + +Drawing = { + + Screen = { + Width = _w, + Height = _h + }, + + DrawCharacters = function (x, y, characters, textColour,bgColour) + Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour) + end, + + DrawBlankArea = function (x, y, w, h, colour) + Drawing.DrawArea (x, y, w, h, " ", 1, colour) + end, + + DrawArea = function (x, y, w, h, character, textColour, bgColour) + --width must be greater than 1, other wise we get a stack overflow + if w < 0 then + w = w * -1 + elseif w == 0 then + w = 1 + end + + for ix = 1, w do + local currX = x + ix - 1 + for iy = 1, h do + local currY = y + iy - 1 + Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour) + end + end + end, + + DrawImage = function(_x,_y,tImage, w, h) + if tImage then + for y = 1, h do + if not tImage[y] then + break + end + for x = 1, w do + if not tImage[y][x] then + break + end + local bgColour = tImage[y][x] + local textColour = tImage.textcol[y][x] or colours.white + local char = tImage.text[y][x] + Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour) + end + end + elseif w and h then + Drawing.DrawBlankArea(x, y, w, h, colours.green) + end + end, + --using .nft + LoadImage = function(path) + local image = { + text = {}, + textcol = {} + } + local fs = fs + if OneOS then + fs = OneOS.FS + end + if fs.exists(path) then + local _open = io.open + if OneOS then + _open = OneOS.IO.open + end + local file = _open(path, "r") + local sLine = file:read() + local num = 1 + while sLine do + table.insert(image, num, {}) + table.insert(image.text, num, {}) + table.insert(image.textcol, num, {}) + + --As we're no longer 1-1, we keep track of what index to write to + local writeIndex = 1 + --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour + local bgNext, fgNext = false, false + --The current background and foreground colours + local currBG, currFG = nil,nil + for i=1,#sLine do + local nextChar = string.sub(sLine, i, i) + if nextChar:byte() == 30 then + bgNext = true + elseif nextChar:byte() == 31 then + fgNext = true + elseif bgNext then + currBG = Drawing.GetColour(nextChar) + bgNext = false + elseif fgNext then + currFG = Drawing.GetColour(nextChar) + fgNext = false + else + if nextChar ~= " " and currFG == nil then + currFG = colours.white + end + image[num][writeIndex] = currBG + image.textcol[num][writeIndex] = currFG + image.text[num][writeIndex] = nextChar + writeIndex = writeIndex + 1 + end + end + num = num+1 + sLine = file:read() + end + file:close() + end + return image + end, + + DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour) + w = w or Drawing.Screen.Width + h = h or Drawing.Screen.Height + x = x or 0 + y = y or 0 + x = math.ceil((w - #characters) / 2) + x + y = math.floor(h / 2) + y + + Drawing.DrawCharacters(x, y, characters, textColour, bgColour) + end, + + GetColour = function(hex) + if hex == ' ' then + return colours.transparent + end + local value = tonumber(hex, 16) + if not value then return nil end + value = math.pow(2,value) + return value + end, + + Clear = function (_colour) + _colour = _colour or colours.black + Drawing.ClearBuffer() + Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour) + end, + + Buffer = {}, + BackBuffer = {}, + + DrawBuffer = function() + for y,row in pairs(Drawing.Buffer) do + for x,pixel in pairs(row) do + local shouldDraw = true + local hasBackBuffer = true + if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then + hasBackBuffer = false + end + if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then + shouldDraw = false + end + if shouldDraw then + term.setBackgroundColour(pixel[3]) + term.setTextColour(pixel[2]) + term.setCursorPos(x, y) + term.write(pixel[1]) + end + end + end + Drawing.BackBuffer = Drawing.Buffer + Drawing.Buffer = {} + term.setCursorPos(1,1) + end, + + ClearBuffer = function() + Drawing.Buffer = {} + end, + + WriteStringToBuffer = function (x, y, characters, textColour,bgColour) + for i = 1, #characters do + local character = characters:sub(i,i) + Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour) + end + end, + + WriteToBuffer = function(x, y, character, textColour,bgColour) + x = round(x) + y = round(y) + if bgColour == colours.transparent then + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black} + Drawing.Buffer[y][x][1] = character + Drawing.Buffer[y][x][2] = textColour + else + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = {character, textColour, bgColour} + end + end, +} + +Current = { + Document = nil, + TextInput = nil, + CursorPos = {1,1}, + CursorColour = colours.black, + Selection = {8, 36}, + Window = nil, + HeaderText = '', + StatusText = '', + StatusColour = colours.grey, + StatusScreen = true, + ButtonOne = nil, + ButtonTwo = nil, + Locked = false, + Page = '', + PageControls = {} +} + +isRunning = true + +Events = {} + +Button = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.white, + ActiveBackgroundColour = colours.lightGrey, + Text = "", + Parent = nil, + _Click = nil, + Toggle = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local bg = self.BackgroundColour + local tc = self.TextColour + if type(bg) == 'function' then + bg = bg() + end + + if self.Toggle then + tc = colours.white + bg = self.ActiveBackgroundColour + end + + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg) + Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg) + end, + + Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.Text = text or "" + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.white + new.ActiveBackgroundColour = activeBackgroundColour or colours.lightBlue + new.Parent = parent + new._Click = click + new.Toggle = toggle + return new + end, + + Click = function(self, side, x, y) + if self._Click then + if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then + self.Toggle = not self.Toggle + Draw() + end + return true + else + return false + end + end +} + +Label = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.white, + Text = "", + Parent = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local bg = self.BackgroundColour + local tc = self.TextColour + + if self.Toggle then + tc = UIColours.MenuBarActive + bg = self.ActiveBackgroundColour + end + + local pos = GetAbsolutePosition(self) + Drawing.DrawCharacters(pos.X, pos.Y, self.Text, self.TextColour, self.BackgroundColour) + end, + + Initialise = function(self, x, y, text, textColour, backgroundColour, parent) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.Text = text or "" + new.BackgroundColour = backgroundColour or colours.white + new.TextColour = textColour or colours.black + new.Parent = parent + return new + end, + + Click = function(self, side, x, y) + return false + end +} + +TextBox = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.black, + Parent = nil, + TextInput = nil, + Placeholder = '', + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour) + local text = self.TextInput.Value + if #tostring(text) > (self.Width - 2) then + text = text:sub(#text-(self.Width - 3)) + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y} + end + else + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y} + end + end + + if #tostring(text) == 0 then + Drawing.DrawCharacters(pos.X + 1, pos.Y, self.Placeholder, colours.lightGrey, self.BackgroundColour) + else + Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour) + end + + term.setCursorBlink(true) + + Current.CursorColour = self.TextColour + end, + + Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.TextInput = TextInput:Initialise(text or '', function(key) + if done then + done(key) + end + Draw() + end, numerical) + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.black + new.Parent = parent + return new + end, + + Click = function(self, side, x, y) + Current.Input = self.TextInput + self:Draw() + end +} + +TextInput = { + Value = "", + Change = nil, + CursorPos = nil, + Numerical = false, + IsDocument = nil, + + Initialise = function(self, value, change, numerical, isDocument) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Value = tostring(value) + new.Change = change + new.CursorPos = #tostring(value) + new.Numerical = numerical + new.IsDocument = isDocument or false + return new + end, + + Insert = function(self, str) + if self.Numerical then + str = tostring(tonumber(str)) + end + + local selection = OrderSelection() + + if self.IsDocument and selection then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. str .. string.sub( self.Value, selection[2]+2) + self.CursorPos = selection[1] + Current.Selection = nil + else + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub(self.Value, 1, self.CursorPos + newLineAdjust) .. str .. string.sub( self.Value, self.CursorPos + 1 + newLineAdjust) + self.CursorPos = self.CursorPos + 1 + end + + self.Change(key) + end, + + Extract = function(self, remove) + local selection = OrderSelection() + if self.IsDocument and selection then + local _, newLineAdjust = string.gsub(self.Value:sub(selection[1], selection[2]), '\n','') + local str = string.sub(self.Value, selection[1], selection[2]+1+newLineAdjust) + if remove then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. string.sub( self.Value, selection[2]+2+newLineAdjust) + self.CursorPos = selection[1] - 1 + Current.Selection = nil + end + return str + end + end, + + Char = function(self, char) + if char == 'nil' then + return + end + self:Insert(char) + end, + + Key = function(self, key) + if key == keys.enter then + if self.IsDocument then + self.Value = string.sub(self.Value, 1, self.CursorPos ) .. '\n' .. string.sub( self.Value, self.CursorPos + 1 ) + self.CursorPos = self.CursorPos + 1 + end + self.Change(key) + elseif key == keys.left then + -- Left + if self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + + elseif key == keys.right then + -- Right + if self.CursorPos < string.len(self.Value) then + local colShift = FindColours(string.sub( self.Value, self.CursorPos+1, self.CursorPos+1)) + self.CursorPos = self.CursorPos + 1 + colShift + self.Change(key) + end + + elseif key == keys.backspace then + -- Backspace + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub( self.Value, 1, self.CursorPos - 1 - colShift + newLineAdjust) .. string.sub( self.Value, self.CursorPos + 1 - colShift + newLineAdjust) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + elseif key == keys.home then + -- Home + self.CursorPos = 0 + self.Change(key) + elseif key == keys.delete then + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos < string.len(self.Value) then + self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 ) + self.Change(key) + end + elseif key == keys["end"] then + -- End + self.CursorPos = string.len(self.Value) + self.Change(key) + elseif key == keys.up and self.IsDocument then + -- Up + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY - 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + elseif key == keys.down and self.IsDocument then + -- Down + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY + 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + end + end +} + +local Capitalise = function(str) + return str:sub(1, 1):upper() .. str:sub(2, -1) +end + + +local getNames = peripheral.getNames or function() + local tResults = {} + for n,sSide in ipairs( rs.getSides() ) do + if peripheral.isPresent( sSide ) then + table.insert( tResults, sSide ) + local isWireless = false + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if peripheral.getType( sSide ) == "modem" and not isWireless then + local tRemote = peripheral.call( sSide, "getNamesRemote" ) + for n,sName in ipairs( tRemote ) do + table.insert( tResults, sName ) + end + end + end + end + return tResults +end + +Peripheral = { + GetPeripheral = function(_type) + for i, p in ipairs(Peripheral.GetPeripherals()) do + if p.Type == _type then + return p + end + end + end, + + Call = function(type, ...) + local tArgs = {...} + local p = Peripheral.GetPeripheral(type) + peripheral.call(p.Side, unpack(tArgs)) + end, + + GetPeripherals = function(filterType) + local peripherals = {} + for i, side in ipairs(getNames()) do + local name = peripheral.getType(side):gsub("^%l", string.upper) + local code = string.upper(side:sub(1,1)) + if side:find('_') then + code = side:sub(side:find('_')+1) + end + + local dupe = false + for i, v in ipairs(peripherals) do + if v[1] == name .. ' ' .. code then + dupe = true + end + end + + if not dupe then + local _type = peripheral.getType(side) + local isWireless = false + if _type == 'modem' then + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if isWireless then + _type = 'wireless_modem' + name = 'W '..name + end + end + if not filterType or _type == filterType then + table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..side:sub(1, 1):upper() .. side:sub(2, -1)..')', Side = side, Type = _type, Wireless = isWireless}) + end + end + end + return peripherals + end, + + PresentNamed = function(name) + return peripheral.isPresent(name) + end, + + CallType = function(type, ...) + local tArgs = {...} + local p = Peripheral.GetPeripheral(type) + return peripheral.call(p.Side, unpack(tArgs)) + end, + + CallNamed = function(name, ...) + local tArgs = {...} + return peripheral.call(name, unpack(tArgs)) + end +} + +Wireless = { + Channels = { + UltimateDoorlockPing = 4210, + UltimateDoorlockRequest = 4211, + UltimateDoorlockRequestReply = 4212, + }, + + isOpen = function(channel) + return Peripheral.CallType('wireless_modem', 'isOpen', channel) + end, + + Open = function(channel) + if not Wireless.isOpen(channel) then + Peripheral.CallType('wireless_modem', 'open', channel) + end + end, + + close = function(channel) + Peripheral.CallType('wireless_modem', 'close', channel) + end, + + closeAll = function() + Peripheral.CallType('wireless_modem', 'closeAll') + end, + + transmit = function(channel, replyChannel, message) + Peripheral.CallType('wireless_modem', 'transmit', channel, replyChannel, textutils.serialize(message)) + end, + + Present = function() + if Peripheral.GetPeripheral('wireless_modem') == nil then + return false + else + return true + end + end, + + FormatMessage = function(message, messageID, destinationID) + return { + content = textutils.serialize(message), + senderID = os.getComputerID(), + senderName = os.getComputerLabel(), + channel = channel, + replyChannel = reply, + messageID = messageID or math.random(10000), + destinationID = destinationID + } + end, + + Timeout = function(func, time) + time = time or 1 + parallel.waitForAny(func, function() + sleep(time) + --log('Timeout!'..time) + end) + end, + + RecieveMessage = function(_channel, messageID, timeout) + open(_channel) + local done = false + local event, side, channel, replyChannel, message = nil + Timeout(function() + while not done do + event, side, channel, replyChannel, message = os.pullEvent('modem_message') + if channel ~= _channel then + event, side, channel, replyChannel, message = nil + else + message = textutils.unserialize(message) + message.content = textutils.unserialize(message.content) + if messageID and messageID ~= message.messageID or (message.destinationID ~= nil and message.destinationID ~= os.getComputerID()) then + event, side, channel, replyChannel, message = nil + else + done = true + end + end + end + end, + timeout) + return event, side, channel, replyChannel, message + end, + + Initialise = function() + if Wireless.Present() then + for i, c in pairs(Wireless.Channels) do + Wireless.Open(c) + end + end + end, + + HandleMessage = function(event, side, channel, replyChannel, message, distance) + message = textutils.unserialize(message) + message.content = textutils.unserialize(message.content) + + if channel == Wireless.Channels.Ping then + if message.content == 'Ping!' then + SendMessage(replyChannel, 'Pong!', nil, message.messageID) + end + elseif message.destinationID ~= nil and message.destinationID ~= os.getComputerID() then + elseif Wireless.Responder then + Wireless.Responder(event, side, channel, replyChannel, message, distance) + end + end, + + SendMessage = function(channel, message, reply, messageID, destinationID) + reply = reply or channel + 1 + Wireless.Open(channel) + Wireless.Open(reply) + local _message = Wireless.FormatMessage(message, messageID, destinationID) + Wireless.transmit(channel, reply, _message) + return _message + end, + + Ping = function() + local message = SendMessage(Channels.Ping, 'Ping!', Channels.PingReply) + RecieveMessage(Channels.PingReply, message.messageID) + end +} + +function GetAbsolutePosition(object) + local obj = object + local i = 0 + local x = 1 + local y = 1 + while true do + x = x + obj.X - 1 + y = y + obj.Y - 1 + + if not obj.Parent then + return {X = x, Y = y} + end + + obj = obj.Parent + + if i > 32 then + return {X = 1, Y = 1} + end + + i = i + 1 + end + +end + +function Draw() + Drawing.Clear(colours.white) + + if Current.StatusScreen then + Drawing.DrawCharactersCenter(1, -2, nil, nil, Current.HeaderText, colours.blue, colours.white) + Drawing.DrawCharactersCenter(1, -1, nil, nil, 'by oeed', colours.lightGrey, colours.white) + Drawing.DrawCharactersCenter(1, 1, nil, nil, Current.StatusText, Current.StatusColour, colours.white) + end + + if Current.ButtonOne then + Current.ButtonOne:Draw() + end + + if Current.ButtonTwo then + Current.ButtonTwo:Draw() + end + + for i, v in ipairs(Current.PageControls) do + v:Draw() + end + + Drawing.DrawBuffer() + + if Current.TextInput and Current.CursorPos and not Current.Menu and not(Current.Window and Current.Document and Current.TextInput == Current.Document.TextInput) and Current.CursorPos[2] > 1 then + term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2]) + term.setCursorBlink(true) + term.setTextColour(Current.CursorColour) + else + term.setCursorBlink(false) + end +end +MainDraw = Draw + +function GenerateFingerprint() + local str = "" + for _ = 1, 256 do + local char = math.random(32, 126) + --if char == 96 then char = math.random(32, 95) end + str = str .. string.char(char) + end + return str +end + +function MakeFingerprint() + local h = fs.open('.fingerprint', 'w') + if h then + h.write(GenerateFingerprint()) + end + h.close() + Current.Fingerprint = str +end + +local drawTimer = nil +function SetText(header, status, colour, isReset) + if header then + Current.HeaderText = header + end + if status then + Current.StatusText = status + end + if colour then + Current.StatusColour = colour + end + Draw() + if not isReset then + statusResetTimer = os.startTimer(2) + end +end + +function ResetStatus() + if pocket then + if Current.Locked then + SetText('Ultimate Door Lock', 'Add Wireless Modem to PDA', colours.red, true) + else + SetText('Ultimate Door Lock', 'Ready', colours.grey, true) + end + else + if Current.Locked then + SetText('Ultimate Door Lock', ' Attach a Wireless Modem then reboot', colours.red, true) + else + SetText('Ultimate Door Lock', 'Ready', colours.grey, true) + end + end +end + +function ResetPage() + Wireless.Responder = function()end + pingTimer = nil + Current.PageControls = nil + Current.StatusScreen = false + Current.ButtonOne = nil + Current.ButtonTwo = nil + Current.PageControls = {} + CloseDoor() +end + +function PocketInitialise() + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + if not Wireless.Present() then + Current.Locked = true + ResetStatus() + return + end + Wireless.Initialise() + ResetStatus() + if fs.exists('.fingerprint') then + local h = fs.open('.fingerprint', 'r') + if h then + Current.Fingerprint = h.readAll() + else + MakeFingerprint() + end + h.close() + else + MakeFingerprint() + end + + Wireless.Responder = function(event, side, channel, replyChannel, message, distance) + if channel == Wireless.Channels.UltimateDoorlockPing then + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequest, Current.Fingerprint, Wireless.Channels.UltimateDoorlockRequestReply, nil, message.senderID) + elseif channel == Wireless.Channels.UltimateDoorlockRequestReply then + if message.content == true then + SetText(nil, 'Opening Door', colours.green) + else + SetText(nil, ' Access Denied', colours.red) + end + end + end +end + +function FingerprintIsOnWhitelist(fingerprint) + if Current.Settings.Whitelist then + for i, f in ipairs(Current.Settings.Whitelist) do + if f == fingerprint then + return true + end + end + end + return false +end + +function SaveSettings() + Current.Settings = Current.Settings or {} + local h = fs.open('.settings', 'w') + if h then + h.write(textutils.serialize(Current.Settings)) + end + h.close() +end + +local closeDoorTimer = nil +function OpenDoor() + if Current.Settings and Current.Settings.RedstoneSide then + SetText(nil, 'Opening Door', colours.green) + redstone.setOutput(Current.Settings.RedstoneSide, true) + closeDoorTimer = os.startTimer(0.6) + end +end + +function CloseDoor() + if Current.Settings and Current.Settings.RedstoneSide then + if redstone.getOutput(Current.Settings.RedstoneSide) then + SetText(nil, 'Closing Door', colours.orange) + redstone.setOutput(Current.Settings.RedstoneSide, false) + end + end +end + +DefaultSettings = { + Whitelist = {}, + RedstoneSide = 'back', + Distance = 10 +} + +function RegisterPDA(event, drive) + if disk.hasData(drive) then + local _fs = fs + if OneOS then + _fs = OneOS.FS + end + local path = disk.getMountPath(drive) + local addStartup = true + if _fs.exists(path..'/System/') then + path = path..'/System/' + addStartup = false + end + local fingerprint = nil + if _fs.exists(path..'/.fingerprint') then + local h = _fs.open(path..'/.fingerprint', 'r') + if h then + local str = h.readAll() + if #str == 256 then + fingerprint = str + end + end + h.close() + end + if not fingerprint then + fingerprint = GenerateFingerprint() + local h = _fs.open(path..'/.fingerprint', 'w') + h.write(fingerprint) + h.close() + if addStartup then + local h = fs.open(shell.getRunningProgram(), 'r') + local startup = h.readAll() + h.close() + local h = _fs.open(path..'/startup', 'w') + h.write(startup) + h.close() + end + end + if not FingerprintIsOnWhitelist(fingerprint) then + table.insert(Current.Settings.Whitelist, fingerprint) + SaveSettings() + end + disk.eject(drive) + SetText(nil, 'Registered Pocket Computer', colours.green) + end +end + +function HostSetup() + ResetPage() + Current.Page = 'HostSetup' + Current.ButtonTwo = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostStatusPage, 'Save', colours.black) + if not Current.Settings then + Current.Settings = DefaultSettings + end + + local sideButtons = {} + local function resetSideToggle(self) + for i, v in ipairs(sideButtons) do + if v.Toggle ~= nil then + v.Toggle = false + end + end + Current.Settings.RedstoneSide = self.Text:lower() + SaveSettings() + end + + table.insert(Current.PageControls, Label:Initialise(2, 2, 'Redstone Side')) + sideButtons = { + Button:Initialise(2, 4, nil, nil, nil, nil, resetSideToggle, 'Back', colours.black, false, colours.green), + Button:Initialise(9, 4, nil, nil, nil, nil, resetSideToggle, 'Front', colours.black, false, colours.green), + Button:Initialise(2, 6, nil, nil, nil, nil, resetSideToggle, 'Left', colours.black, false, colours.green), + Button:Initialise(9, 6, nil, nil, nil, nil, resetSideToggle, 'Right', colours.black, false, colours.green), + Button:Initialise(2, 8, nil, nil, nil, nil, resetSideToggle, 'Top', colours.black, false, colours.green), + Button:Initialise(8, 8, nil, nil, nil, nil, resetSideToggle, 'Bottom', colours.black, false, colours.green) + } + for i, v in ipairs(sideButtons) do + if v.Text:lower() == Current.Settings.RedstoneSide then + v.Toggle = true + end + table.insert(Current.PageControls, v) + end + + local distanceButtons = {} + local function resetDistanceToggle(self) + for i, v in ipairs(distanceButtons) do + if v.Toggle ~= nil then + v.Toggle = false + end + end + if self.Text == 'Small' then + Current.Settings.Distance = 5 + elseif self.Text == 'Normal' then + Current.Settings.Distance = 10 + elseif self.Text == 'Far' then + Current.Settings.Distance = 15 + end + SaveSettings() + end + + table.insert(Current.PageControls, Label:Initialise(23, 2, 'Opening Distance')) + distanceButtons = { + Button:Initialise(23, 4, nil, nil, nil, nil, resetDistanceToggle, 'Small', colours.black, false, colours.green), + Button:Initialise(31, 4, nil, nil, nil, nil, resetDistanceToggle, 'Normal', colours.black, false, colours.green), + Button:Initialise(40, 4, nil, nil, nil, nil, resetDistanceToggle, 'Far', colours.black, false, colours.green) + } + for i, v in ipairs(distanceButtons) do + if v.Text == 'Small' and Current.Settings.Distance == 5 then + v.Toggle = true + elseif v.Text == 'Normal' and Current.Settings.Distance == 10 then + v.Toggle = true + elseif v.Text == 'Far' and Current.Settings.Distance == 15 then + v.Toggle = true + end + table.insert(Current.PageControls, v) + end + + table.insert(Current.PageControls, Label:Initialise(2, 10, 'Registered PDAs: '..#Current.Settings.Whitelist)) + table.insert(Current.PageControls, Button:Initialise(2, 12, nil, nil, nil, nil, function()Current.Settings.Whitelist = {}HostSetup()end, 'Unregister All', colours.black)) + + + table.insert(Current.PageControls, Label:Initialise(23, 6, 'Help', colours.black)) + local helpLines = { + Label:Initialise(23, 8, 'To register a new PDA simply', colours.black), + Label:Initialise(23, 9, 'place a Disk Drive next to', colours.black), + Label:Initialise(23, 10, 'the computer, then put the', colours.black), + Label:Initialise(23, 11, 'PDA in the Drive, it will', colours.black), + Label:Initialise(23, 12, 'register automatically. If', colours.black), + Label:Initialise(23, 13, 'it worked it will eject.', colours.black), + Label:Initialise(23, 15, 'Make sure you hide this', colours.red), + Label:Initialise(23, 16, 'computer away from the', colours.red), + Label:Initialise(23, 17, 'door! (other people)', colours.red) + } + for i, v in ipairs(helpLines) do + table.insert(Current.PageControls, v) + end + + + table.insert(Current.PageControls, Button:Initialise(2, 14, nil, nil, nil, nil, function() + for i = 1, 6 do + helpLines[i].TextColour = colours.green + end + end, 'Register New PDA', colours.black)) + +end + +function HostStatusPage() + ResetPage() + Current.Page = 'HostStatus' + Current.StatusScreen = true + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostSetup, 'Settings/Help', colours.black) + + Wireless.Responder = function(event, side, channel, replyChannel, message, distance) + if channel == Wireless.Channels.UltimateDoorlockRequest and distance < Current.Settings.Distance then + if FingerprintIsOnWhitelist(message.content) then + OpenDoor() + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, true) + else + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, false) + end + end + end + + PingPocketComputers() +end + +function HostInitialise() + if not Wireless.Present() then + Current.Locked = true + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, function()os.reboot()end, 'Reboot', colours.black) + ResetStatus() + return + end + Wireless.Initialise() + ResetStatus() + if fs.exists('.settings') then + local h = fs.open('.settings', 'r') + if h then + Current.Settings = textutils.unserialize(h.readAll()) + end + h.close() + HostStatusPage() + else + HostSetup() + end + if OneOS then + OneOS.CanClose = function() + CloseDoor() + return true + end + end +end + +local pingTimer = nil +function PingPocketComputers() + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockPing, 'Ping!', Wireless.Channels.UltimateDoorlockRequest) + pingTimer = os.startTimer(0.5) +end + +function Initialise(arg) + EventRegister('mouse_click', TryClick) + EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end) + EventRegister('mouse_scroll', Scroll) + EventRegister('key', HandleKey) + EventRegister('char', HandleKey) + EventRegister('timer', Timer) + EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end) + EventRegister('modem_message', Wireless.HandleMessage) + EventRegister('disk', RegisterPDA) + + if OneOS then + OneOS.RequestRunAtStartup() + end + + if pocket then + PocketInitialise() + else + HostInitialise() + end + + + Draw() + + EventHandler() +end + +function Timer(event, timer) + if timer == pingTimer then + PingPocketComputers() + elseif timer == closeDoorTimer then + CloseDoor() + elseif timer == statusResetTimer then + ResetStatus() + end +end + +local ignoreNextChar = false +function HandleKey(...) + local args = {...} + local event = args[1] + local keychar = args[2] + --[[ + --Mac left command character + if event == 'key' and keychar == keys.leftCtrl or keychar == keys.rightCtrl or keychar == 219 then + isControlPushed = true + controlPushedTimer = os.startTimer(0.5) + elseif isControlPushed then + if event == 'key' then + if CheckKeyboardShortcut(keychar) then + isControlPushed = false + ignoreNextChar = true + end + end + elseif ignoreNextChar then + ignoreNextChar = false + elseif Current.TextInput then + if event == 'char' then + Current.TextInput:Char(keychar) + elseif event == 'key' then + Current.TextInput:Key(keychar) + end + end + ]]-- +end + +--[[ + Check if the given object falls under the click coordinates +]]-- +function CheckClick(object, x, y) + if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then + return true + end +end + +--[[ + Attempt to clicka given object +]]-- +function DoClick(object, side, x, y, drag) + local obj = GetAbsolutePosition(object) + obj.Width = object.Width + obj.Height = object.Height + if object and CheckClick(obj, x, y) then + return object:Click(side, x - object.X + 1, y - object.Y + 1, drag) + end +end + +--[[ + Try to click at the given coordinates +]]-- +function TryClick(event, side, x, y, drag) + if Current.ButtonOne then + if DoClick(Current.ButtonOne, side, x, y, drag) then + Draw() + return + end + end + + if Current.ButtonTwo then + if DoClick(Current.ButtonTwo, side, x, y, drag) then + Draw() + return + end + end + + for i, v in ipairs(Current.PageControls) do + if DoClick(v, side, x, y, drag) then + Draw() + return + end + end + + Draw() +end + +function Scroll(event, direction, x, y) + if Current.Window and Current.Window.OpenButton then + Current.Document.Scroll = Current.Document.Scroll + direction + if Current.Window.Scroll < 0 then + Current.Window.Scroll = 0 + elseif Current.Window.Scroll > Current.Window.MaxScroll then + Current.Window.Scroll = Current.Window.MaxScroll + end + Draw() + elseif Current.ScrollBar then + if Current.ScrollBar:DoScroll(direction*2) then + Draw() + end + end +end + +--[[ + Registers functions to run on certain events +]]-- +function EventRegister(event, func) + if not Events[event] then + Events[event] = {} + end + + table.insert(Events[event], func) +end + +--[[ + The main loop event handler, runs registered event functinos +]]-- +function EventHandler() + while isRunning do + local event, arg1, arg2, arg3, arg4, arg5, arg6 = os.pullEventRaw() + if Events[event] then + for i, e in ipairs(Events[event]) do + e(event, arg1, arg2, arg3, arg4, arg5, arg6) + end + end + end +end + +function Quit() + isRunning = false + term.setCursorPos(1,1) + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.clear() + if OneOS then + OneOS.Close() + end +end + +if not term.current then -- if not 1.6 + print('Because it requires pocket computers, Ultimate Door Lock requires ComputerCraft 1.6. Please update to 1.6 to use Ultimate Door Lock.') +elseif not (OneOS and pocket) and term.isColor and term.isColor() then + -- If the program crashes close the door and reboot + local _, err = pcall(Initialise) + if err then + CloseDoor() + term.setCursorPos(1,1) + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.clear() + print('Ultimate Door Lock has crashed') + print('To maintain security, the computer will reboot.') + print('If you are seeing this alot try turning off all Pocket Computers or reinstall.') + print() + print('Error:') + printError(err) + sleep(5) + os.reboot() + end +elseif OneOS and pocket then + term.setCursorPos(1,3) + term.setBackgroundColour(colours.white) + term.setTextColour(colours.blue) + term.clear() + print('OneOS already acts as a door key. Simply place your PDA in the door\'s disk drive to register it.') + print() + print('To setup a door, run this program on an advanced computer (non-pocket).') + print() + print('Click anywhere to quit') + os.pullEvent('mouse_click') + Quit() +else + print('Ultimate Door Lock requires an advanced (gold) computer or pocket computer.') +end diff --git a/Secure OS/programs/autostart/config.lua b/Secure OS/programs/autostart/config.lua new file mode 100644 index 0000000..e7a5594 --- /dev/null +++ b/Secure OS/programs/autostart/config.lua @@ -0,0 +1,6 @@ +-- list of programs to autostart +return { + "desktop", + "menu", + "keyhandler" +} diff --git a/Secure OS/programs/autostart/init.lua b/Secure OS/programs/autostart/init.lua new file mode 100644 index 0000000..ce78aab --- /dev/null +++ b/Secure OS/programs/autostart/init.lua @@ -0,0 +1,4 @@ +local config = require "programs.autostart.config" +for _, programName in ipairs(config) do + processes:start(programName) +end diff --git a/Secure OS/programs/autostart/properties.lua b/Secure OS/programs/autostart/properties.lua new file mode 100644 index 0000000..32328e3 --- /dev/null +++ b/Secure OS/programs/autostart/properties.lua @@ -0,0 +1,3 @@ +return { + noWindow = true +} diff --git a/Secure OS/programs/desktop/init.lua b/Secure OS/programs/desktop/init.lua new file mode 100644 index 0000000..b83df36 --- /dev/null +++ b/Secure OS/programs/desktop/init.lua @@ -0,0 +1,5 @@ +while true do + term.setBackgroundColor(colors.white) + term.clear() + coroutine.yield() +end diff --git a/Secure OS/programs/desktop/properties.lua b/Secure OS/programs/desktop/properties.lua new file mode 100644 index 0000000..eec7ea5 --- /dev/null +++ b/Secure OS/programs/desktop/properties.lua @@ -0,0 +1,6 @@ +local w, h = term.native().getSize() +return { + x = 1, y = 1, + w = w, h = h, + noBar = true, noMove = true +} diff --git a/Secure OS/programs/keyhandler/init.lua b/Secure OS/programs/keyhandler/init.lua new file mode 100644 index 0000000..878bcf7 --- /dev/null +++ b/Secure OS/programs/keyhandler/init.lua @@ -0,0 +1,12 @@ +keyboard = {} + +while true do + local event, key = os.pullEvent() + if event == "char" then + keyboard.lastChar = key + elseif event == "key" then + keyboard[keys.getName(key)] = true + elseif event == "key_up" then + keyboard[keys.getName(key)] = false + end +end diff --git a/Secure OS/programs/keyhandler/properties.lua b/Secure OS/programs/keyhandler/properties.lua new file mode 100644 index 0000000..8039511 --- /dev/null +++ b/Secure OS/programs/keyhandler/properties.lua @@ -0,0 +1,4 @@ +return { + x = 1, y = 3, w = 20, h = 2, + noWindow = true +} diff --git a/Secure OS/programs/menu/init.lua b/Secure OS/programs/menu/init.lua new file mode 100644 index 0000000..9152d1b --- /dev/null +++ b/Secure OS/programs/menu/init.lua @@ -0,0 +1,45 @@ +local itemNames = fs.list("/programs/menu/items") +local items = {} +local nextX = 2 + +for _, itemName in ipairs(itemNames) do + local itemFunc = loadfile("/programs/menu/items/"..itemName, _ENV) + local item = itemFunc() + local itemWindow = window.create(term.current(), nextX, 1, item.w, 1) + + table.insert(items, { + term = itemWindow, + update = function(self, event, var1, var2, var3) + local oldTerm = term.redirect(self.term) + + term.setBackgroundColor(colors.lightGray) + term.setTextColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + item.update(event, var1, var2, var3) + + term.redirect(oldTerm) + end + }) + + nextX = nextX+item.w+1 +end + +while true do + local event, var1, var2, var3 = os.pullEvent() + + + term.setBackgroundColor(colors.lightGray) + term.clear() + term.setCursorPos(1, 1) + for _, item in ipairs(items) do + local var1, var2, var3 = var1, var2, var3 + + if string.sub(event, 1, #"mouse") == "mouse" then + local x, y = item.term.getPosition() + var2 = var2-x+1 + var3 = var3-y+1 + end + item:update(event, var1, var2, var3) + end +end diff --git a/Secure OS/programs/menu/items/clock.lua b/Secure OS/programs/menu/items/clock.lua new file mode 100644 index 0000000..ff94c56 --- /dev/null +++ b/Secure OS/programs/menu/items/clock.lua @@ -0,0 +1,6 @@ +return { + w = 5, + update = function() + term.write(textutils.formatTime(os.time())) + end +} diff --git a/Secure OS/programs/menu/items/launcher.lua b/Secure OS/programs/menu/items/launcher.lua new file mode 100644 index 0000000..6440d6f --- /dev/null +++ b/Secure OS/programs/menu/items/launcher.lua @@ -0,0 +1,52 @@ +local programs = { + { + exec = "worm", + icon = {"\141\136", "de", "ff"} + }, + { + exec = "paint image", + icon = {"\152\135", "ce", "ff"} + }, + { + exec = "edit text", + icon = {"ed", "44", "ff"} + }, + { + exec = "shell", + icon = {">_", "40", "ff"} + }, + { + exec = "redirection", + icon = {"\136\133", "b8", "77"} + }, + { + exec = "adventure", + icon = {"?_", "40", "ff"} + }, + { + exec = "lua", + icon = {"lu", "00", "ff"} + }, + { + exec = "chat join lost_chat "..os.getComputerID(), + icon = {"\2\19", "00", "ff"} + }, + { + exec = "chat host lost_chat", + icon = {"\16\19", "00", "ff"} + } +} + +return { + w = #programs*3, + update = function(event, var1, var2, var3) + for programNum, program in ipairs(programs) do + + if event == "mouse_click" and var3 == 1 and (var2 == (programNum-1)*3+1 or var2 == (programNum-1)*3+2) then + processes:run(program.exec) + end + term.blit(program.icon[1], program.icon[2], program.icon[3]) + term.write(" ") + end + end +} diff --git a/Secure OS/programs/menu/properties.lua b/Secure OS/programs/menu/properties.lua new file mode 100644 index 0000000..e0c063e --- /dev/null +++ b/Secure OS/programs/menu/properties.lua @@ -0,0 +1,5 @@ +return { + x = 1, y = 1, + w = term.native().getSize(), h = 1, + noBar = true, noMove = true, noResize = true +} diff --git a/Secure OS/secure.lua b/Secure OS/secure.lua new file mode 100644 index 0000000..f8190b0 --- /dev/null +++ b/Secure OS/secure.lua @@ -0,0 +1,89 @@ +local branches = { + "master", + "experimental" +} + + +local function formatFS() + local function mkdir(dir) + if not fs.exists(dir) then fs.makeDir(dir) end + end + if fs.exists("AxiomUI") then + for k, v in pairs(fs.list("AxiomUI")) do + if not fs.exists(v) then + fs.move("AxiomUI/"..v, v) + print("AxiomUI/"..v.." -> "..v) + else + print("AxiomUI/"..v.." -x>") + end + end + fs.delete("AxiomUI") + print("Delete extra files?") + if read() == "y" then + fs.delete("install.lua") + fs.delete("README.md") + end + else + error("formatFS failed") + end +end +local function wget(url, file) + local data = http.get(url) + data = data.readAll() + local file_handle = fs.open(file,"w") + file_handle.write(data) + file_handle.close() +end +function selector(y,option) + term.setCursorPos(1,y) + for k,v in ipairs(branches) do + if k == option then + write(v.. " <-") + term.setCursorPos(1,y+k) + else + write(v.. " ") + term.setCursorPos(1,y+k) + end + end +end +local version = os.version() +if version == "CraftOS 1.5" then + error("Axiom is not compatible with "..version.."!") +end +print("Axiom UI CE Installer") +print("Select a branch using arrow keys") +local x,y = term.getCursorPos() +if y > 17 then + shell.run("clear") + print("Axiom UI CE Installer") + print("Select a branch using arrow keys") + x,y = term.getCursorPos() +end +selector(y,1) +local user = "nothjarnan" +local branch = 1 +while(true) do + local e,k,h = os.pullEvent( "key" ) + if k == keys.up then + if branch > 1 then + branch = branch - 1 + selector(y,branch) + end + end + if k == keys.down then + if branch < #branches then + branch = branch + 1 + selector(y,branch) + end + end + if k == keys.enter then + branch = branches[branch] + print("Branch selected: "..branch) + print("Starting installation") + break + end +end +wget("http://www.pastebin.com/raw/w5zkvysi",".gitget") +shell.run(".gitget "..user.." axiom-opensource "..branch.." AxiomUI") +formatFS() +print("Installation completed!") diff --git a/SecurePdaDoor/SecureDoor b/SecurePdaDoor/SecureDoor new file mode 100644 index 0000000..2d47f34 --- /dev/null +++ b/SecurePdaDoor/SecureDoor @@ -0,0 +1,1348 @@ +tArgs = {...} + +if OneOS then + --running under OneOS + OneOS.ToolBarColour = colours.black + OneOS.ToolBarTextColour = colours.blue +end + +local _w, _h = term.getSize() + +local round = function(num, idp) + local mult = 10^(idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +InterfaceElements = {} + +Drawing = { + + Screen = { + Width = _w, + Height = _h + }, + + DrawCharacters = function (x, y, characters, textColour,bgColour) + Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour) + end, + + DrawBlankArea = function (x, y, w, h, colour) + Drawing.DrawArea (x, y, w, h, " ", 1, colour) + end, + + DrawArea = function (x, y, w, h, character, textColour, bgColour) + --width must be greater than 1, other wise we get a stack overflow + if w < 0 then + w = w * -1 + elseif w == 0 then + w = 1 + end + + for ix = 1, w do + local currX = x + ix - 1 + for iy = 1, h do + local currY = y + iy - 1 + Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour) + end + end + end, + + DrawImage = function(_x,_y,tImage, w, h) + if tImage then + for y = 1, h do + if not tImage[y] then + break + end + for x = 1, w do + if not tImage[y][x] then + break + end + local bgColour = tImage[y][x] + local textColour = tImage.textcol[y][x] or colours.white + local char = tImage.text[y][x] + Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour) + end + end + elseif w and h then + Drawing.DrawBlankArea(x, y, w, h, colours.green) + end + end, + --using .nft + LoadImage = function(path) + local image = { + text = {}, + textcol = {} + } + local fs = fs + if OneOS then + fs = OneOS.FS + end + if fs.exists(path) then + local _open = io.open + if OneOS then + _open = OneOS.IO.open + end + local file = _open(path, "r") + local sLine = file:read() + local num = 1 + while sLine do + table.insert(image, num, {}) + table.insert(image.text, num, {}) + table.insert(image.textcol, num, {}) + + --As we're no longer 1-1, we keep track of what index to write to + local writeIndex = 1 + --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour + local bgNext, fgNext = false, false + --The current background and foreground colours + local currBG, currFG = nil,nil + for i=1,#sLine do + local nextChar = string.sub(sLine, i, i) + if nextChar:byte() == 30 then + bgNext = true + elseif nextChar:byte() == 31 then + fgNext = true + elseif bgNext then + currBG = Drawing.GetColour(nextChar) + bgNext = false + elseif fgNext then + currFG = Drawing.GetColour(nextChar) + fgNext = false + else + if nextChar ~= " " and currFG == nil then + currFG = colours.green + end + image[num][writeIndex] = currBG + image.textcol[num][writeIndex] = currFG + image.text[num][writeIndex] = nextChar + writeIndex = writeIndex + 1 + end + end + num = num+1 + sLine = file:read() + end + file:close() + end + return image + end, + + DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour) + w = w or Drawing.Screen.Width + h = h or Drawing.Screen.Height + x = x or 0 + y = y or 0 + x = math.ceil((w - #characters) / 2) + x + y = math.floor(h / 2) + y + + Drawing.DrawCharacters(x, y, characters, textColour, bgColour) + end, + + GetColour = function(hex) + if hex == ' ' then + return colours.transparent + end + local value = tonumber(hex, 16) + if not value then return nil end + value = math.pow(2,value) + return value + end, + + Clear = function (_colour) + _colour = _colour or colours.white + Drawing.ClearBuffer() + Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour) + end, + + Buffer = {}, + BackBuffer = {}, + + DrawBuffer = function() + for y,row in pairs(Drawing.Buffer) do + for x,pixel in pairs(row) do + local shouldDraw = true + local hasBackBuffer = true + if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then + hasBackBuffer = false + end + if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then + shouldDraw = false + end + if shouldDraw then + term.setBackgroundColour(pixel[3]) + term.setTextColour(pixel[2]) + term.setCursorPos(x, y) + term.write(pixel[1]) + end + end + end + Drawing.BackBuffer = Drawing.Buffer + Drawing.Buffer = {} + term.setCursorPos(1,1) + end, + + ClearBuffer = function() + Drawing.Buffer = {} + end, + + WriteStringToBuffer = function (x, y, characters, textColour,bgColour) + for i = 1, #characters do + local character = characters:sub(i,i) + Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour) + end + end, + + WriteToBuffer = function(x, y, character, textColour,bgColour) + x = round(x) + y = round(y) + if bgColour == colours.transparent then + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black} + Drawing.Buffer[y][x][1] = character + Drawing.Buffer[y][x][2] = textColour + else + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = {character, textColour, bgColour} + end + end, +} + +Current = { + Document = nil, + TextInput = nil, + CursorPos = {1,1}, + CursorColour = colours.black, + Selection = {8, 36}, + Window = nil, + HeaderText = '', + StatusText = '', + StatusColour = colours.grey, + StatusScreen = true, + ButtonOne = nil, + ButtonTwo = nil, + Locked = false, + Page = '', + PageControls = {} +} + +isRunning = true + +Events = {} + +Button = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.white, + ActiveBackgroundColour = colours.lightGrey, + Text = "", + Parent = nil, + _Click = nil, + Toggle = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local bg = self.BackgroundColour + local tc = self.TextColour + if type(bg) == 'function' then + bg = bg() + end + + if self.Toggle then + tc = colours.white + bg = self.ActiveBackgroundColour + end + + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg) + Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg) + end, + + Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.Text = text or "" + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.white + new.ActiveBackgroundColour = activeBackgroundColour or colours.lightBlue + new.Parent = parent + new._Click = click + new.Toggle = toggle + return new + end, + + Click = function(self, side, x, y) + if self._Click then + if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then + self.Toggle = not self.Toggle + Draw() + end + return true + else + return false + end + end +} + +Label = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.white, + Text = "", + Parent = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local bg = self.BackgroundColour + local tc = self.TextColour + + if self.Toggle then + tc = UIColours.MenuBarActive + bg = self.ActiveBackgroundColour + end + + local pos = GetAbsolutePosition(self) + Drawing.DrawCharacters(pos.X, pos.Y, self.Text, self.TextColour, self.BackgroundColour) + end, + + Initialise = function(self, x, y, text, textColour, backgroundColour, parent) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.Text = text or "" + new.BackgroundColour = backgroundColour or colours.white + new.TextColour = textColour or colours.black + new.Parent = parent + return new + end, + + Click = function(self, side, x, y) + return false + end +} + +TextBox = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.black, + Parent = nil, + TextInput = nil, + Placeholder = '', + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour) + local text = self.TextInput.Value + if #tostring(text) > (self.Width - 2) then + text = text:sub(#text-(self.Width - 3)) + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y} + end + else + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y} + end + end + + if #tostring(text) == 0 then + Drawing.DrawCharacters(pos.X + 1, pos.Y, self.Placeholder, colours.lightGrey, self.BackgroundColour) + else + Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour) + end + + term.setCursorBlink(true) + + Current.CursorColour = self.TextColour + end, + + Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.TextInput = TextInput:Initialise(text or '', function(key) + if done then + done(key) + end + Draw() + end, numerical) + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.black + new.Parent = parent + return new + end, + + Click = function(self, side, x, y) + Current.Input = self.TextInput + self:Draw() + end +} + +TextInput = { + Value = "", + Change = nil, + CursorPos = nil, + Numerical = false, + IsDocument = nil, + + Initialise = function(self, value, change, numerical, isDocument) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Value = tostring(value) + new.Change = change + new.CursorPos = #tostring(value) + new.Numerical = numerical + new.IsDocument = isDocument or false + return new + end, + + Insert = function(self, str) + if self.Numerical then + str = tostring(tonumber(str)) + end + + local selection = OrderSelection() + + if self.IsDocument and selection then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. str .. string.sub( self.Value, selection[2]+2) + self.CursorPos = selection[1] + Current.Selection = nil + else + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub(self.Value, 1, self.CursorPos + newLineAdjust) .. str .. string.sub( self.Value, self.CursorPos + 1 + newLineAdjust) + self.CursorPos = self.CursorPos + 1 + end + + self.Change(key) + end, + + Extract = function(self, remove) + local selection = OrderSelection() + if self.IsDocument and selection then + local _, newLineAdjust = string.gsub(self.Value:sub(selection[1], selection[2]), '\n','') + local str = string.sub(self.Value, selection[1], selection[2]+1+newLineAdjust) + if remove then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. string.sub( self.Value, selection[2]+2+newLineAdjust) + self.CursorPos = selection[1] - 1 + Current.Selection = nil + end + return str + end + end, + + Char = function(self, char) + if char == 'nil' then + return + end + self:Insert(char) + end, + + Key = function(self, key) + if key == keys.enter then + if self.IsDocument then + self.Value = string.sub(self.Value, 1, self.CursorPos ) .. '\n' .. string.sub( self.Value, self.CursorPos + 1 ) + self.CursorPos = self.CursorPos + 1 + end + self.Change(key) + elseif key == keys.left then + -- Left + if self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + + elseif key == keys.right then + -- Right + if self.CursorPos < string.len(self.Value) then + local colShift = FindColours(string.sub( self.Value, self.CursorPos+1, self.CursorPos+1)) + self.CursorPos = self.CursorPos + 1 + colShift + self.Change(key) + end + + elseif key == keys.backspace then + -- Backspace + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub( self.Value, 1, self.CursorPos - 1 - colShift + newLineAdjust) .. string.sub( self.Value, self.CursorPos + 1 - colShift + newLineAdjust) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + elseif key == keys.home then + -- Home + self.CursorPos = 0 + self.Change(key) + elseif key == keys.delete then + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos < string.len(self.Value) then + self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 ) + self.Change(key) + end + elseif key == keys["end"] then + -- End + self.CursorPos = string.len(self.Value) + self.Change(key) + elseif key == keys.up and self.IsDocument then + -- Up + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY - 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + elseif key == keys.down and self.IsDocument then + -- Down + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY + 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + end + end +} + +local Capitalise = function(str) + return str:sub(1, 1):upper() .. str:sub(2, -1) +end + + +local getNames = peripheral.getNames or function() + local tResults = {} + for n,sSide in ipairs( rs.getSides() ) do + if peripheral.isPresent( sSide ) then + table.insert( tResults, sSide ) + local isWireless = false + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if peripheral.getType( sSide ) == "modem" and not isWireless then + local tRemote = peripheral.call( sSide, "getNamesRemote" ) + for n,sName in ipairs( tRemote ) do + table.insert( tResults, sName ) + end + end + end + end + return tResults +end + +Peripheral = { + GetPeripheral = function(_type) + for i, p in ipairs(Peripheral.GetPeripherals()) do + if p.Type == _type then + return p + end + end + end, + + Call = function(type, ...) + local tArgs = {...} + local p = Peripheral.GetPeripheral(type) + peripheral.call(p.Side, unpack(tArgs)) + end, + + GetPeripherals = function(filterType) + local peripherals = {} + for i, side in ipairs(getNames()) do + local name = peripheral.getType(side):gsub("^%l", string.upper) + local code = string.upper(side:sub(1,1)) + if side:find('_') then + code = side:sub(side:find('_')+1) + end + + local dupe = false + for i, v in ipairs(peripherals) do + if v[1] == name .. ' ' .. code then + dupe = true + end + end + + if not dupe then + local _type = peripheral.getType(side) + local isWireless = false + if _type == 'modem' then + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if isWireless then + _type = 'wireless_modem' + name = 'W '..name + end + end + if not filterType or _type == filterType then + table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..side:sub(1, 1):upper() .. side:sub(2, -1)..')', Side = side, Type = _type, Wireless = isWireless}) + end + end + end + return peripherals + end, + + PresentNamed = function(name) + return peripheral.isPresent(name) + end, + + CallType = function(type, ...) + local tArgs = {...} + local p = Peripheral.GetPeripheral(type) + return peripheral.call(p.Side, unpack(tArgs)) + end, + + CallNamed = function(name, ...) + local tArgs = {...} + return peripheral.call(name, unpack(tArgs)) + end +} + +Wireless = { + Channels = { + UltimateDoorlockPing = 4210, + UltimateDoorlockRequest = 4211, + UltimateDoorlockRequestReply = 4212, + }, + + isOpen = function(channel) + return Peripheral.CallType('wireless_modem', 'isOpen', channel) + end, + + Open = function(channel) + if not Wireless.isOpen(channel) then + Peripheral.CallType('wireless_modem', 'open', channel) + end + end, + + close = function(channel) + Peripheral.CallType('wireless_modem', 'close', channel) + end, + + closeAll = function() + Peripheral.CallType('wireless_modem', 'closeAll') + end, + + transmit = function(channel, replyChannel, message) + Peripheral.CallType('wireless_modem', 'transmit', channel, replyChannel, textutils.serialize(message)) + end, + + Present = function() + if Peripheral.GetPeripheral('wireless_modem') == nil then + return false + else + return true + end + end, + + FormatMessage = function(message, messageID, destinationID) + return { + content = textutils.serialize(message), + senderID = os.getComputerID(), + senderName = os.getComputerLabel(), + channel = channel, + replyChannel = reply, + messageID = messageID or math.random(10000), + destinationID = destinationID + } + end, + + Timeout = function(func, time) + time = time or 1 + parallel.waitForAny(func, function() + sleep(time) + --log('Timeout!'..time) + end) + end, + + RecieveMessage = function(_channel, messageID, timeout) + open(_channel) + local done = false + local event, side, channel, replyChannel, message = nil + Timeout(function() + while not done do + event, side, channel, replyChannel, message = os.pullEvent('modem_message') + if channel ~= _channel then + event, side, channel, replyChannel, message = nil + else + message = textutils.unserialize(message) + message.content = textutils.unserialize(message.content) + if messageID and messageID ~= message.messageID or (message.destinationID ~= nil and message.destinationID ~= os.getComputerID()) then + event, side, channel, replyChannel, message = nil + else + done = true + end + end + end + end, + timeout) + return event, side, channel, replyChannel, message + end, + + Initialise = function() + if Wireless.Present() then + for i, c in pairs(Wireless.Channels) do + Wireless.Open(c) + end + end + end, + + HandleMessage = function(event, side, channel, replyChannel, message, distance) + message = textutils.unserialize(message) + message.content = textutils.unserialize(message.content) + + if channel == Wireless.Channels.Ping then + if message.content == 'Ping!' then + SendMessage(replyChannel, 'Pong!', nil, message.messageID) + end + elseif message.destinationID ~= nil and message.destinationID ~= os.getComputerID() then + elseif Wireless.Responder then + Wireless.Responder(event, side, channel, replyChannel, message, distance) + end + end, + + SendMessage = function(channel, message, reply, messageID, destinationID) + reply = reply or channel + 1 + Wireless.Open(channel) + Wireless.Open(reply) + local _message = Wireless.FormatMessage(message, messageID, destinationID) + Wireless.transmit(channel, reply, _message) + return _message + end, + + Ping = function() + local message = SendMessage(Channels.Ping, 'Ping!', Channels.PingReply) + RecieveMessage(Channels.PingReply, message.messageID) + end +} + +function GetAbsolutePosition(object) + local obj = object + local i = 0 + local x = 1 + local y = 1 + while true do + x = x + obj.X - 1 + y = y + obj.Y - 1 + + if not obj.Parent then + return {X = x, Y = y} + end + + obj = obj.Parent + + if i > 32 then + return {X = 1, Y = 1} + end + + i = i + 1 + end + +end + +function Draw() + Drawing.Clear(colours.white) + + if Current.StatusScreen then + Drawing.DrawCharactersCenter(1, -2, nil, nil, Current.HeaderText, colours.blue, colours.white) + Drawing.DrawCharactersCenter(1, -1, nil, nil, 'by Outraged Security .INC', colours.lightGrey, colours.white) + Drawing.DrawCharactersCenter(1, 1, nil, nil, Current.StatusText, Current.StatusColour, colours.white) + end + + if Current.ButtonOne then + Current.ButtonOne:Draw() + end + + if Current.ButtonTwo then + Current.ButtonTwo:Draw() + end + + for i, v in ipairs(Current.PageControls) do + v:Draw() + end + + Drawing.DrawBuffer() + + if Current.TextInput and Current.CursorPos and not Current.Menu and not(Current.Window and Current.Document and Current.TextInput == Current.Document.TextInput) and Current.CursorPos[2] > 1 then + term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2]) + term.setCursorBlink(true) + term.setTextColour(Current.CursorColour) + else + term.setCursorBlink(false) + end +end +MainDraw = Draw + +function GenerateFingerprint() + local str = "" + for _ = 1, 256 do + local char = math.random(32, 126) + --if char == 96 then char = math.random(32, 95) end + str = str .. string.char(char) + end + return str +end + +function MakeFingerprint() + local h = fs.open('.fingerprint', 'w') + if h then + h.write(GenerateFingerprint()) + end + h.close() + Current.Fingerprint = str +end + +local drawTimer = nil +function SetText(header, status, colour, isReset) + if header then + Current.HeaderText = header + end + if status then + Current.StatusText = status + end + if colour then + Current.StatusColour = colour + end + Draw() + if not isReset then + statusResetTimer = os.startTimer(2) + end +end + +function ResetStatus() + if pocket then + if Current.Locked then + SetText('Ultimate Door Lock', 'Add Wireless Modem to PDA', colours.red, true) + else + SetText('Ultimate Door Lock', 'Ready', colours.grey, true) + end + else + if Current.Locked then + SetText('Ultimate Door Lock', ' Attach a Wireless Modem then reboot', colours.red, true) + else + SetText('Ultimate Door Lock', 'Ready', colours.grey, true) + end + end +end + +function ResetPage() + Wireless.Responder = function()end + pingTimer = nil + Current.PageControls = nil + Current.StatusScreen = false + Current.ButtonOne = nil + Current.ButtonTwo = nil + Current.PageControls = {} + CloseDoor() +end + +function PocketInitialise() + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + if not Wireless.Present() then + Current.Locked = true + ResetStatus() + return + end + Wireless.Initialise() + ResetStatus() + if fs.exists('.fingerprint') then + local h = fs.open('.fingerprint', 'r') + if h then + Current.Fingerprint = h.readAll() + else + MakeFingerprint() + end + h.close() + else + MakeFingerprint() + end + + Wireless.Responder = function(event, side, channel, replyChannel, message, distance) + if channel == Wireless.Channels.UltimateDoorlockPing then + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequest, Current.Fingerprint, Wireless.Channels.UltimateDoorlockRequestReply, nil, message.senderID) + elseif channel == Wireless.Channels.UltimateDoorlockRequestReply then + if message.content == true then + SetText(nil, 'Opening Door', colours.green) + else + SetText(nil, ' Access Denied', colours.red) + end + end + end +end + +function FingerprintIsOnWhitelist(fingerprint) + if Current.Settings.Whitelist then + for i, f in ipairs(Current.Settings.Whitelist) do + if f == fingerprint then + return true + end + end + end + return false +end + +function SaveSettings() + Current.Settings = Current.Settings or {} + local h = fs.open('.settings', 'w') + if h then + h.write(textutils.serialize(Current.Settings)) + end + h.close() +end + +local closeDoorTimer = nil +function OpenDoor() + if Current.Settings and Current.Settings.RedstoneSide then + SetText(nil, 'Opening Door', colours.green) + redstone.setOutput(Current.Settings.RedstoneSide, true) + closeDoorTimer = os.startTimer(0.6) + end +end + +function CloseDoor() + if Current.Settings and Current.Settings.RedstoneSide then + if redstone.getOutput(Current.Settings.RedstoneSide) then + SetText(nil, 'Closing Door', colours.orange) + redstone.setOutput(Current.Settings.RedstoneSide, false) + end + end +end + +DefaultSettings = { + Whitelist = {}, + RedstoneSide = 'back', + Distance = 10 +} + +function RegisterPDA(event, drive) + if disk.hasData(drive) then + local _fs = fs + if OneOS then + _fs = OneOS.FS + end + local path = disk.getMountPath(drive) + local addStartup = true + if _fs.exists(path..'/System/') then + path = path..'/System/' + addStartup = false + end + local fingerprint = nil + if _fs.exists(path..'/.fingerprint') then + local h = _fs.open(path..'/.fingerprint', 'r') + if h then + local str = h.readAll() + if #str == 256 then + fingerprint = str + end + end + h.close() + end + if not fingerprint then + fingerprint = GenerateFingerprint() + local h = _fs.open(path..'/.fingerprint', 'w') + h.write(fingerprint) + h.close() + if addStartup then + local h = fs.open(shell.getRunningProgram(), 'r') + local startup = h.readAll() + h.close() + local h = _fs.open(path..'/startup', 'w') + h.write(startup) + h.close() + end + end + if not FingerprintIsOnWhitelist(fingerprint) then + table.insert(Current.Settings.Whitelist, fingerprint) + SaveSettings() + end + disk.eject(drive) + SetText(nil, 'Registered Pocket Computer', colours.green) + end +end + +function HostSetup() + ResetPage() + Current.Page = 'HostSetup' + Current.ButtonTwo = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostStatusPage, 'Save', colours.black) + if not Current.Settings then + Current.Settings = DefaultSettings + end + + local sideButtons = {} + local function resetSideToggle(self) + for i, v in ipairs(sideButtons) do + if v.Toggle ~= nil then + v.Toggle = false + end + end + Current.Settings.RedstoneSide = self.Text:lower() + SaveSettings() + end + + table.insert(Current.PageControls, Label:Initialise(2, 2, 'Redstone Side')) + sideButtons = { + Button:Initialise(2, 4, nil, nil, nil, nil, resetSideToggle, 'Back', colours.black, false, colours.green), + Button:Initialise(9, 4, nil, nil, nil, nil, resetSideToggle, 'Front', colours.black, false, colours.green), + Button:Initialise(2, 6, nil, nil, nil, nil, resetSideToggle, 'Left', colours.black, false, colours.green), + Button:Initialise(9, 6, nil, nil, nil, nil, resetSideToggle, 'Right', colours.black, false, colours.green), + Button:Initialise(2, 8, nil, nil, nil, nil, resetSideToggle, 'Top', colours.black, false, colours.green), + Button:Initialise(8, 8, nil, nil, nil, nil, resetSideToggle, 'Bottom', colours.black, false, colours.green) + } + for i, v in ipairs(sideButtons) do + if v.Text:lower() == Current.Settings.RedstoneSide then + v.Toggle = true + end + table.insert(Current.PageControls, v) + end + + local distanceButtons = {} + local function resetDistanceToggle(self) + for i, v in ipairs(distanceButtons) do + if v.Toggle ~= nil then + v.Toggle = false + end + end + if self.Text == 'Small' then + Current.Settings.Distance = 5 + elseif self.Text == 'Normal' then + Current.Settings.Distance = 10 + elseif self.Text == 'Far' then + Current.Settings.Distance = 15 + end + SaveSettings() + end + + table.insert(Current.PageControls, Label:Initialise(23, 2, 'Opening Distance')) + distanceButtons = { + Button:Initialise(23, 4, nil, nil, nil, nil, resetDistanceToggle, 'Small', colours.black, false, colours.green), + Button:Initialise(31, 4, nil, nil, nil, nil, resetDistanceToggle, 'Normal', colours.black, false, colours.green), + Button:Initialise(40, 4, nil, nil, nil, nil, resetDistanceToggle, 'Far', colours.black, false, colours.green) + } + for i, v in ipairs(distanceButtons) do + if v.Text == 'Small' and Current.Settings.Distance == 5 then + v.Toggle = true + elseif v.Text == 'Normal' and Current.Settings.Distance == 10 then + v.Toggle = true + elseif v.Text == 'Far' and Current.Settings.Distance == 15 then + v.Toggle = true + end + table.insert(Current.PageControls, v) + end + + table.insert(Current.PageControls, Label:Initialise(2, 10, 'Registered PDAs: '..#Current.Settings.Whitelist)) + table.insert(Current.PageControls, Button:Initialise(2, 12, nil, nil, nil, nil, function()Current.Settings.Whitelist = {}HostSetup()end, 'Unregister All', colours.black)) + + + table.insert(Current.PageControls, Label:Initialise(23, 6, 'Help', colours.black)) + local helpLines = { + Label:Initialise(23, 8, 'To register a new PDA simply', colours.black), + Label:Initialise(23, 9, 'place a Disk Drive next to', colours.black), + Label:Initialise(23, 10, 'the computer, then put the', colours.black), + Label:Initialise(23, 11, 'PDA in the Drive, it will', colours.black), + Label:Initialise(23, 12, 'register automatically. If', colours.black), + Label:Initialise(23, 13, 'it worked it will eject.', colours.black), + Label:Initialise(23, 15, 'Make sure you hide this', colours.red), + Label:Initialise(23, 16, 'computer away from the', colours.red), + Label:Initialise(23, 17, 'door! (other people)', colours.red) + } + for i, v in ipairs(helpLines) do + table.insert(Current.PageControls, v) + end + + + table.insert(Current.PageControls, Button:Initialise(2, 14, nil, nil, nil, nil, function() + for i = 1, 6 do + helpLines[i].TextColour = colours.green + end + end, 'Register New PDA', colours.black)) + +end + +function HostStatusPage() + ResetPage() + Current.Page = 'HostStatus' + Current.StatusScreen = true + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, HostSetup, 'Settings/Help', colours.black) + + Wireless.Responder = function(event, side, channel, replyChannel, message, distance) + if channel == Wireless.Channels.UltimateDoorlockRequest and distance < Current.Settings.Distance then + if FingerprintIsOnWhitelist(message.content) then + OpenDoor() + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, true) + else + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockRequestReply, false) + end + end + end + + PingPocketComputers() +end + +function HostInitialise() + if not Wireless.Present() then + Current.Locked = true + Current.ButtonOne = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height - 1, nil, nil, nil, nil, Quit, 'Quit', colours.black) + Current.ButtonTwo = Button:Initialise(2, Drawing.Screen.Height - 1, nil, nil, nil, nil, function()os.reboot()end, 'Reboot', colours.black) + ResetStatus() + return + end + Wireless.Initialise() + ResetStatus() + if fs.exists('.settings') then + local h = fs.open('.settings', 'r') + if h then + Current.Settings = textutils.unserialize(h.readAll()) + end + h.close() + HostStatusPage() + else + HostSetup() + end + if OneOS then + OneOS.CanClose = function() + CloseDoor() + return true + end + end +end + +local pingTimer = nil +function PingPocketComputers() + Wireless.SendMessage(Wireless.Channels.UltimateDoorlockPing, 'Ping!', Wireless.Channels.UltimateDoorlockRequest) + pingTimer = os.startTimer(0.5) +end + +function Initialise(arg) + EventRegister('mouse_click', TryClick) + EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end) + EventRegister('mouse_scroll', Scroll) + EventRegister('key', HandleKey) + EventRegister('char', HandleKey) + EventRegister('timer', Timer) + EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end) + EventRegister('modem_message', Wireless.HandleMessage) + EventRegister('disk', RegisterPDA) + + if OneOS then + OneOS.RequestRunAtStartup() + end + + if pocket then + PocketInitialise() + else + HostInitialise() + end + + + Draw() + + EventHandler() +end + +function Timer(event, timer) + if timer == pingTimer then + PingPocketComputers() + elseif timer == closeDoorTimer then + CloseDoor() + elseif timer == statusResetTimer then + ResetStatus() + end +end + +local ignoreNextChar = false +function HandleKey(...) + local args = {...} + local event = args[1] + local keychar = args[2] + --[[ + --Mac left command character + if event == 'key' and keychar == keys.leftCtrl or keychar == keys.rightCtrl or keychar == 219 then + isControlPushed = true + controlPushedTimer = os.startTimer(0.5) + elseif isControlPushed then + if event == 'key' then + if CheckKeyboardShortcut(keychar) then + isControlPushed = false + ignoreNextChar = true + end + end + elseif ignoreNextChar then + ignoreNextChar = false + elseif Current.TextInput then + if event == 'char' then + Current.TextInput:Char(keychar) + elseif event == 'key' then + Current.TextInput:Key(keychar) + end + end + ]]-- +end + +--[[ + Check if the given object falls under the click coordinates +]]-- +function CheckClick(object, x, y) + if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then + return true + end +end + +--[[ + Attempt to clicka given object +]]-- +function DoClick(object, side, x, y, drag) + local obj = GetAbsolutePosition(object) + obj.Width = object.Width + obj.Height = object.Height + if object and CheckClick(obj, x, y) then + return object:Click(side, x - object.X + 1, y - object.Y + 1, drag) + end +end + +--[[ + Try to click at the given coordinates +]]-- +function TryClick(event, side, x, y, drag) + if Current.ButtonOne then + if DoClick(Current.ButtonOne, side, x, y, drag) then + Draw() + return + end + end + + if Current.ButtonTwo then + if DoClick(Current.ButtonTwo, side, x, y, drag) then + Draw() + return + end + end + + for i, v in ipairs(Current.PageControls) do + if DoClick(v, side, x, y, drag) then + Draw() + return + end + end + + Draw() +end + +function Scroll(event, direction, x, y) + if Current.Window and Current.Window.OpenButton then + Current.Document.Scroll = Current.Document.Scroll + direction + if Current.Window.Scroll < 0 then + Current.Window.Scroll = 0 + elseif Current.Window.Scroll > Current.Window.MaxScroll then + Current.Window.Scroll = Current.Window.MaxScroll + end + Draw() + elseif Current.ScrollBar then + if Current.ScrollBar:DoScroll(direction*2) then + Draw() + end + end +end + +--[[ + Registers functions to run on certain events +]]-- +function EventRegister(event, func) + if not Events[event] then + Events[event] = {} + end + + table.insert(Events[event], func) +end + +--[[ + The main loop event handler, runs registered event functinos +]]-- +function EventHandler() + while isRunning do + local event, arg1, arg2, arg3, arg4, arg5, arg6 = os.pullEventRaw() + if Events[event] then + for i, e in ipairs(Events[event]) do + e(event, arg1, arg2, arg3, arg4, arg5, arg6) + end + end + end +end + +function Quit() + isRunning = false + term.setCursorPos(1,1) + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.clear() + if OneOS then + OneOS.Close() + end +end + +if not term.current then -- if not 1.6 + print('Because it requires pocket computers, Ultimate Door Lock requires ComputerCraft 1.6. Please update to 1.6 to use Ultimate Door Lock.') +elseif not (OneOS and pocket) and term.isColor and term.isColor() then + -- If the program crashes close the door and reboot + local _, err = pcall(Initialise) + if err then + CloseDoor() + term.setCursorPos(1,1) + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.clear() + print('Ultimate Door Lock has crashed') + print('To maintain security, the computer will reboot.') + print('If you are seeing this alot try turning off all Pocket Computers or reinstall.') + print() + print('Error:') + printError(err) + sleep(5) + os.reboot() + end +elseif OneOS and pocket then + term.setCursorPos(1,3) + term.setBackgroundColour(colours.white) + term.setTextColour(colours.blue) + term.clear() + print('OneOS already acts as a door key. Simply place your PDA in the door\'s disk drive to register it.') + print() + print('To setup a door, run this program on an advanced computer (non-pocket).') + print() + print('Click anywhere to quit') + os.pullEvent('mouse_click') + Quit() +else + print('Ultimate Door Lock requires an advanced (gold) computer or pocket computer.') +end diff --git a/api/dark.lua b/api/dark.lua index 05a5dbd..9e5b627 100644 --- a/api/dark.lua +++ b/api/dark.lua @@ -126,7 +126,7 @@ function getPBFile(PBCode, uPath) -- pastebin code of the file, and path to save end function gitUpdate(ProgramName, Filename, ProgramVersion) if http then - local status, getGit = pcall(http.get,"https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") + local status, getGit = pcall(http.get,"https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/programVersions") if not status then return false end @@ -372,4 +372,4 @@ function repdeCrypt(Input, numHash) i = i + 1 until Input:byte(i) == nil return dec -end \ No newline at end of file +end diff --git a/api/darkfile.lua b/api/darkfile.lua index 1e2ad51..ad75eac 100644 --- a/api/darkfile.lua +++ b/api/darkfile.lua @@ -3,7 +3,7 @@ version = 1.101 function checkUpdate() if http then - local getGit = http.get("https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") + local getGit = http.get("https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/programVersions") local getGit = getGit.readAll() NVersion = textutils.unserialize(getGit) if NVersion["darkfile"].Version > version then diff --git a/chat.lua b/chat.lua index fb52623..0f84d68 100644 --- a/chat.lua +++ b/chat.lua @@ -1,461 +1,164 @@ ---Args -args = {...} ---[[ - optional arguments - 1: username - 2: channel (default will be 10) - 3: autoupdate (false to disable) -]]-- ---changeable -HistoryNum = 200 --how many lines of history to keep -if args[3] and args[3] == "false" then - autoupdate = false -else - autoupdate = true -- turn on or off auto update -end ---Non changeable! -chat = {} -lineCount = 1 -modifier = 0 -X, Y = term.getSize() -Version = 1.51 -BottomText = "Message: " -KeyCount = 0 -user = "" -Header = "Welcome to darkchat "..Version.."!" -function findPeripheral(Perihp) - for _,s in ipairs(rs.getSides()) do - if peripheral.isPresent(s) and peripheral.getType(s) == Perihp then - return s - end - end - return false -end -function gitUpdate(ProgramName, Filename, ProgramVersion) - if http then - status, getGit = pcall(http.get, "https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") - if not status then - return(getGit) - end - local getGit = getGit.readAll() - NVersion = textutils.unserialize(getGit) - if NVersion[ProgramName].Version > ProgramVersion then - getGit = http.get(NVersion[ProgramName].GitURL) - getGit = getGit.readAll() - local file = fs.open(Filename, "w") - file.write(getGit) - file.close() - return true - end - else - return false - end -end -function split(str, pattern) -- Splits string by pattern, returns table - local t = { } - local fpat = "(.-)" .. pattern - local last_end = 1 - local s, e, cap = str:find(fpat, 1) - while s do - if s ~= 1 or cap ~= "" then - table.insert(t,cap) - end - last_end = e+1 - s, e, cap = str:find(fpat, last_end) - end - if last_end <= #str then - cap = str:sub(last_end) - table.insert(t, cap) - end - return t -end -function cWrite(Text, bgcolor, tecolor, solid) - if term.isColor() == true then - term.setBackgroundColor(colors[bgcolor]) - term.setTextColor(colors[tecolor]) - if solid then - term.write(string.rep(" ", #Text)) - else - term.write(Text) - end - else - term.write(Text) - end -end -function bgReset() - if term.isColor() == true then - term.setTextColor(colors.white) - term.setBackgroundColor(colors.black) - end -end -function rSend(message, special, hidden) - local messaget = {} - messaget.user = user - messaget.message = message - messaget.darkchat = true - messaget.id = os.getComputerID() - if special then messaget.special = true end - messaget = textutils.serialize(messaget) - modem.transmit(channelN,channelN,messaget) - if not hidden then - if special then - os.queueEvent("tableInsert", "yellow#* "..user.." "..message) - else - os.queueEvent("tableInsert", "white#"..user..": "..message) - end - end -end -function rReceive() - local darkchat = false - repeat - _,_,C,rC,M,D = os.pullEvent("modem_message") - M = textutils.unserialize(M) - if type(M) == "table" and M.darkchat then - darkchat = true - elseif type(M) == "table" and M.list then - local list = {} - list.user = user - list.reply = true - list = textutils.serialize(list) - modem.transmit(channelN,channelN,list) - elseif type(M) == "table" and M.reply then - os.queueEvent("user",M.user) - end - until darkchat == true - return M -end -function modiferMod(operation, amount) -- if operation is true, number will be added else subtacted - if operation == true then - if lineCount - modifier > 1 then - modifier = modifier + 1 - end - else - if modifier > 0 then - modifier = modifier - 1 - end - end -end -function clears() - for i = 1, Y - 2 do - term.setCursorPos(1,i) - term.write(string.rep(" ", X)) - end +os.pullEvent = os.pullEventRaw + +local isPocket = false +if pocket then + isPocket = true end -function getChat() - draw() - while true do - m = rReceive() - if m.id ~= os.getComputerID() and m.user ~= user and m.message then - if m.special then - os.queueEvent("tableInsert", "yellow#* ".. m.user .. " " .. m.message) - else - os.queueEvent("tableInsert", "white#" .. m.user ..": ".. m.message) - end + +local msg = "" +local MH = {} +local historyFilePath = "/.chat_history" +local nameFilePath = "/.chat_username" +local modemSide = nil + +-- Load chat history from file if available +if fs.exists(historyFilePath) then + local file = fs.open(historyFilePath, "r") + local line = file.readLine() + while line do + table.insert(MH, 1, line) -- Insert at the beginning for newest messages at the bottom + line = file.readLine() end - end -end -function draw() - bgReset() clears() - if #chat > HistoryNum then table.remove(chat, 1) end - if #chat > Y - 2 then - lineCount = ((#chat) - (Y - 3)) - end - for i = lineCount - modifier, #chat - modifier do - chatN = split(chat[i], "#") - term.setCursorPos(1,i - lineCount+1+modifier) - cWrite(chatN[2],"black",chatN[1]) - end - term.setCursorPos(1, Y - 1) - cWrite(string.rep("-", X), "blue","blue", true) - term.setTextColor(colors.white) - local Text = " " - term.setCursorPos(X/2 - #Text/2, Y - 1) - write(Text) - if modifier > 0 and term.isColor() == true then - paintutils.drawPixel(1, Y - 1, colors.yellow) - paintutils.drawPixel(X, Y - 1, colors.yellow) - end - bgReset() - term.setCursorPos(#BottomText + KeyCount + 1, Y) - return true + file.close() end -function sendChat() - while true do - term.setCursorPos(1, Y) - term.write(BottomText) - message = read() - if string.sub(message,1,1) == "/" then - commandS = string.sub(message,2,#message) - commandS = split(commandS, " ") - if comD[commandS[1]] then - comD[commandS[1]].run(commandS) - else - os.queueEvent("tableInsert", "red#Unknown Command") - end - elseif message == "" then - draw() - elseif message then - rSend(message) - draw() - end - end + +-- Check if the name is saved in a file, otherwise ask the user to enter it +if fs.exists(nameFilePath) then + local file = fs.open(nameFilePath, "r") + name = file.readLine() + file.close() +else + term.write("Name: ") + name = read() + local file = fs.open(nameFilePath, "w") + file.writeLine(name) + file.close() end -function keyListen() - while true do - Type, KEY = os.pullEvent("key") - if KEY == 28 then - KeyCount = 0 - elseif KEY == 14 then - if KeyCount ~= 0 then - KeyCount = KeyCount - 1 - end - elseif KEY then - if KEY ~= 54 then - KeyCount = KeyCount + 1 - end + +-- Detect modem side +for _, side in ipairs(rs.getSides()) do + if peripheral.getType(side) == "modem" then + modemSide = side + break end - end end -function startUp() - term.clear() term.setCursorPos(1,1) - if autoupdate == true then - print("Checking for updates...") - local updateStatus = gitUpdate("chat", shell.getRunningProgram(), Version) - if type(updateStatus) == "string" then - print("Cannot check for updates:") - print(updateStatus) - sleep(1) - elseif updateStatus == true then - print("Downloaded new version, restarting...") - sleep(1.5) - os.reboot() - else - print("You're running the latest version") - sleep(1) - end - end - Side = findPeripheral("modem") - if not Side then - print("no modem.") - return exit - end - modem = peripheral.wrap(Side) - term.clear() term.setCursorPos(1,1) - cWrite(string.rep("-", X), "blue","blue", true) bgReset() - term.setCursorPos(X/2 - string.len(Header)/2,2) - print(Header) - cWrite(string.rep("-", X), "blue","blue", true) bgReset() + +if not modemSide then + error("No modem detected. Please attach a modem.") end -function privateMode() - user = config.user - channelN = config.channel + +local function clear() + term.clear() + local _, y = term.getSize() + term.setCursorPos(1, y) end -function publicMode() - repeat - write("Nickname: ") - user = read() - if user == "" then - print("\nInvalid Name") + +local function saveHistory() + local file = fs.open(historyFilePath, "w") + for _, line in ipairs(MH) do + file.writeLine(line) end - until user ~= "" - print("\nDefault channel is 10") - write("Channel: ") - channelN = read() - if not tonumber(channelN) then - channelN = "10" - end + file.close() end -function getOnlineList() - while true do - os.pullEvent("grabList") - local com = {} - local Users = "" - com.list = true - com = textutils.serialize(com) - modem.transmit(channelN,channelN,com) - os.startTimer(2) - repeat - local e, u = os.pullEvent() - if e == "user" then - Users = Users..u..", " - end - until e == "timer" - Users = string.sub(Users, 1, #Users - 2) -- remove extra comma - os.queueEvent("tableInsert", "yellow#Users in channel: "..Users) - end + +local function send(MSg) + rednet.broadcast(name .. ": " .. MSg) end -function scrollingEventListen() - while true do - local _,direction = os.pullEvent("mouse_scroll") - if direction == -1 then - modiferMod(true, 1) - draw() - else - modiferMod(false, 1) - draw() +local function drawScreen(Msg) + clear() + local i = 18 + while i >= 0 do + if MH[i] ~= nil then + print(MH[i]) + end + i = i - 1 end - end + print(Msg) end -function tableEventListen() - while true do - local e, mess = os.pullEvent("tableInsert") - if modifier > 0 and HistoryNum ~= #chat then - modifier = modifier + 1 + +local function clearOldMessages() + local currentTime = os.time() + local maxAge = 2 * 24 * 60 * 60 -- 2 days in seconds + + local newMH = {} + for _, line in ipairs(MH) do + local timestamp = tonumber(line:match("^%[(%d+)%]")) + if not timestamp or currentTime - timestamp <= maxAge then + table.insert(newMH, line) + end end - table.insert(chat, mess) - draw() - end + + MH = newMH + saveHistory() end -function exitEventListen() - while true do - os.pullEvent("exit") - term.clear() - term.setCursorPos(1,1) - modem.closeAll() - return exit - end + +local function deleteHistory() + MH = {} + saveHistory() end -function helpGen() - os.queueEvent("tableInsert", "lime#".. string.rep("-", X / 2 - 4) .. " help " .. string.rep("-", X / 2 - 3)) - for i, v in pairs(comD) do - if v.help then - os.queueEvent("tableInsert", "lime#/"..i.." ".. v.help) + +local function runTime() + rednet.open(modemSide) + + local historyStart = 1 + local linesToShow = isPocket and 5 or 18 + local screenLines = term.getSize() + + while true do + clear() + + term.setCursorPos(1, 1) + term.write("Wireless One Chat") + + local historyCount = #MH + local historyEnd = historyCount + local historyBegin = math.max(1, historyCount - linesToShow + 1) + + for i = historyBegin + historyStart - 1, historyEnd + historyStart - 1 do + term.setCursorPos(1, screenLines - (i - historyStart + 1)) + term.write(MH[i]) + end + + drawScreen("Enter a message: " .. msg) + + local event, a, b, c = os.pullEvent() + + if event == "char" then + msg = msg .. a + drawScreen("Enter a message: " .. msg) + elseif event == "key" then + if a == keys.backspace then + msg = msg:sub(1, #msg - 1) + drawScreen("Enter a message: " .. msg) + elseif a == keys.enter then + if msg ~= "" then + send(msg) + table.insert(MH, 1, name .. ": " .. msg) + saveHistory() + msg = "" + drawScreen("Enter a message: " .. msg) + end + elseif a == keys.up then + historyStart = math.max(1, historyStart - 1) + elseif a == keys.down then + historyStart = math.min(historyCount - linesToShow + 1, historyStart + 1) + elseif a == keys.d and c == true then + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.red) + term.write("Delete chat history? (Y/N): ") + local confirmation = read():lower() + if confirmation == "y" then + deleteHistory() + end + end + elseif event == "rednet_message" then + table.insert(MH, 1, "[" .. os.time() .. "] " .. b) + saveHistory() + end + + clearOldMessages() -- Check and clear old messages end - end - os.queueEvent("tableInsert", "lime#".. string.rep("-", X)) -end -comD = { - ["exit"] = { - run = function() - rSend("has quit.", true) - os.queueEvent("exit") - end, - help = "" - }, - ["quit"] = { - run = function() - rSend("has quit.", true) - os.queueEvent("exit") - end, - help = "" - }, - ["me"] = { - run = function(Words) - local StringRe = "" - for i = 2, #Words do - StringRe = StringRe..Words[i].." " - end - rSend(StringRe, true) - end, - help = "" - }, - ["channel"] = { - run = function(Channels) - local SetChan = Channels[2] - if not tonumber(SetChan) then - os.queueEvent("tableInsert", "red#Error: Must be a number.") - else - rSend("has changed channel.", true) - channelN = tonumber(SetChan) - modem.closeAll() - modem.open(channelN) - rSend("has entered the channel!", true, true) - end - end, - help = "" - }, - ["list"] = { - run = function() - os.queueEvent("grabList") - os.queueEvent("tableInsert", "lime#Gathering list...") - end, - help = "" - }, - ["clear"] = { - run = function() - chat = {} - lineCount = 1 - modifier = 0 - draw() - end, - help = "" - }, - ["help"] = { - run = helpGen, - help = "" - }, - ["nick"] = { - run = function(Nickname) - rSend("is now known as "..Nickname[2], true) - user = Nickname[2] - if config.private == true then - config.user = Nickname[2] - local F = fs.open(".darkChatConf", "w") - local configString = textutils.serialize(config) - F.write(configString) - F.close() - end - draw() - end, - help = "" - }, -} ---[[ -28: enter -14: backspace -]]-- -term.clear() term.setCursorPos(1,1) -if (fs.exists(".darkChatConf") == true) and (#args == 0) then - F = fs.open(".darkChatConf", "r") - Data = F.readAll() - F.close() - config = textutils.unserialize(Data) -elseif #args == 0 then - config = {} - repeat - print("Do you want your username to be stored? (Private Mode)") - write("y / n : ") - Qprivate = read() - until Qprivate == "y" or Qprivate == "n" - if Qprivate == "y" then - config.private = true - write("\nUsername: ") - config.user = read() - repeat - write("Default channel number: ") - Qchannel = read() - until tonumber(Qchannel) - config.channel = tonumber(Qchannel) - else - config.private = false - end - configString = textutils.serialize(config) - F = fs.open(".darkChatConf", "w") - F.write(configString) - F.close() - print("Setup Complete!") - sleep(1) -end -if args[1] then - config = {} - config.private = true - config.user = args[1] - config.channel = 10 -end -if args[2] and tonumber(args[2]) then - config.channel = tonumber(args[2]) end -startUp() -if config.private == true then - privateMode() -else - publicMode() -end -channelN = tonumber(channelN) -modem.closeAll() -modem.open(channelN) -term.clear() -term.setCursorPos(1,1) -rSend("has joined the chat!", true, true) -parallel.waitForAny(getChat, sendChat, keyListen, getOnlineList, scrollingEventListen, tableEventListen, exitEventListen) \ No newline at end of file +runTime() diff --git a/chatgpt b/chatgpt new file mode 100644 index 0000000..c41a33e --- /dev/null +++ b/chatgpt @@ -0,0 +1,88 @@ +-- Function to check if a file exists +local function fileExists(path) + return fs.exists(path) and not fs.isDir(path) +end + +-- Function to download a file from Pastebin +local function downloadFromPastebin(pastebinCode, path) + local url = "https://pastebin.com/raw/" .. pastebinCode + local response = http.get(url) + if response then + local file = fs.open(path, "w") + file.write(response.readAll()) + file.close() + response.close() + return true + else + return false + end +end + +-- Check and install LuaSocket library if missing +if not fileExists("/apis/https.lua") then + print("Installing LuaSocket (https.lua)...") + if not downloadFromPastebin("4nRg9CHU", "/apis/https.lua") then + print("Failed to install LuaSocket.") + return + end + print("LuaSocket installation complete.") +end +-- Load the installed libraries +os.loadAPI("/apis/https.lua") + +-- Replace this URL with the API endpoint for GPT-3.5 or GPT-4 +local gpt_endpoint = "https://api.openai.com/v1/engines/gpt-3.5/completions" + +-- Replace YOUR_API_KEY with your actual OpenAI API key +local api_key = "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" + +function getResponse(prompt) + local data = { + prompt = prompt, + max_tokens = 150, + temperature = 0.7, + } + + local headers = { + ["Content-Type"] = "application/json", + ["Authorization"] = "Bearer " .. api_key, + } + + local result = https.post(gpt_endpoint, json.encode(data), headers) + if result then + local response = result.readAll() + result.close() + return response + else + return nil + end +end + +function main() + print("Welcome to ChatGPT!") + print("Type 'exit' to end the conversation.") + print("") + + while true do + term.write("You: ") + local input = read() + if input == "exit" then + break + end + + local response = getResponse(input) + + if response then + local responseData = json.decode(response) + local reply = responseData.choices[1].text + print("ChatGPT: " .. reply) + else + print("An error occurred while communicating with ChatGPT.") + break + end + end + + print("Goodbye!") +end + +main() \ No newline at end of file diff --git a/darkbuttons.lua b/darkbuttons.lua index cb628ec..6bcb48c 100644 --- a/darkbuttons.lua +++ b/darkbuttons.lua @@ -1,18 +1,16 @@ --Title: Dark buttons Version = 1.231 ---Author: Darkrising (minecraft name djhannz) ---Platform: ComputerCraft Lua Virtual Machine if not term.isColour() then print("Requires an Advanced Computer and an Advanced monitor.") return end if fs.exists("dark") == false then -- load darkAPI - print("Missing DarkAPI") + print("Missing OSI API") print("Attempting to download...") if not http then - error("Enable the HTTP API to download DarkAPI") + error("Enable the HTTP API to download OSI API") end - getGit = http.get("https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua") + getGit = http.get("https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/dark.lua") getGit = getGit.readAll() file = fs.open("dark", "w") file.write(getGit) @@ -386,7 +384,7 @@ function wizard(mode) if happyness ~= true then textBox(":'(",txd,txu,tyd,tyu,colors.white,colors.blue) else - textBox(":)",txd,txu,tyd,tyu,colors.white,colors.green) + textBox(":)",txd,txu,tyd,tyu,colors.white,colors.blue) end sleep(1) until happyness == true @@ -464,4 +462,4 @@ options = {} options.wireSide = "bottom" LoadState() getMonitors() -parallel.waitForAll(hitListen, breakListen, terminalMenu, stealthUpdate) \ No newline at end of file +parallel.waitForAll(hitListen, breakListen, terminalMenu, stealthUpdate) diff --git a/darkretriever.lua b/darkretriever.lua index c23c554..17645fb 100644 --- a/darkretriever.lua +++ b/darkretriever.lua @@ -1,23 +1,29 @@ Version = 2.12 x,y = term.getSize() + if not http then print("Herp derp, forget to enable http?") - return exit + return end + local function getUrlFile(url) - local mrHttpFile = http.get(url) - mrHttpFile = mrHttpFile.readAll() - return mrHttpFile + local response = http.get(url) + local contents = response.readAll() + response.close() + return contents end + local function writeFile(filename, data) local file = fs.open(filename, "w") file.write(data) file.close() end + local function cs() term.clear() term.setCursorPos(1,1) end + local function tc(tcolor,bcolor) if term.isColor() then if tcolor then @@ -28,10 +34,12 @@ local function tc(tcolor,bcolor) end end end + local function writeC(text,line) term.setCursorPos((x / 2) - (#text / 2),line) term.write(text) end + term.oldWrite = term.write function term.write(text) if not text then @@ -39,6 +47,7 @@ function term.write(text) end term.oldWrite(text) end + local function header(text) tc("white","blue") writeC(string.rep(" ",x),1) @@ -46,16 +55,17 @@ local function header(text) writeC(text,1) tc("white","black") end + local function gitUpdate(ProgramName, Filename, ProgramVersion) if http then - local status, getGit = pcall(http.get, "https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") + local status, getGit = pcall(http.get, "https://raw.githubusercontent.com/OutragedMetro/darkprograms/darkprograms/programVersions") if not status then print("\nFailed to get Program Versions file.") print("Error: ".. getGit) return exit end - local getGit = getGit.readAll() - NVersion = textutils.unserialize(getGit) + getGit = getGit.readAll() + local NVersion = textutils.unserialize(getGit) if NVersion[ProgramName].Version > ProgramVersion then getGit = http.get(NVersion[ProgramName].GitURL) getGit = getGit.readAll() @@ -80,10 +90,10 @@ else end sleep(1) -x,y = term.getSize() +x, y = term.getSize() cs() write("-> Grabbing file...") -cat = getUrlFile("https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") +cat = getUrlFile("https://raw.githubusercontent.com/OutragedMetro/darkprograms/darkprograms/programVersions") cat = textutils.unserialize(cat) write(" Done.") sleep(1) @@ -100,7 +110,7 @@ rawName = {} ]]-- -for name,data in pairs(cat) do +for name, data in pairs(cat) do if not menu[data.Author] then menu[data.Author] = {} end @@ -131,9 +141,10 @@ function selection(no,list,totpage) tc("white","blue") term.write("Page: ".. page + 1 .. "/" .. totpage) term.setCursorPos(x - 14, y) - term.write("By Darkrising") + term.write("By Outraged") tc("white","black") end + function draw(tbl) local c = 1 local sdat = {} @@ -171,42 +182,43 @@ function draw(tbl) return sdat, tpages, mod end + function runMenu() while true do cs() if level == 1 then - list,totpage,mod = draw(menu) + list, totpage, mod = draw(menu) header("Authors") tc("yellow","black") - writeC("Press 'h' for help, 'q' to quit.",2) + writeC("Press 'h' for help, 'q' to quit.", 2) tc("white","black") elseif level == 2 then - list,totpage,mod = draw(menu[auna]) + list, totpage, mod = draw(menu[auna]) header("Packages") elseif level == 3 then - list,totpage,mod = draw(menu[auna][pkg]) + list, totpage, mod = draw(menu[auna][pkg]) header("Programs") elseif level == 4 then header("Program Data") - list,totpage,mod = draw(menu[auna][pkg][pro]) + list, totpage, mod = draw(menu[auna][pkg][pro]) end selection(csel, list, totpage) - e,key = os.pullEvent("key") + e, key = os.pullEvent("key") if key == keys.h then cs() header("Help") - term.setCursorPos(1,ind) + term.setCursorPos(1, ind) print("Use the up and down arrows to move through the list.") - print("use the right arrow to enter a menu item and the left arrow to exit") + print("Use the right arrow to enter a menu item and the left arrow to exit.") print("") - _,cy = term.getCursorPos() + _, cy = term.getCursorPos() tc("yellow","black") - writeC("Press enter to continue.",cy) + writeC("Press enter to continue.", cy) tc("white","black") read(" ") end @@ -265,7 +277,7 @@ function runMenu() repeat cs() writeC("Would you like to generate a startup script? ", y/2) - writeC("Y / N : ",y/2 + 1) + writeC("Y / N : ", y/2 + 1) answer = string.lower(read()) until answer == "y" or answer == "n" @@ -273,7 +285,7 @@ function runMenu() cs() writeC("Writing startup script...", y/2) - star = fs.open("/startup","w") + star = fs.open("/startup", "w") star.write("shell.run('".. rawName[pro] .. "')") star.close() @@ -283,10 +295,10 @@ function runMenu() end end - if csel < 1 then --Can't go below beginning of the list + if csel < 1 then --Can't go below the beginning of the list csel = 1 end - if csel > #list then --Can't go above length of the list + if csel > #list then --Can't go above the length of the list csel = #list end @@ -297,8 +309,7 @@ function runMenu() end page = math.floor((csel - 1) / ava) - end end -runMenu() \ No newline at end of file +runMenu() diff --git a/darksecurity/chat_client.lua b/darksecurity/chat_client.lua new file mode 100644 index 0000000..b48d7b7 --- /dev/null +++ b/darksecurity/chat_client.lua @@ -0,0 +1,213 @@ +os.pullEvent = os.pullEventRaw + +-- Check if running on a pocket computer +local isPocket = pocket and true or false + +-- Variables +local msg = "" +local MH = {} +local historyFilePath = "/.chat_history" +local nameFilePath = "/.chat_username" +local modemSide = nil +local name = "" + +-- Load chat history from file if available +if fs.exists(historyFilePath) then + local file = fs.open(historyFilePath, "r") + local line = file.readLine() + while line do + table.insert(MH, line) -- Newest messages at the bottom + line = file.readLine() + end + file.close() +end + +-- Load or ask for username +if fs.exists(nameFilePath) then + local file = fs.open(nameFilePath, "r") + name = file.readLine() + file.close() +else + term.write("Name: ") + name = read() + local file = fs.open(nameFilePath, "w") + file.writeLine(name) + file.close() +end + +-- Find and open the modem (works for both wired and wireless) +local modemDetected = false +local startTime = os.time() +while os.time() - startTime < 10 do + local modem = peripheral.find("modem") or peripheral.find("wireless_modem") + if modem then + modemSide = peripheral.getName(modem) + rednet.open(modemSide) + modemDetected = true + print("Modem detected and Rednet opened on:", modemSide) + break + end + os.sleep(1) -- Wait 1 second before retrying +end + +if not modemDetected then + term.clear() + term.setCursorPos(1, 1) + print("No modems detected after 10 seconds. Please attach or enable a modem.") + os.sleep(3) -- Allow time to read the message before attempting to restart + shell.run("reboot") -- Option to reboot the system or exit to fix the modem issue +end + +-- Ensure Rednet is open +if not rednet.isOpen(modemSide) then + error("Failed to open Rednet on " .. modemSide) +end + +-- Clear the terminal +local function clear() + term.clear() + term.setCursorPos(1, 1) +end + +-- Display the startup message/logo +local function displayStartupMessage() + clear() + term.setTextColor(colors.green) -- Emerald color + local screenWidth, screenHeight = term.getSize() + local message = "Emerald Wireless!" + + -- Ensure the message fits on the screen (adjust for Pocket Computer if needed) + if #message > screenWidth then + message = message:sub(1, screenWidth) -- Trim the message if it's too long + end + + -- Calculate the position to center the message + local xPos = math.floor((screenWidth - #message) / 2) + 1 + local yPos = math.floor(screenHeight / 2) + + -- Set cursor to the calculated position + term.setCursorPos(xPos, yPos) + print(message) + + term.setTextColor(colors.white) -- Default color for subsequent text + os.sleep(2) -- Display the logo for 2 seconds + clear() -- Clear the screen after the logo +end + +-- Save chat history to file +local function saveHistory() + local file = fs.open(historyFilePath, "w") + for _, line in ipairs(MH) do + file.writeLine(line) + end + file.close() +end + +-- Send message via Rednet +local function send(MSg) + rednet.broadcast(name .. ": " .. MSg) +end + +-- Draw the chat screen +local function drawScreen(Msg) + clear() + local screenWidth, screenHeight = term.getSize() + local linesToShow = isPocket and 5 or 18 -- Adjust the number of lines to show based on screen size + local startIdx = math.max(1, #MH - linesToShow) -- Get the last `linesToShow` messages + + -- Print the chat history starting from the last message + for i = startIdx, #MH do + term.setCursorPos(1, screenHeight - (linesToShow - (i - startIdx))) -- Position messages just above the input line + print(MH[i]) + end + + -- Print the current message input at the bottom + term.setCursorPos(1, screenHeight) -- Set the cursor at the bottom of the screen + print(Msg) +end + +-- Clear old messages (older than 2 days) +local function clearOldMessages() + local currentTime = os.time() + local maxAge = 2 * 24 * 60 * 60 -- 2 days + + local newMH = {} + for _, line in ipairs(MH) do + local timestamp = tonumber(line:match("^%[(%d+)%]")) + if not timestamp or currentTime - timestamp <= maxAge then + table.insert(newMH, line) + end + end + + MH = newMH + saveHistory() +end + +-- Delete all chat history +local function deleteHistory() + MH = {} + saveHistory() +end + +-- Main chat loop +local function runTime() + local historyStart = 1 + local linesToShow = isPocket and 5 or 18 + local screenWidth, screenHeight = term.getSize() + + while true do + -- Draw the screen before asking for input + drawScreen("Enter a message: " .. msg) + + local event, a, b, c = os.pullEvent() + + if event == "char" then + msg = msg .. a + elseif event == "key" then + if a == keys.backspace then + msg = msg:sub(1, #msg - 1) + elseif a == keys.enter and msg ~= "" then + -- Send the message + send(msg) + + -- Add the message to the history immediately after sending it + table.insert(MH, name .. ": " .. msg) + saveHistory() + + -- Clear the message input box + msg = "" + + -- Update the screen immediately to show the new message + drawScreen("Enter a message: ") + elseif a == keys.up then + historyStart = math.max(1, historyStart - 1) + elseif a == keys.down then + historyStart = math.min(#MH - linesToShow + 1, historyStart + 1) + elseif a == keys.d and c == true then + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.red) + term.write("Delete chat history? (Y/N): ") + local confirmation = read():lower() + if confirmation == "y" then + deleteHistory() + end + end + elseif event == "rednet_message" then + -- Add the received message to the history and update the screen + table.insert(MH, name .. ": " .. b) + saveHistory() + + -- Immediately draw the updated chat + drawScreen("Enter a message: " .. msg) + end + + clearOldMessages() -- Remove old messages + end +end + +-- Show startup message/logo +displayStartupMessage() + +-- Start chat application +runTime() diff --git a/darksecurity/chat_server.lua b/darksecurity/chat_server.lua new file mode 100644 index 0000000..13371ef --- /dev/null +++ b/darksecurity/chat_server.lua @@ -0,0 +1,100 @@ +os.pullEvent = os.pullEventRaw + +-- Variables +local serverChannel = 1 -- Channel for receiving messages +local historyFilePath = "/server_chat_history" -- File to store chat history +local modemSide = nil + +-- Find and open the modem (works for both wired and wireless) +local modemDetected = false +local startTime = os.time() +while os.time() - startTime < 10 do + local modem = peripheral.find("modem") or peripheral.find("wireless_modem") + if modem then + modemSide = peripheral.getName(modem) + rednet.open(modemSide) + modemDetected = true + print("Modem detected and Rednet opened on:", modemSide) + break + end + os.sleep(1) -- Wait 1 second before retrying +end + +if not modemDetected then + term.clear() + term.setCursorPos(1, 1) + print("No modems detected after 10 seconds. Please attach or enable a modem.") + os.sleep(3) -- Allow time to read the message before attempting to restart + shell.run("reboot") -- Option to reboot the system or exit to fix the modem issue +end + +-- Ensure Rednet is open +if not rednet.isOpen(modemSide) then + error("Failed to open Rednet on " .. modemSide) +end + +-- Load chat history from file if available +local function loadHistory() + local history = {} + if fs.exists(historyFilePath) then + local file = fs.open(historyFilePath, "r") + local line = file.readLine() + while line do + table.insert(history, line) + line = file.readLine() + end + file.close() + end + return history +end + +-- Save chat history to file +local function saveHistory(history) + local file = fs.open(historyFilePath, "w") + for _, line in ipairs(history) do + file.writeLine(line) + end + file.close() +end + +-- Log the incoming message +local function logMessage(sender, message) + local timestamp = os.date("%Y-%m-%d %H:%M:%S") + local logLine = string.format("[%s] %s: %s", timestamp, sender, message) + local history = loadHistory() + table.insert(history, 1, logLine) -- Add new message to the beginning + saveHistory(history) + print(logLine) -- Display the message on the server screen +end + +-- Clear the screen and display a header +local function clearScreen() + term.clear() + term.setCursorPos(1, 1) + term.setTextColor(colors.green) -- Change to green for header + print("---- Server Chat Log ----") + term.setTextColor(colors.white) -- Reset color to white for messages +end + +-- Main server loop +local function serverLoop() + clearScreen() + print("Server is listening for messages...") + + -- Load chat history and display on screen + local history = loadHistory() + for _, line in ipairs(history) do + print(line) + end + + -- Listen for incoming messages and display them + while true do + local senderID, message = rednet.receive(serverChannel) -- Wait for message from client + if message then + logMessage(senderID, message) -- Log and display the message + end + end +end + +-- Start the server +serverLoop() diff --git a/darksecurity/client.lua b/darksecurity/client.lua index 97f323e..7fe9a98 100644 --- a/darksecurity/client.lua +++ b/darksecurity/client.lua @@ -1,4 +1,4 @@ ---Title: Dark Client +--Title: Outraged Security Client Version = 4.26 --Author: Darkrising (minecraft name djhannz) --Platform: ComputerCraft Lua Virtual Machine @@ -9,12 +9,12 @@ x,y = term.getSize() oldEvent = os.pullEvent os.pullEvent = os.pullEventRaw if fs.exists("dark") == false then -- load darkAPI - print("Missing DarkAPI") + print("Missing OSI API") sleep(2) print("Attempting to download...") - status, getGit = pcall(http.get,"https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua") + status, getGit = pcall(http.get,"https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/dark.lua") if not status then - print("\nFailed to get Dark API") + print("\nFailed to get OSI API") print("Error: ".. getGit) return exit end @@ -52,12 +52,12 @@ function header(text, lText, rText) dark.printC(string.rep(" ", x), 2, nil, "white", "blue") if lText then dark.printA(lText, 1, 2, nil, "white", "blue") end if rText then dark.printA(rText, x - #rText, 2, nil, "white", "blue") end - dark.printC(text, 2, nil, "yellow", "blue") + dark.printC(text, 2, nil, "white", "blue") dark.printL("-", 3, 5, "blue", "blue") end function footer() dark.printL("-", y, nil, "blue", "blue") - dark.printA("by darkrising", x-13, y, nil, "yellow", "blue") + dark.printA("by OutragedMetro", x-13, y, nil, "red", "blue") end function keycard_mainProgram() while true do @@ -146,7 +146,7 @@ if fs.exists(".DarkC_conf") == false then term.clear() term.setCursorPos(1,1) - header("Dark Client Setup") + header("Outraged Security Client Setup") print("Computer's id is ".. os.getComputerID()) while true do @@ -252,4 +252,4 @@ elseif config.tType == "password" then elseif config.tType == "both" then parallel.waitForAll(userandpassword_mainProgram, keycard_mainProgram, stealthUpdate) end -os.pullEvent = oldEvent \ No newline at end of file +os.pullEvent = oldEvent diff --git a/darksecurity/installer.lua b/darksecurity/installer.lua index 3c81d04..6ca5a71 100644 --- a/darksecurity/installer.lua +++ b/darksecurity/installer.lua @@ -41,7 +41,7 @@ until ((installAnswer == "Server") or (installAnswer == "Client") or (installAns end print("Downloading requested programs...") - local status, getGit = pcall(http.get, "https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") + local status, getGit = pcall(http.get, "https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/programVersions") if not status then print("\nFailed to get Program Versions file.") print("Error: ".. getGit) diff --git a/darksecurity/server.lua b/darksecurity/server.lua index 18c5577..51c881b 100644 --- a/darksecurity/server.lua +++ b/darksecurity/server.lua @@ -1,15 +1,13 @@ ---Title: Dark Server +--Title: Outraged Security Server Version = 6.37 ---Author: Darkrising (minecraft name djhannz) ---Platform: ComputerCraft Lua Virtual Machine term.clear() term.setCursorPos(1,1) if fs.exists("dark") == false then - print("Missing DarkAPI") + print("Missing OSI API") print("Attempting to download...") - status, getGit = pcall(http.get, "https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua") + status, getGit = pcall(http.get, "https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/dark.lua") if not status then - print("\nFailed to get Dark API") + print("\nFailed to get OSI API") print("Error: ".. getGit) return exit end @@ -130,7 +128,7 @@ function footer() co = "blue" end dark.printL("-", y, nil, co, co) - dark.printA("by darkrising", x-13, y, nil, "yellow", co) + dark.printA("by OutragedMetro", x-13, y, nil, "red", co) end function displayTNameColumn(TName, Page, Extrater, Admin) if Extrater then @@ -238,7 +236,7 @@ end function runServerGui() term.clear() term.setCursorPos(1,1) - dark.splash(1.5, "Powered by DarkGui") + dark.splash(1.5, "Powered by Outraged Security Gui") state = "main" Page = 0 while true do @@ -323,7 +321,8 @@ Co = { term.setCursorPos(1,1) header("Help") dark.printA("Press [1] to return to the main menu", 1, y) - print("\nHelp comming soon!") + print("\nTo Navigate the settings menu and to add new users, Keycards, And passwords just follow the on screen prompts!") + print("\nOutraged Security INC prides them selves in providing top notch security to its customers for more support contact Outraged Security INC. For installation a geek squad visit may be required by a professional.") os.pullEvent("key") end, options = {"main"} @@ -350,7 +349,7 @@ Co = { printR("[8] Shell", 8) end dark.printL("-", y, nil, co, co) - dark.printA("by darkrising", x-13, y, nil, "yellow", co) + dark.printA("by OutragedMetro", x-13, y, nil, "yellow", co) dark.printA(" ", 1, y, nil, co, co) dark.printA("Current Security Level: "..slevel, 1, y, nil, "white", co) end, @@ -771,7 +770,7 @@ if fs.exists(".DarkS_conf") == false then dark.cs() config = {} masterdb = databaseNew() - header("Dark Server Setup") + header("Outraged Security Server Setup") print("Computer's id is ".. os.getComputerID()) repeat write("security level amount (must be a number): ") @@ -784,4 +783,4 @@ if fs.exists(".DarkS_conf") == false then end --Finale Stuff databaseLoad() -parallel.waitForAll(runServerBackend, runServerGui, stealthUpdate, listen) \ No newline at end of file +parallel.waitForAll(runServerBackend, runServerGui, stealthUpdate, listen) diff --git a/games/Autorun/Autorun b/games/Autorun/Autorun new file mode 100644 index 0000000..ed5a37f --- /dev/null +++ b/games/Autorun/Autorun @@ -0,0 +1,87 @@ +x = 1 +y = 2 +vel = 0 +score = 0 +platforms = {} + +term.setBackgroundColor(colors.lightBlue) +term.setTextColor(colors.white) +term.clear() +function createPlatforms() + pl = 3 + size = 51/pl + height = math.random(1, 19) + for i=0,pl do + height = height+math.random(8)-4 + for j=0,size do + platforms[(size*i)+j] = height + end + platforms[i*size] = -1 + end +end +function drawBuildings() + term.setBackgroundColor(colors.red) + for i=1, #platforms do + if(platforms[i] ~= -1) then + term.setCursorPos(i-1, platforms[i]) + term.write("-") + for j=platforms[i], 19 do + term.setCursorPos(i-1, j) + term.write(" ") + end + end + end + term.setBackgroundColor(colors.lightBlue) +end +function restart() + x = 1 + y = 2 + term.setBackgroundColor(colors.lightBlue) + term.clear() + createPlatforms() + drawBuildings() +end +function grounded() + if(x < #platforms) then + if(y >= platforms[x]-1) and (platforms[x] ~= -1) then return true end + end + return false +end +function Char() + sleep(0.2) + term.setCursorPos(x, y) + term.write(" ") + if(grounded()) then x = x+1 end + if(vel > 0) then x = x+1 end + if(vel <= 0) then + y = y+1 + else + y = y-1 + vel = vel-1 + end + if(x < #platforms) then + if(y > platforms[x]-1) and (platforms[x] ~= -1) then y = platforms[x]-1 end + end + if(y > 19) then restart() end + term.setCursorPos(x, y) + term.setBackgroundColor(colors.blue) + term.write(" ") + term.setCursorPos(1, 19) + --term.write("Pos:"..tostring(x).." "..tostring(y)) + term.setBackgroundColor(colors.lightBlue) + +end +function keyPressed() + event, key = os.pullEvent("key") + if(key == keys.space) and (grounded()) then + term.setCursorPos(x,y) + term.write(" ") + vel = 3 + end +end +createPlatforms() +drawBuildings() +while true do + parallel.waitForAny(Char, keyPressed) + sleep(0.1) +end diff --git a/games/BrickBreaker/BrickBreaker b/games/BrickBreaker/BrickBreaker new file mode 100644 index 0000000..e5afb41 --- /dev/null +++ b/games/BrickBreaker/BrickBreaker @@ -0,0 +1,133 @@ +local w,h = term.getSize() +local pos = (w/2)-3 +local score = 0 +local fscore = 0 +local bricks = {} +local ballx = (w/2)+0.5 +local bally = h-8 +local ballvx = 1 +local ballvy = 1 +local lose = false +for i=1,3 do + for j=1,w do + local obj = {} + obj["x"] = j + obj["y"] = i+1 + obj["broken"] = false + bricks[#bricks+1] = obj + end +end +term.setBackgroundColor(colors.black) +term.clear() +function keyPress() + while true do + event, key = os.pullEvent("key") + if key == keys.right then + pos = pos+1 + end + if key == keys.left then + pos = pos-1 + end + if key == keys.r then + pos = (w/2)-3 + score = 0 + fscore = 0 + bricks = {} + ballx = (w/2)+0.5 + bally = h-8 + ballvx = 1 + ballvy = 1 + lose = false + for i=1,3 do + for j=1,w do + local obj = {} + obj["x"] = j + obj["y"] = i+1 + obj["broken"] = false + bricks[#bricks+1] = obj + end + end + end + draw() + end +end +function draw() + term.setBackgroundColor(colors.black) + term.clear() + term.setBackgroundColor(colors.white) + for i=0,6 do + term.setCursorPos(pos+i, h-1) + term.write(" ") + end + term.setBackgroundColor(colors.lightGray) + for i=1,w do + term.setCursorPos(i, 1) + term.write(" ") + end + term.setTextColor(colors.white) + term.setCursorPos(1,1) + term.write(score) + for i=1,#bricks do + term.setBackgroundColor(colors.magenta) + term.setCursorPos(bricks[i]["x"], bricks[i]["y"]) + if bricks[i]["broken"] == false then + term.write(" ") + end + end + term.setBackgroundColor(colors.white) + term.setTextColor(colors.black) + term.setCursorPos(ballx, bally) + term.write(" ") + if lose == true then + term.setBackgroundColor(colors.black) + term.setTextColor(colors.white) + term.clear() + fscore = score + centertext("Final Score: "..fscore, h/2) + centertext("Press R to restart", (h/2)+1) + end +end +function ballmove() + while true do + ballx = ballx + ballvx + bally = bally + ballvy + if ballx > pos and ballx < pos+6 and bally > h-3 and bally < h-1 then + bounce(1) + end + if bally < 2 then + bounce(1) + end + if ballx > w-1 then + bounce(2) + end + if ballx < 1 then + bounce(2) + end + if bally > h then + lose = true + end + for i=1,#bricks do + if bricks[i]["x"] == ballx and bricks[i]["y"] == bally and bricks[i]["broken"] == false then + bounce(1) + bricks[i]["broken"] = true + score = score+1 + end + end + draw() + sleep(0.14) + end +end +function bounce(dir) + if dir == 1 then + ballvy = -ballvy + end + if dir == 2 then + ballvx = -ballvx + end +end +function centertext(text, height) + term.setCursorPos((w/2)-(string.len(text)/2), height) + term.write(text) +end +draw() +parallel.waitForAll(keyPress, ballmove) \ No newline at end of file diff --git a/games/CookieClicker/CookieClicker b/games/CookieClicker/CookieClicker new file mode 100644 index 0000000..ef961fc --- /dev/null +++ b/games/CookieClicker/CookieClicker @@ -0,0 +1,638 @@ +local w, h = term.getSize() -- First getting the size of the computer screen display +-- A computer term will be 51 x 19 +-- A pocket computer will be 26 x 20 +menustate = "cookie" +terminate = false +cookies = 0 +cps = 0 + +function printCentered(sText) + local x, y = term.getCursorPos() + x = math.max(math.floor((w / 2) - (#sText / 2)), 0) + term.setCursorPos(x, y) + print(sText) +end + +local function drawMenuColour() -- creates the colours of the menu + paintutils.drawFilledBox(0, 0, w, h, colours.grey) -- Bottom Grey + paintutils.drawFilledBox(0, 0, w, 2, colours.orange) -- top 2 Cyan +end + +local function drawTitle() + term.setCursorPos(0,1) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.orange) + printCentered("COOKIE CLICKERS - V1") --Title + print(string.rep("=", w)) + term.setBackgroundColour(colours.lightGrey) +end + +local function drawHeadings() -- creates the game statistic displays + if pocket then + if menustate == "cookie" then + term.setBackgroundColour(colours.grey) + term.setTextColour(colours.lightGrey) + paintutils.drawLine(2,4,27,4, colours.grey) + term.setCursorPos(2, 4) + print("Cookies:", cookies) + paintutils.drawLine(2,5,27,5, colours.grey) + term.setCursorPos(2,5) + print("CPS:", cps) + end + else + term.setBackgroundColour(colours.grey) + term.setTextColour(colours.lightGrey) + paintutils.drawLine(2,4,27,4, colours.grey) + term.setCursorPos(2, 4) + print("Cookies:", cookies) + paintutils.drawLine(2,5,27,5, colours.grey) + term.setCursorPos(2,5) + print("CPS:", cps) + end +end + +local function drawCookie() + if pocket then + if menustate == "cookie" then + paintutils.drawFilledBox(4,7,13,13, colours.orange) + paintutils.drawPixel(4,7, colours.grey) + paintutils.drawPixel(13,7, colours.grey) + paintutils.drawPixel(4,13, colours.grey) + paintutils.drawPixel(13,13, colours.grey) + paintutils.drawPixel(5,9, colours.black) + paintutils.drawPixel(7,12, colours.black) -- W,H,Colour + paintutils.drawPixel(10,10, colours.black) + paintutils.drawPixel(8,8, colours.black) + paintutils.drawPixel(11,12, colours.black) + paintutils.drawPixel(12,9, colours.black) + end + else + paintutils.drawFilledBox(4,7,13,13, colours.orange) + paintutils.drawPixel(4,7, colours.grey) + paintutils.drawPixel(13,7, colours.grey) + paintutils.drawPixel(4,13, colours.grey) + paintutils.drawPixel(13,13, colours.grey) + paintutils.drawPixel(5,9, colours.black) + paintutils.drawPixel(7,12, colours.black) -- W,H,Colour + paintutils.drawPixel(10,10, colours.black) + paintutils.drawPixel(8,8, colours.black) + paintutils.drawPixel(11,12, colours.black) + paintutils.drawPixel(12,9, colours.black) + end +end + +local function drawExit() + term.setBackgroundColour(colours.red) + term.setTextColour(colours.white) + term.setCursorPos(2, h-1) + print("EXIT") +end + +local function drawMenuSwap() + term.setBackgroundColour(colours.blue) + term.setTextColor(colours.white) + term.setCursorPos(w-4, h-1) + if menustate == "cookie" then + print("SHOP") + else + print("BACK") + end +end + +local function exitPrompt() + if pocket then + --making fancy boxes + paintutils.drawFilledBox(2,6,25,14, colours.black) + paintutils.drawFilledBox(2,6,25,7, colours.orange) + --Making a fancy title + term.setBackgroundColour(colours.orange) + term.setTextColour(colours.black) + term.setCursorPos(9,6) + print("EXIT MENU") + term.setCursorPos(2,7) + print(string.rep("=", 24)) + --making fancy text + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.setCursorPos(3, 9) + print("Are you sure you want") + term.setCursorPos(9,10) + print("to exit?") + --Making fancy Yes/No boxes + term.setBackgroundColour(colours.green) + term.setCursorPos(9, 12) + print("YES") + term.setBackgroundColour(colours.red) + term.setCursorPos(15, 12) + print("NO ") + -- using the exit GUI + while true do + local event, button, x, y = os.pullEventRaw("mouse_click") -- It enables you to select with the mouse + if (event == "mouse_click" and x >= 1 and 25 >= x and y >= 6 and 14 >= y) then -- if you click in the window zone + if (event == "mouse_click" and x >= 9 and 11 >= x and y == 12) then -- and if you also click on the 'YES' + term.setTextColour(colours.yellow) + term.setBackgroundColour(colours.black) + term.setCursorPos(9, 12) + textutils.slowPrint(" Goodbye!") + sleep(1) + return true + elseif (x >= 15 and 18 >= x and y == 12) then -- and if you also click on the 'NO' + return false + end + elseif button == 28 then -- If you hit enter + term.setTextColour(colours.yellow) + term.setBackgroundColour(colours.black) + term.setCursorPos(26, 12) + textutils.slowPrint(" Goodbye!") + sleep(1) + return true + else + return false + end + end + else + --making fancy boxes + paintutils.drawFilledBox(18,6,42,14, colours.black) + paintutils.drawFilledBox(18,6,42,7, colours.orange) + --Making a fancy title + term.setBackgroundColour(colours.orange) + term.setTextColour(colours.black) + term.setCursorPos(26,6) + print("EXIT MENU") + term.setCursorPos(18,7) + print(string.rep("=", 25)) + --making fancy text + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.setCursorPos(20, 9) + print("Are you sure you want") + term.setCursorPos(26,10) + print("to exit?") + --Making fancy Yes/No boxes + term.setBackgroundColour(colours.green) + term.setCursorPos(26, 12) + print("YES") + term.setBackgroundColour(colours.red) + term.setCursorPos(32, 12) + print("NO ") + -- using the exit GUI + while true do + local event, button, x, y = os.pullEventRaw("mouse_click") -- It enables you to select with the mouse + if (event == "mouse_click" and x >= 18 and 42 >= x and y >= 6 and 14 >= y) then -- if you click in the window zone + if (event == "mouse_click" and x >= 26 and 28 >= x and y == 12) then -- and if you also click on the 'YES' + term.setTextColour(colours.yellow) + term.setBackgroundColour(colours.black) + term.setCursorPos(26, 12) + textutils.slowPrint(" Goodbye!") + sleep(1) + return true + elseif (x >= 32 and 35 >= x and y == 12) then -- and if you also click on the 'NO' + return false + end + elseif button == 28 then -- If you hit enter + term.setTextColour(colours.yellow) + term.setBackgroundColour(colours.black) + term.setCursorPos(26, 12) + textutils.slowPrint(" Goodbye!") + sleep(1) + return true + else + return false + end + end + end +end + +--The upgrade menu panel + +pickaxeAmount = 0 +pickaxePrice = 25 +villagerAmount = 0 +villagerPrice = 75 +farmAmount = 0 +farmPrice = 300 +mineAmount = 0 +minePrice = 1000 +factoryAmount = 0 +factoryPrice = 7500 +portalAmount = 0 +portalPrice = 25000 + +local function drawUpgrades() + if pocket then -- checks to see if it's a pocket computer + drawMenuSwap() + if menustate == "upgrades" then + --PICKAXE Upgrade menu + if cookies >= pickaxePrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-24, 4, w-14, 7, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-24, 4, w-14, 7, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + -- Writing the text + term.setCursorPos(w-22,4) + print("Pickaxe") + term.setCursorPos(w-22,5) + print("0.3 CPS") + term.setCursorPos(w-22,6) + print("$",pickaxePrice) + term.setCursorPos(w-22,7) + print("Own: ",pickaxeAmount) + + --VILLAGER upgrade menu + if cookies >= villagerPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 4, w-1, 7, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 4, w-1, 7, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,4) + print("Villager") + term.setCursorPos(w-10,5) + print("1 CPS") + term.setCursorPos(w-10,6) + print("$",villagerPrice) + term.setCursorPos(w-10,7) + print("Own: ",villagerAmount) + + -- FARM upgrade menu + if cookies >= farmPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-24, 9, w-14, 12, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-24, 9, w-14, 12, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-22,9) + print("Farm") + term.setCursorPos(w-22,10) + print("3 CPS") + term.setCursorPos(w-22,11) + print("$",farmPrice) + term.setCursorPos(w-22,12) + print("Own: ",farmAmount) + + --Mine Upgrade Menu + if cookies >= minePrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 9, w-1, 12, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 9, w-1, 12, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,9) + print("Mine") + term.setCursorPos(w-10,10) + print("5 CPS") + term.setCursorPos(w-10,11) + print("$",minePrice) + term.setCursorPos(w-10,12) + print("Own: ",mineAmount) + + --Factory Upgrade Menu + if cookies >= factoryPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-24, 14, w-14, 17, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-24, 14, w-14, 17, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-22,14) + print("Factory") + term.setCursorPos(w-22,15) + print("15 CPS") + term.setCursorPos(w-22,16) + print("$",factoryPrice) + term.setCursorPos(w-22,17) + print("Own: ",factoryAmount) + + --Portal Upgrade Menu + if cookies >= portalPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 14, w-1, 17, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 14, w-1, 17, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,14) + print("Portal") + term.setCursorPos(w-10,15) + print("50 CPS") + term.setCursorPos(w-10,16) + print("$",portalPrice) + term.setCursorPos(w-10,17) + print("Own: ",portalAmount) + end + else -- if it's an ordinary computer + --PICKAXE Upgrade menu + if cookies >= pickaxePrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-23, 4, w-13, 7, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-23, 4, w-13, 7, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + -- Writing the text + term.setCursorPos(w-22,4) + print("Pickaxe") + term.setCursorPos(w-22,5) + print("0.3 CPS") + term.setCursorPos(w-22,6) + print("$",pickaxePrice) + term.setCursorPos(w-22,7) + print("Own: ",pickaxeAmount) + + --VILLAGER upgrade menu + if cookies >= villagerPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 4, w-1, 7, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 4, w-1, 7, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,4) + print("Villager") + term.setCursorPos(w-10,5) + print("1 CPS") + term.setCursorPos(w-10,6) + print("$",villagerPrice) + term.setCursorPos(w-10,7) + print("Own: ",villagerAmount) + + -- FARM upgrade menu + if cookies >= farmPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-23, 9, w-13, 12, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-23, 9, w-13, 12, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-22,9) + print("Farm") + term.setCursorPos(w-22,10) + print("3 CPS") + term.setCursorPos(w-22,11) + print("$",farmPrice) + term.setCursorPos(w-22,12) + print("Own: ",farmAmount) + + --Mine Upgrade Menu + if cookies >= minePrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 9, w-1, 12, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 9, w-1, 12, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,9) + print("Mine") + term.setCursorPos(w-10,10) + print("5 CPS") + term.setCursorPos(w-10,11) + print("$",minePrice) + term.setCursorPos(w-10,12) + print("Own: ",mineAmount) + + --Factory Upgrade Menu + if cookies >= factoryPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-23, 14, w-13, 17, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-23, 14, w-13, 17, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-22,14) + print("Factory") + term.setCursorPos(w-22,15) + print("15 CPS") + term.setCursorPos(w-22,16) + print("$",factoryPrice) + term.setCursorPos(w-22,17) + print("Own: ",factoryAmount) + + --Portal Upgrade Menu + if cookies >= portalPrice then -- If you have enough money, it's green + paintutils.drawFilledBox(w-11, 14, w-1, 17, colours.green) + term.setTextColour(colours.black) + term.setBackgroundColour(colours.green) + else -- If you don't have enough money, it's red + paintutils.drawFilledBox(w-11, 14, w-1, 17, colours.red) + term.setTextColour(colours.white) + term.setBackgroundColour(colours.red) + end + --Writing the text + term.setCursorPos(w-10,14) + print("Portal") + term.setCursorPos(w-10,15) + print("50 CPS") + term.setCursorPos(w-10,16) + print("$",portalPrice) + term.setCursorPos(w-10,17) + print("Own: ",portalAmount) + end +end + +-- Functions to run the game + +local function runGame() + while true do -- The continuous loop of the game + drawTitle() + drawCookie() + drawUpgrades() + drawExit() + drawHeadings() -- draws in all the data + local event, button, x, y = os.pullEventRaw() -- if there is a mouse click + if pocket then + if menustate == "cookie" then -- if you're on the cookie page + if (event == "mouse_click" and x >= 4 and 13 >= x and y >= 7 and 13 >= y) then -- and if that mouse click is on the cookie + cookies = cookies + 1 -- you get more cookies + end + if (event == "mouse_click" and w-1 >= x and x >= w-4 and y == h-1) then -- If you hit SHOP / BACK + menustate = "upgrades" + drawMenuColour() + end + elseif menustate == "upgrades" then -- if you're on the menu page + if (event == "mouse_click" and x >= w-24 and w-14 >= x and y >= 4 and 7 >= y) then -- PICKAXE CLICK + if cookies >= pickaxePrice then + cookies = cookies - pickaxePrice + pickaxeAmount = pickaxeAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 4 and 7 >= y) then -- VILLAGER CLICK + if cookies >= villagerPrice then + cookies = cookies - villagerPrice + villagerAmount = villagerAmount + 1 + end + end + if (event == "mouse_click" and x >= w-23 and w-13 >= x and y >= 9 and 12 >= y) then -- FARM CLICK + if cookies >= villagerPrice then + cookies = cookies - farmPrice + farmAmount = farmAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 9 and 12 >= y) then -- MINE CLICK + if cookies >= minePrice then + cookies = cookies - minePrice + mineAmount = mineAmount + 1 + end + end + if (event == "mouse_click" and x >= w-23 and w-13 >= x and y >= 14 and 17 >= y) then -- FACTORY CLICK + if cookies >= factoryPrice then + cookies = cookies - factoryPrice + factoryAmount = factoryAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 14 and 17 >= y) then -- PORTAL CLICK + if cookies >= portalPrice then + cookies = cookies - portalPrice + portalAmount = portalAmount + 1 + end + end + if (event == "mouse_click" and w-1 >= x and x >= w-4 and y == h-1) then -- If you hit SHOP / BACK + menustate = "cookie" + drawMenuColour() + end + end + if (event == "mouse_click" and 5 >= x and x >= 2 and y == h-1) then -- If you hit EXIT + return + end + if event == "terminate" then + break + end + else + if (event == "mouse_click" and x >= 4 and 13 >= x and y >= 7 and 13 >= y) then -- and if that mouse click is on the cookie + cookies = cookies + 1 -- you get more cookies + end + if (event == "mouse_click" and 5 >= x and x >= 2 and y == h-1) then -- If you hit EXIT + return + end + if (event == "mouse_click" and x >= w-23 and w-13 >= x and y >= 4 and 7 >= y) then -- PICKAXE CLICK + if cookies >= pickaxePrice then + cookies = cookies - pickaxePrice + pickaxeAmount = pickaxeAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 4 and 7 >= y) then -- VILLAGER CLICK + if cookies >= villagerPrice then + cookies = cookies - villagerPrice + villagerAmount = villagerAmount + 1 + end + end + if (event == "mouse_click" and x >= w-23 and w-13 >= x and y >= 9 and 12 >= y) then -- FARM CLICK + if cookies >= villagerPrice then + cookies = cookies - farmPrice + farmAmount = farmAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 9 and 12 >= y) then -- MINE CLICK + if cookies >= minePrice then + cookies = cookies - minePrice + mineAmount = mineAmount + 1 + end + end + if (event == "mouse_click" and x >= w-23 and w-13 >= x and y >= 14 and 17 >= y) then -- FACTORY CLICK + if cookies >= factoryPrice then + cookies = cookies - factoryPrice + factoryAmount = factoryAmount + 1 + end + end + if (event == "mouse_click" and x >= w-11 and w-1 >= x and y >= 14 and 17 >= y) then -- PORTAL CLICK + if cookies >= portalPrice then + cookies = cookies - portalPrice + portalAmount = portalAmount + 1 + end + end + if event == "terminate" then + break + end + end + cps = (pickaxeAmount*0.3) + (villagerAmount*1) + (farmAmount*3) + (mineAmount*5) + (factoryAmount*15) + (portalAmount*50) + pickaxePrice = 25 + (pickaxeAmount*5) + villagerPrice = 75 + (villagerAmount*20) + farmPrice = 300 + (farmAmount*75) + minePrice = 1000 + (mineAmount*350) + factoryPrice = 7500 + (factoryAmount*1200) + portalPrice = 25000 + (portalAmount*10000) + drawUpgrades() + end +end + +local function runUpgrades() + while true do -- continuously adding cookies every amount of seconds for the different runUpgrades + sleep(1) + cps = (pickaxeAmount*0.3) + (villagerAmount*1) + (farmAmount*3) + (mineAmount*5) + (factoryAmount*15) + (portalAmount*50) + cookies = cookies + cps + drawHeadings() -- draws in all the data + drawUpgrades() + end +end + +-- Running the game +if not turtle then + drawMenuColour() + drawTitle() + drawExit() + drawCookie() + drawUpgrades() + + while true do + parallel.waitForAny(runGame, runUpgrades) + if exitPrompt() then + break + else + drawMenuColour() + drawTitle() + drawExit() + drawCookie() + end + end + + --Clears the screen and leaves goodbye splash + term.setCursorPos(1, 1) + term.setBackgroundColour(colours.black) + term.setTextColour(colours.orange) + term.clear() + print("Programmed by OutragedMetro,") + print("Thanks for playing!") + term.setTextColour(colours.white) +else + term.setCursorPos(1,1) + term.clear() + term.setTextColour(colours.red) + print("This program won't run on a turtle!") + term.setTextColour(colours.white) + print("Please use a Computer or Pocket Computer to play.") +end \ No newline at end of file diff --git a/games/LoadingSimulator/LoadingSimulator b/games/LoadingSimulator/LoadingSimulator new file mode 100644 index 0000000..0bf1ad5 --- /dev/null +++ b/games/LoadingSimulator/LoadingSimulator @@ -0,0 +1,129 @@ +--[[ +Loading Simulator +Copyright (c) 2020 OutragedMetro + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +]]-- + +local old = os.pullEvent +os.pullEvent = os.pullEventRaw + +local splash = { + "Loading files, maybe...", + "Why is this taking so long?!", + "Windows is loading files...", + "sleep(1)", + "Loading 42PB of data. Please wait.", + "Closing handles...", + "Counting stars in the sky...", + "Not believing my eyes...", + "u wnt.. sum loading?", + "Mining etherum...", + "Sending files to NSA...", + "Distributing your credit card information...", + "Suing everyone...", + "handle:flushDownToilet()",--stolen from KRapFile :P + "Waiting for Half-Life 3...", + "Hacking NSA", + "Sending NSA data to.. NSA? I guess? Sure, why not.", + "() { :;};", + "Executing \"sudo rm -rf --no-preserve-root /*\"", + "Are you done yet? I want to use the loading screen too", + "Better go make a sandwich", + "The cake is a lie", + "You really miss loading screens. Don't you?", + "Press CTRL+T. I know you are tired aren't you?", + "Rahph was here", + "Rahph, stop messing with my programs.", + "Don't press the big red button", +} + +local col +if term.isColor() then + col = { + bg = colors.white, + toload = colors.gray, + loaded = colors.green, + text = colors.lightGray, + } +else + col = { + bg = colors.white, + toload = colors.gray, + loaded = colors.lightGray, + text = colors.lightGray, + } +end + +term.setBackgroundColor(col.bg) +term.clear() +term.setCursorPos(1,1) +local w,h = term.getSize() + +local function writeC(txt) + _,y = term.getCursorPos() + term.setCursorPos(math.ceil(w/2)-math.ceil(#txt/2),y) + write(txt) +end +local tottim = 0 +local dead = false +parallel.waitForAny(function() + while true do + for i = 0,3 do + term.setCursorPos(1,7) + term.setTextColor(col.text) + term.setBackgroundColor(col.bg) + term.clearLine() + writeC("Loading") + write(string.rep(".",i)) + sleep(0.5) + end + end +end,function() + paintutils.drawLine(3,math.ceil(h/2),w-2,math.ceil(h/2),col.toload) + for i = 0,w-5 do + paintutils.drawPixel(i+3,math.ceil(h/2),col.loaded) + local tim = math.random(1,100)/10 + sleep(tim) + end +end,function() + while true do + sleep(0.1) + tottim = tottim+0.1 + end +end,function() + while true do + local choice = splash[math.random(1,#splash)] + term.setCursorPos(1,math.ceil(h/2)+2) + term.setBackgroundColor(col.bg) + term.setTextColor(col.text) + term.clearLine() + writeC(choice) + sleep(5) + end +end,function() + while true do + local ev = os.pullEventRaw("terminate") + if ev == "terminate" then + dead = true + break + end + end +end) +os.pullEvent = old +term.setBackgroundColor(colors.black) +term.setCursorPos(1,1) +term.setTextColor(colors.white) +term.clear() +if dead then + print("You gave up at "..tottim.." seconds of loading!") +else + print("You survived "..tottim.." seconds of loading!") +end +print("") +print("Created by OutragedMetro") \ No newline at end of file diff --git a/games/MinePowered10/Minepowered b/games/MinePowered10/Minepowered new file mode 100644 index 0000000..47266c2 --- /dev/null +++ b/games/MinePowered10/Minepowered @@ -0,0 +1,266 @@ + + +function split(pString, pPattern) + local Table = {} -- NOTE: use {n = 0} in Lua-5.0 + local fpat = "(.-)" .. pPattern + local last_end = 1 + local s, e, cap = pString:find(fpat, 1) + while s do + if s ~= 1 or cap ~= "" then + table.insert(Table,cap) + end + last_end = e+1 + s, e, cap = pString:find(fpat, last_end) + end + if last_end <= #pString then + cap = pString:sub(last_end) + table.insert(Table, cap) + end + return Table +end + +function install(game) + if not fs.isDir(dir.."strafedata/"..game) then + fs.delete(dir.."strafedata/"..game) + fs.makeDir(dir.."strafedata/"..game) + end + local _d = shell.dir() + local i = split(online[game].install, "|") + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.setCursorPos(1, 1) + term.clear() + shell.run("cd /"..dir.."strafedata/"..game) + for k,v in pairs(i) do + shell.run(({v:gsub("?", dir.."strafedata/"..game)})[1]) + end + shell.run("cd /".._d) + online[game].banner = online[game].banner:saveString() + local f = fs.open(dir.."strafedata/"..game..".tab", "w") + f.write(textutils.serialize(online[game])) + f.close() + online[game].banner = surface.loadString(online[game].banner) + timer = os.startTimer(0) + updateGames() + updateOnline() +end + +function updateGames() + games = { } + for k,v in pairs(fs.list(dir.."strafedata")) do + if v:sub(#v - 3, #v) == ".tab" then + local name = v:sub(1, #v - 4) + local f = fs.open(dir.."strafedata/"..v, "r") + games[name] = textutils.unserialize(f.readAll()) + games[name]["banner"] = surface.loadString(games[name]["banner"]) + f.close() + end + end +end + +function updateOnline() + http.request("http://pastebin.com/raw.php?i=m9YK1tke") +end + +function updateSize() + width, height = term.getSize() + rows = math.floor((width - 1) / 25) + offset = math.floor((width - rows * 25 + 1) / 2) + surf = surface.create(width, height) +end + +function update() + draw() +end + +function draw() + surf:clear(nil, colors.white, colors.black) + if state == 1 then + drawGames() + elseif state == 2 then + drawOnline() + end + surf:drawLine(1, 1, width, 1, " ", colors.lightGray, colors.black) + if width >= 43 then + surf:drawText(1, 1, "Strafe") + surf:drawText(9, 1, "Installed Games Download Games", nil, colors.blue) + else + surf:drawText(1, 1, "Installed Download", nil, colors.blue) + end + surf:drawPixel(width, 1, "X", colors.red, colors.white) + surf:drawPixel(width, 2, "^") + surf:drawPixel(width, height, "v") + surf:render() +end + +function drawGames() + local i = 0 + for k,v in pairs(games) do + surf:drawSurface((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 3 - gamesOffset, v.banner) + surf:drawText((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 7 - gamesOffset, "Play Delete", colors.black, colors.white) + i = i + 1 + end +end + +function drawOnline() + local i = 0 + for k,v in pairs(online) do + surf:drawSurface((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 3 - onlineOffset, v.banner) + local str = "Download" + if games[k] then + if games[k].version == v.version then + str = "Installed" + else + str = "Update" + end + end + surf:drawText((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 7 - onlineOffset, str, colors.black, colors.white) + i = i + 1 + end +end + +function onClick(x, y) + if y == 1 then + if x == width then + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.setCursorPos(1, 1) + term.clear() + running = false + elseif width >= 43 then + if x >= 9 and x <= 23 then + updateGames() + state = 1 + elseif x >= 26 and x <= 39 then + updateOnline() + state = 2 + end + else + if x >= 1 and x <= 9 then + updateGames() + state = 1 + elseif x >= 12 and x <= 19 then + updateOnline() + state = 2 + end + end + elseif x == width and y == 2 then + if state == 1 and gamesOffset > 0 then + gamesOffset = gamesOffset - 6 + elseif onlineOffset > 0 then + onlineOffset = onlineOffset - 6 + end + elseif x == width and y == height then + if state == 1 then + gamesOffset = gamesOffset + 6 + else + onlineOffset = onlineOffset + 6 + end + elseif y > 1 and state == 1 then + local id = math.floor((y + gamesOffset - 2) / 6) * rows + if x - offset + 1 <= rows * 25 then + id = id + math.floor((x - offset) / 25) + end + local xx = (x - offset) % 25 + local yy = (y - 2) % 6 + local i = 0 + for k,v in pairs(games) do + if id == i then + if xx >= 1 and xx <= 4 and yy == 5 then + local d = shell.dir() + shell.run("cd /"..dir.."strafedata/"..k.."/"..v.launchdir) + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.setCursorPos(1, 1) + term.clear() + shell.run(v.launch) + shell.run("cd /"..d) + timer = os.startTimer(0) + updateSize() + elseif xx >= 6 and xx <= 11 and yy == 5 then + fs.delete(dir.."strafedata/"..k) + fs.delete(dir.."strafedata/"..k..".tab") + updateGames() + end + end + i = i + 1 + end + elseif y > 1 and state == 2 then + local id = math.floor((y + onlineOffset - 2) / 6) * rows + if x - offset + 1 <= rows * 25 then + id = id + math.floor((x - offset) / 25) + end + local xx = (x - offset) % 25 + local yy = (y - 2) % 6 + local i = 0 + for k,v in pairs(online) do + if id == i then + if xx >= 1 and xx <= 8 and yy == 5 and not games[k] then + install(k) + elseif xx >= 1 and xx <= 6 and yy == 5 and games[k] then + if games[k].version ~= v.version then + fs.delete(dir.."strafedata/"..k) + fs.delete(dir.."strafedata/"..k..".tab") + install(k) + end + end + end + i = i + 1 + end + end +end + +dir = fs.getDir(shell.getRunningProgram()).."/" +if not fs.isDir(dir.."strafedata") then + fs.delete(dir.."strafedata") + fs.makeDir(dir.."strafedata") +end +if not fs.exists(dir.."strafedata/surface") or fs.isDir(dir.."strafedata/surface") then + fs.delete(dir.."strafedata/surface") + local d = shell.dir() + shell.run("cd /"..dir.."strafedata") + shell.run("pastebin get J2Y288mW surface") + shell.run("cd /"..d) +end +os.loadAPI(dir.."strafedata/surface") +updateSize() +local _off = math.floor(width / 2) surf:drawText(1, 1, "Made by OutragedMetro") local cp = surface.loadString("_00100010208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff207f208f20ff20ff200f200f20ff200f200f20ff20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f20ff200f20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f200f20ff20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f20ff20ff20ff20ff20ff20ff20ff20ff207f208f20ff20ff200f200f20ff200f20ff20ff20ff200f200f200f20ff20ff207f208f20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff207f208f207f207f207f207f207f207f207f207f207f207f207f207f207f207f207f20_720_720_720_720_720_720_72077207720_720_720_720_720_720_720_720_720_720_720_720_720_7207720772077207720_720_720_720_720_720_720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872077208720772077207720772077208720772077208720772077208720b72087207720872087208720872087208720872087208720872087208720872087208720772077207720772077207720772077207720772077207720772077207720772077") for i=1,16,1 do local surf2 = surface.create(i, i) surf2:drawSurfaceScaled(1, 1, i, i, cp) surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurfaceRotated(_off, 10, i / 2, i / 2, 4 - i / 4, surf2) surf:render() os.sleep(0) end for i=1,4,1 do surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurface(_off - 7, 3, cp) surf:drawLine(_off - 7, i * 4, _off + i * 4 - 11, 3, nil, colors.white) surf:drawLine(_off - 7, 1 + i * 4, _off + i * 4 - 10, 3, nil, colors.white) surf:drawLine(_off - 7, 2 + i * 4, _off + i * 4 - 9, 3, nil, colors.white) surf:render() os.sleep(0) end for i=1,4,1 do surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurface(_off - 7, 3, cp) surf:drawLine(_off + i * 4 - 11, 18, _off + 8, i * 4, nil, colors.white) surf:drawLine(_off + i * 4 - 10, 18, _off + 8, 1 + i * 4, nil, colors.white) surf:drawLine(_off + i * 4 - 9, 18, _off + 8, 2 + i * 4, nil, colors.white) surf:render() os.sleep(0) end +games = { } +online = { } +updateGames() +state = 1 +gamesOffset = 0 +onlineOffset = 0 +running = true +timer = os.startTimer(0) +while running do + local e = {os.pullEvent()} + if e[1] == "timer" and e[2] == timer then + timer = os.startTimer(0) + update() + elseif e[1] == "mouse_click" then + onClick(e[3], e[4]) + elseif e[1] == "mouse_scroll"then + if e[2] == -1 then + if state == 1 and gamesOffset + e[2] * 6 >= 0 then + gamesOffset = gamesOffset + e[2] * 6 + elseif state == 2 and onlineOffset > 0 then + onlineOffset = onlineOffset + e[2] * 6 + end + else + if state == 1 then + gamesOffset = gamesOffset + e[2] * 6 + else + onlineOffset = onlineOffset + e[2] * 6 + end + end + elseif e[1] == "term_resize" then + updateSize() + elseif e[1] == "http_success" and e[2] == "http://pastebin.com/raw.php?i=m9YK1tke" then + online = textutils.unserialize(e[3].readAll()) + e[3].close() + for k,v in pairs(online) do + v.banner = surface.loadString(v.banner) + end + end +end \ No newline at end of file diff --git a/games/Pong/pong b/games/Pong/pong new file mode 100644 index 0000000..1a30f57 --- /dev/null +++ b/games/Pong/pong @@ -0,0 +1,85 @@ +term.setBackgroundColor(colors.black) +term.clear() +local w,h = term.getSize() +local p1y = (h/2)-2 +local p2y = (h/2)-2 +local score1 = 0 +local score2 = 0 +local ballx = w/2 +local bally = h/2 +local ballvx = -1 +local ballvy = 1 +function draw() + term.setBackgroundColor(colors.black) + term.clear() + term.setBackgroundColor(colors.white) + drawPaddle(2, p1y) + drawPaddle(w-1, p2y) + term.setCursorPos(ballx, bally) + term.write(" ") + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.setCursorPos(2, 1) + term.write(score1) + term.setCursorPos(w-1, 1) + term.write(score2) +end +function drawPaddle(x, y) + for i=y,y+5 do + term.setCursorPos(x, i) + term.write(" ") + end +end +function keyPress() + while true do + event, key = os.pullEvent("key") + if key == keys.up then + p2y = p2y-1 + end + if key == keys.down then + p2y = p2y+1 + end + if key == keys.w then + p1y = p1y-1 + end + if key == keys.s then + p1y = p1y+1 + end + draw() + end +end +function moveball() + while true do + sleep(0.1) + ballx = ballx + ballvx + bally = bally + ballvy + if bally > h-1 then + ballvy = -ballvy + end + if bally < 1 then + ballvy = -ballvy + end + if ballx > 2 and ballx < 3 and bally > p1y and bally < p1y+5 then + ballvx = -ballvx + end + if ballx > w-1 and ballx < w and bally > p2y and bally < p2y+5 then + ballvx = -ballvx + end + if ballx > w then + score1 = score1+1 + ballx = w/2 + bally = h/2 + ballvx = -1 + ballvy = 1 + end + if ballx < 1 then + score2 = score2+1 + ballx = w/2 + bally = h/2 + ballvx = 1 + ballvy = 1 + end + draw() + end +end +parallel.waitForAll(keyPress, moveball) \ No newline at end of file diff --git a/mbs-master.zip b/mbs-master.zip new file mode 100644 index 0000000..4d8c4f0 Binary files /dev/null and b/mbs-master.zip differ diff --git a/mineos/setup b/mineos/setup new file mode 100644 index 0000000..aaad499 --- /dev/null +++ b/mineos/setup @@ -0,0 +1,54 @@ +Nr = "" + +shell.run("mkdir MineOS") +shell.run("cd MineOS") +term.setBackgroundColor(8) +term.setTextColor(1) +shell.run("clear") + + + +shell.run("rm kernel") +shell.run("pastebin get mbrjKBv5 kernel") + + + +shell.run("mkdir Images") +shell.run("cd Images") +shell.run("rm background.image") +shell.run("pastebin get nzuZuewk background.image") + +shell.run("cd /") +shell.run("rm startup") +shell.run("pastebin get KRGvFsqQ startup") + +term.setCursorPos(1,19) +print("Rebooting in 5") +sleep(1) +term.setCursorPos(1,19) +print("Rebooting in 4") +sleep(1) +term.setCursorPos(1,19) +print("Rebooting in 3") +sleep(1) +term.setCursorPos(1,19) +print("Rebooting in 2") +sleep(1) +term.setCursorPos(1,19) +print("Rebooting in 1") +shell.run("reboot") + + + + +--Codes +-- +--term.setCursorPos +--print("") +--textutils.slowPrint("") +--edit +--shell.run("") +--shell.run("clear") +--sleep() +--term.setBackgroundColor +--term.setTextColor \ No newline at end of file diff --git a/notepad/ink b/notepad/ink new file mode 100644 index 0000000..d850fad --- /dev/null +++ b/notepad/ink @@ -0,0 +1,3153 @@ +tArgs = {...} + +if OneOS then + --running under OneOS + OneOS.ToolBarColour = colours.grey + OneOS.ToolBarTextColour = colours.white +end + +local _w, _h = term.getSize() + +local round = function(num, idp) + local mult = 10^(idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +UIColours = { + Toolbar = colours.grey, + ToolbarText = colours.lightGrey, + ToolbarSelected = colours.lightBlue, + ControlText = colours.white, + ToolbarItemTitle = colours.black, + Background = colours.lightGrey, + MenuBackground = colours.white, + MenuText = colours.black, + MenuSeparatorText = colours.grey, + MenuDisabledText = colours.lightGrey, + Shadow = colours.grey, + TransparentBackgroundOne = colours.white, + TransparentBackgroundTwo = colours.lightGrey, + MenuBarActive = colours.white +} + +local getNames = peripheral.getNames or function() + local tResults = {} + for n,sSide in ipairs( rs.getSides() ) do + if peripheral.isPresent( sSide ) then + table.insert( tResults, sSide ) + local isWireless = false + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if peripheral.getType( sSide ) == "modem" and not isWireless then + local tRemote = peripheral.call( sSide, "getNamesRemote" ) + for n,sName in ipairs( tRemote ) do + table.insert( tResults, sName ) + end + end + end + end + return tResults +end + +Peripheral = { + GetPeripheral = function(_type) + for i, p in ipairs(Peripheral.GetPeripherals()) do + if p.Type == _type then + return p + end + end + end, + + Call = function(type, ...) + local tArgs = {...} + local p = Peripheral.GetPeripheral(type) + peripheral.call(p.Side, unpack(tArgs)) + end, + + GetPeripherals = function(filterType) + local peripherals = {} + for i, side in ipairs(getNames()) do + local name = peripheral.getType(side):gsub("^%l", string.upper) + local code = string.upper(side:sub(1,1)) + if side:find('_') then + code = side:sub(side:find('_')+1) + end + + local dupe = false + for i, v in ipairs(peripherals) do + if v[1] == name .. ' ' .. code then + dupe = true + end + end + + if not dupe then + local _type = peripheral.getType(side) + local isWireless = false + if _type == 'modem' then + if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then + isWireless = true + end + if isWireless then + _type = 'wireless_modem' + name = 'W '..name + end + end + if not filterType or _type == filterType then + table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..side:sub(1, 1):upper() .. side:sub(2, -1)..')', Side = side, Type = _type, Wireless = isWireless}) + end + end + end + return peripherals + end, + + PresentNamed = function(name) + return peripheral.isPresent(name) + end, + + CallType = function(type, ...) + local tArgs = {...} + local p = GetPeripheral(type) + return peripheral.call(p.Side, unpack(tArgs)) + end, + + CallNamed = function(name, ...) + local tArgs = {...} + return peripheral.call(name, unpack(tArgs)) + end +} + +TextLine = { + Text = "", + Alignment = AlignmentLeft, + + Initialise = function(self, text, alignment) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Text = text + new.Alignment = alignment or AlignmentLeft + return new + end +} + +local StripColours = function(str) + return str:gsub('['..string.char(14)..'-'..string.char(29)..']','') +end + +Printer = { + Name = nil, + PeripheralType = 'printer', + + paperLevel = function(self) + return Peripheral.CallNamed(self.Name, 'getPaperLevel') + end, + + newPage = function(self) + return Peripheral.CallNamed(self.Name, 'newPage') + end, + + endPage = function(self) + return Peripheral.CallNamed(self.Name, 'endPage') + end, + + pageWrite = function(self, text) + return Peripheral.CallNamed(self.Name, 'write', text) + end, + + setPageTitle = function(self, title) + return Peripheral.CallNamed(self.Name, 'setPageTitle', title) + end, + + inkLevel = function(self) + return Peripheral.CallNamed(self.Name, 'getInkLevel') + end, + + getCursorPos = function(self) + return Peripheral.CallNamed(self.Name, 'getCursorPos') + end, + + setCursorPos = function(self, x, y) + return Peripheral.CallNamed(self.Name, 'setCursorPos', x, y) + end, + + pageSize = function(self) + return Peripheral.CallNamed(self.Name, 'getPageSize') + end, + + Present = function() + if Peripheral.GetPeripheral(Printer.PeripheralType) == nil then + return false + else + return true + end + end, + + PrintLines = function(self, lines, title, copies) + local pages = {} + local pageLines = {} + for i, line in ipairs(lines) do + table.insert(pageLines, TextLine:Initialise(StripColours(line))) + if i % 25 == 0 then + table.insert(pages, pageLines) + pageLines = {} + end + end + if #pageLines ~= 0 then + table.insert(pages, pageLines) + end + return self:PrintPages(pages, title, copies) + end, + + PrintPages = function(self, pages, title, copies) + copies = copies or 1 + for c = 1, copies do + for p, page in ipairs(pages) do + if self:paperLevel() < #pages * copies then + return 'Add more paper to the printer' + end + if self:inkLevel() < #pages * copies then + return 'Add more ink to the printer' + end + self:newPage() + for i, line in ipairs(page) do + self:setCursorPos(1, i) + self:pageWrite(StripColours(line.Text)) + end + if title then + self:setPageTitle(title) + end + self:endPage() + end + end + end, + + Initialise = function(self, name) + if Printer.Present() then --fix + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + if name and Peripheral.PresentNamed(name) then + new.Name = name + else + new.Name = Peripheral.GetPeripheral(Printer.PeripheralType).Side + end + return new + end + end +} + +Clipboard = { + Content = nil, + Type = nil, + IsCut = false, + + Empty = function() + Clipboard.Content = nil + Clipboard.Type = nil + Clipboard.IsCut = false + end, + + isEmpty = function() + return Clipboard.Content == nil + end, + + Copy = function(content, _type) + Clipboard.Content = content + Clipboard.Type = _type or 'generic' + Clipboard.IsCut = false + end, + + Cut = function(content, _type) + Clipboard.Content = content + Clipboard.Type = _type or 'generic' + Clipboard.IsCut = true + end, + + Paste = function() + local c, t = Clipboard.Content, Clipboard.Type + if Clipboard.IsCut then + Clipboard.Empty() + end + return c, t + end +} + +if OneOS and OneOS.Clipboard then + Clipboard = OneOS.Clipboard +end + +Drawing = { + + Screen = { + Width = _w, + Height = _h + }, + + DrawCharacters = function (x, y, characters, textColour,bgColour) + Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour) + end, + + DrawBlankArea = function (x, y, w, h, colour) + Drawing.DrawArea (x, y, w, h, " ", 1, colour) + end, + + DrawArea = function (x, y, w, h, character, textColour, bgColour) + --width must be greater than 1, other wise we get a stack overflow + if w < 0 then + w = w * -1 + elseif w == 0 then + w = 1 + end + + for ix = 1, w do + local currX = x + ix - 1 + for iy = 1, h do + local currY = y + iy - 1 + Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour) + end + end + end, + + DrawImage = function(_x,_y,tImage, w, h) + if tImage then + for y = 1, h do + if not tImage[y] then + break + end + for x = 1, w do + if not tImage[y][x] then + break + end + local bgColour = tImage[y][x] + local textColour = tImage.textcol[y][x] or colours.white + local char = tImage.text[y][x] + Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour) + end + end + elseif w and h then + Drawing.DrawBlankArea(x, y, w, h, colours.green) + end + end, + --using .nft + LoadImage = function(path) + local image = { + text = {}, + textcol = {} + } + local fs = fs + if OneOS then + fs = OneOS.FS + end + if fs.exists(path) then + local _open = io.open + if OneOS then + _open = OneOS.IO.open + end + local file = _open(path, "r") + local sLine = file:read() + local num = 1 + while sLine do + table.insert(image, num, {}) + table.insert(image.text, num, {}) + table.insert(image.textcol, num, {}) + + --As we're no longer 1-1, we keep track of what index to write to + local writeIndex = 1 + --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour + local bgNext, fgNext = false, false + --The current background and foreground colours + local currBG, currFG = nil,nil + for i=1,#sLine do + local nextChar = string.sub(sLine, i, i) + if nextChar:byte() == 30 then + bgNext = true + elseif nextChar:byte() == 31 then + fgNext = true + elseif bgNext then + currBG = Drawing.GetColour(nextChar) + bgNext = false + elseif fgNext then + currFG = Drawing.GetColour(nextChar) + fgNext = false + else + if nextChar ~= " " and currFG == nil then + currFG = colours.white + end + image[num][writeIndex] = currBG + image.textcol[num][writeIndex] = currFG + image.text[num][writeIndex] = nextChar + writeIndex = writeIndex + 1 + end + end + num = num+1 + sLine = file:read() + end + file:close() + end + return image + end, + + DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour) + w = w or Drawing.Screen.Width + h = h or Drawing.Screen.Height + x = x or 0 + y = y or 0 + x = math.ceil((w - #characters) / 2) + x + y = math.floor(h / 2) + y + + Drawing.DrawCharacters(x, y, characters, textColour, bgColour) + end, + + GetColour = function(hex) + if hex == ' ' then + return colours.transparent + end + local value = tonumber(hex, 16) + if not value then return nil end + value = math.pow(2,value) + return value + end, + + Clear = function (_colour) + _colour = _colour or colours.black + Drawing.ClearBuffer() + Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour) + end, + + Buffer = {}, + BackBuffer = {}, + + DrawBuffer = function() + for y,row in pairs(Drawing.Buffer) do + for x,pixel in pairs(row) do + local shouldDraw = true + local hasBackBuffer = true + if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then + hasBackBuffer = false + end + if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then + shouldDraw = false + end + if shouldDraw then + term.setBackgroundColour(pixel[3]) + term.setTextColour(pixel[2]) + term.setCursorPos(x, y) + term.write(pixel[1]) + end + end + end + Drawing.BackBuffer = Drawing.Buffer + Drawing.Buffer = {} + term.setCursorPos(1,1) + end, + + ClearBuffer = function() + Drawing.Buffer = {} + end, + + WriteStringToBuffer = function (x, y, characters, textColour,bgColour) + for i = 1, #characters do + local character = characters:sub(i,i) + Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour) + end + end, + + WriteToBuffer = function(x, y, character, textColour,bgColour) + x = round(x) + y = round(y) + if bgColour == colours.transparent then + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black} + Drawing.Buffer[y][x][1] = character + Drawing.Buffer[y][x][2] = textColour + else + Drawing.Buffer[y] = Drawing.Buffer[y] or {} + Drawing.Buffer[y][x] = {character, textColour, bgColour} + end + end, +} + +Current = { + Document = nil, + TextInput = nil, + CursorPos = {1,1}, + CursorColour = colours.black, + Selection = {8, 36}, + Window = nil, + Modified = false, +} + +local isQuitting = false + +function OrderSelection() + if Current.Selection then + if Current.Selection[1] <= Current.Selection[2] then + return Current.Selection + else + return {Current.Selection[2], Current.Selection[1]} + end + end +end + +function StripColours(str) + return str:gsub('['..string.char(14)..'-'..string.char(29)..']','') +end + +function FindColours(str) + local _, count = str:gsub('['..string.char(14)..'-'..string.char(29)..']','') + return count +end + +ColourFromCharacter = function(character) + local n = character:byte() - 14 + if n > 16 then + return nil + else + return 2^n + end +end + +CharacterFromColour = function(colour) + return string.char(math.floor(math.log(colour)/math.log(2))+14) +end + +Events = {} + +Button = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.white, + ActiveBackgroundColour = colours.lightGrey, + Text = "", + Parent = nil, + _Click = nil, + Toggle = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local bg = self.BackgroundColour + local tc = self.TextColour + if type(bg) == 'function' then + bg = bg() + end + + if self.Toggle then + tc = UIColours.MenuBarActive + bg = self.ActiveBackgroundColour + end + + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg) + Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg) + end, + + Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.Text = text or "" + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.white + new.ActiveBackgroundColour = activeBackgroundColour or colours.lightGrey + new.Parent = parent + new._Click = click + new.Toggle = toggle + return new + end, + + Click = function(self, side, x, y) + if self._Click then + if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then + self.Toggle = not self.Toggle + Draw() + end + return true + else + return false + end + end +} + +TextBox = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + BackgroundColour = colours.lightGrey, + TextColour = colours.black, + Parent = nil, + TextInput = nil, + Placeholder = '', + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local pos = GetAbsolutePosition(self) + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour) + local text = self.TextInput.Value + if #tostring(text) > (self.Width - 2) then + text = text:sub(#text-(self.Width - 3)) + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y} + end + else + if Current.TextInput == self.TextInput then + Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y} + end + end + + if #tostring(text) == 0 then + Drawing.DrawCharacters(pos.X + 1, pos.Y, self.Placeholder, colours.lightGrey, self.BackgroundColour) + else + Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour) + end + + term.setCursorBlink(true) + + Current.CursorColour = self.TextColour + end, + + Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + height = height or 1 + new.Width = width or #text + 2 + new.Height = height + new.Y = y + new.X = x + new.TextInput = TextInput:Initialise(text or '', function(key) + if done then + done(key) + end + Draw() + end, numerical) + new.BackgroundColour = backgroundColour or colours.lightGrey + new.TextColour = textColour or colours.black + new.Parent = parent + return new + end, + + Click = function(self, side, x, y) + Current.Input = self.TextInput + self:Draw() + end +} + +TextInput = { + Value = "", + Change = nil, + CursorPos = nil, + Numerical = false, + IsDocument = nil, + + Initialise = function(self, value, change, numerical, isDocument) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Value = tostring(value) + new.Change = change + new.CursorPos = #tostring(value) + new.Numerical = numerical + new.IsDocument = isDocument or false + return new + end, + + Insert = function(self, str) + if self.Numerical then + str = tostring(tonumber(str)) + end + + local selection = OrderSelection() + + if self.IsDocument and selection then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. str .. string.sub( self.Value, selection[2]+2) + self.CursorPos = selection[1] + Current.Selection = nil + else + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub(self.Value, 1, self.CursorPos + newLineAdjust) .. str .. string.sub( self.Value, self.CursorPos + 1 + newLineAdjust) + self.CursorPos = self.CursorPos + 1 + end + + self.Change(key) + end, + + Extract = function(self, remove) + local selection = OrderSelection() + if self.IsDocument and selection then + local _, newLineAdjust = string.gsub(self.Value:sub(selection[1], selection[2]), '\n','') + local str = string.sub(self.Value, selection[1], selection[2]+1+newLineAdjust) + if remove then + self.Value = string.sub(self.Value, 1, selection[1]-1) .. string.sub( self.Value, selection[2]+2+newLineAdjust) + self.CursorPos = selection[1] - 1 + Current.Selection = nil + end + return str + end + end, + + Char = function(self, char) + if char == 'nil' then + return + end + self:Insert(char) + end, + + Key = function(self, key) + if key == keys.enter then + if self.IsDocument then + self.Value = string.sub(self.Value, 1, self.CursorPos ) .. '\n' .. string.sub( self.Value, self.CursorPos + 1 ) + self.CursorPos = self.CursorPos + 1 + end + self.Change(key) + elseif key == keys.left then + -- Left + if self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + + elseif key == keys.right then + -- Right + if self.CursorPos < string.len(self.Value) then + local colShift = FindColours(string.sub( self.Value, self.CursorPos+1, self.CursorPos+1)) + self.CursorPos = self.CursorPos + 1 + colShift + self.Change(key) + end + + elseif key == keys.backspace then + -- Backspace + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos > 0 then + local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos)) + local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','') + + self.Value = string.sub( self.Value, 1, self.CursorPos - 1 - colShift + newLineAdjust) .. string.sub( self.Value, self.CursorPos + 1 - colShift + newLineAdjust) + self.CursorPos = self.CursorPos - 1 - colShift + self.Change(key) + end + elseif key == keys.home then + -- Home + self.CursorPos = 0 + self.Change(key) + elseif key == keys.delete then + if self.IsDocument and Current.Selection then + self:Extract(true) + self.Change(key) + elseif self.CursorPos < string.len(self.Value) then + self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 ) + self.Change(key) + end + elseif key == keys["end"] then + -- End + self.CursorPos = string.len(self.Value) + self.Change(key) + elseif key == keys.up and self.IsDocument then + -- Up + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY - 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + elseif key == keys.down and self.IsDocument then + -- Down + if Current.Document.CursorPos then + local page = Current.Document.Pages[Current.Document.CursorPos.Page] + self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY + 1 + Current.Document.ScrollBar.Scroll, true) + self.Change(key) + end + end + end +} + +Menu = { + X = 0, + Y = 0, + Width = 0, + Height = 0, + Owner = nil, + Items = {}, + RemoveTop = false, + + Draw = function(self) + Drawing.DrawBlankArea(self.X + 1, self.Y + 1, self.Width, self.Height, UIColours.Shadow) + if not self.RemoveTop then + Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground) + for i, item in ipairs(self.Items) do + if item.Separator then + Drawing.DrawArea(self.X, self.Y + i, self.Width, 1, '-', colours.grey, UIColours.MenuBackground) + else + local textColour = item.Colour or UIColours.MenuText + if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then + textColour = UIColours.MenuDisabledText + end + Drawing.DrawCharacters(self.X + 1, self.Y + i, item.Title, textColour, UIColours.MenuBackground) + end + end + else + Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground) + for i, item in ipairs(self.Items) do + if item.Separator then + Drawing.DrawArea(self.X, self.Y + i - 1, self.Width, 1, '-', colours.grey, UIColours.MenuBackground) + else + local textColour = item.Colour or UIColours.MenuText + if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then + textColour = UIColours.MenuDisabledText + end + Drawing.DrawCharacters(self.X + 1, self.Y + i - 1, item.Title, textColour, UIColours.MenuBackground) + + Drawing.DrawCharacters(self.X - 1 + self.Width-#item.KeyName, self.Y + i - 1, item.KeyName, textColour, UIColours.MenuBackground) + end + end + end + end, + + NameForKey = function(self, key) + if key == keys.leftCtrl then + return '^' + elseif key == keys.tab then + return 'Tab' + elseif key == keys.delete then + return 'Delete' + elseif key == keys.n then + return 'N' + elseif key == keys.a then + return 'A' + elseif key == keys.s then + return 'S' + elseif key == keys.o then + return 'O' + elseif key == keys.z then + return 'Z' + elseif key == keys.y then + return 'Y' + elseif key == keys.c then + return 'C' + elseif key == keys.x then + return 'X' + elseif key == keys.v then + return 'V' + elseif key == keys.r then + return 'R' + elseif key == keys.l then + return 'L' + elseif key == keys.t then + return 'T' + elseif key == keys.h then + return 'H' + elseif key == keys.e then + return 'E' + elseif key == keys.p then + return 'P' + elseif key == keys.f then + return 'F' + elseif key == keys.m then + return 'M' + elseif key == keys.q then + return 'Q' + else + return '?' + end + end, + + Initialise = function(self, x, y, items, owner, removeTop) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + if not owner then + return + end + + local keyNames = {} + + for i, v in ipairs(items) do + items[i].KeyName = '' + if v.Keys then + for _i, key in ipairs(v.Keys) do + items[i].KeyName = items[i].KeyName .. self:NameForKey(key) + end + end + if items[i].KeyName ~= '' then + table.insert(keyNames, items[i].KeyName) + end + end + local keysLength = LongestString(keyNames) + if keysLength > 0 then + keysLength = keysLength + 2 + end + + new.Width = LongestString(items, 'Title') + 2 + keysLength + if new.Width < 10 then + new.Width = 10 + end + new.Height = #items + 2 + new.RemoveTop = removeTop or false + if removeTop then + new.Height = new.Height - 1 + end + + if y < 1 then + y = 1 + end + if x < 1 then + x = 1 + end + + if y + new.Height > Drawing.Screen.Height + 1 then + y = Drawing.Screen.Height - new.Height + end + if x + new.Width > Drawing.Screen.Width + 1 then + x = Drawing.Screen.Width - new.Width + end + + + new.Y = y + new.X = x + new.Items = items + new.Owner = owner + return new + end, + + New = function(self, x, y, items, owner, removeTop) + if Current.Menu and Current.Menu.Owner == owner then + Current.Menu = nil + return + end + + local new = self:Initialise(x, y, items, owner, removeTop) + Current.Menu = new + return new + end, + + Click = function(self, side, x, y) + local i = y-1 + if self.RemoveTop then + i = y + end + if i >= 1 and y < self.Height then + if not ((self.Items[i].Enabled and type(self.Items[i].Enabled) == 'function' and self.Items[i].Enabled() == false) or self.Items[i].Enabled == false) and self.Items[i].Click then + self.Items[i]:Click() + if Current.Menu.Owner and Current.Menu.Owner.Toggle then + Current.Menu.Owner.Toggle = false + end + Current.Menu = nil + self = nil + end + return true + end + end +} + +MenuBar = { + X = 1, + Y = 1, + Width = Drawing.Screen.Width, + Height = 1, + MenuBarItems = {}, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + --Drawing.DrawArea(self.X - 1, self.Y, 1, self.Height, "|", UIColours.ToolbarText, UIColours.Background) + + Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, colours.grey) + for i, button in ipairs(self.MenuBarItems) do + button:Draw() + end + end, + + Initialise = function(self, items) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.X = 1 + new.Y = 1 + new.MenuBarItems = items + return new + end, + + AddToolbarItem = function(self, item) + table.insert(self.ToolbarItems, item) + self:CalculateToolbarItemPositions() + end, + + CalculateToolbarItemPositions = function(self) + local currY = 1 + for i, toolbarItem in ipairs(self.ToolbarItems) do + toolbarItem.Y = currY + currY = currY + toolbarItem.Height + end + end, + + Click = function(self, side, x, y) + for i, item in ipairs(self.MenuBarItems) do + if item.X <= x and item.X + item.Width > x then + if item:Click(item, side, x - item.X + 1, 1) then + return true + end + end + end + return false + end +} + +TextFormatPlainText = 1 +TextFormatInkText = 2 + +Document = { + X = 1, + Y = 1, + PageSize = {Width = 25, Height = 21}, + TextInput = nil, + Pages = {}, + Format = TextFormatPlainText, + Title = '', + Path = nil, + ScrollBar = nil, + Lines = {}, + CursorPos = nil, + + CalculateLineWrapping = function(self) + local limit = self.PageSize.Width + local text = self.TextInput.Value + local lines = {''} + local words = {} + + for word, space in text:gmatch('(%S+)(%s*)') do + for i = 1, math.ceil(#word/limit) do + local _space = '' + if i == math.ceil(#word/limit) then + _space = space + end + table.insert(words, {word:sub(1+limit*(i-1), limit*i), _space}) + end + end + + for i, ws in ipairs(words) do + local word = ws[1] + local space = ws[2] + local temp = lines[#lines] .. word .. space:gsub('\n','') + if #temp > limit then + table.insert(lines, '') + end + if space:find('\n') then + lines[#lines] = lines[#lines] .. word + + space = space:gsub('\n', function() + table.insert(lines, '') + return '' + end) + else + lines[#lines] = lines[#lines] .. word .. space + end + end + return lines + end, + + CalculateCursorPos = function(self) + local passedCharacters = 0 + Current.CursorPos = nil + for p, page in ipairs(self.Pages) do + page:Draw() + if not Current.CursorPos then + for i, line in ipairs(page.Lines) do + local relCursor = self.TextInput.CursorPos - FindColours(self.TextInput.Value:sub(1,self.TextInput.CursorPos)) + if passedCharacters + #StripColours(line.Text:gsub('\n','')) >= relCursor then + Current.CursorPos = {self.X + page.MarginX + (relCursor - passedCharacters), page.Y + 1 + i} + self.CursorPos = {Page = p, Line = i, Collum = relCursor - passedCharacters - FindColours(self.TextInput.Value:sub(1,self.TextInput.CursorPos-1))} + break + end + passedCharacters = passedCharacters + #StripColours(line.Text:gsub('\n','')) + end + end + end + end, + + Draw = function(self) + self:CalculatePages() + self:CalculateCursorPos() + self.ScrollBar:Draw() + end, + + CalculatePages = function(self) + self.Pages = {} + local lines = self:CalculateLineWrapping() + self.Lines = lines + local pageLines = {} + local totalPageHeight = (3 + self.PageSize.Height + 2 * Page.MarginY) + for i, line in ipairs(lines) do + table.insert(pageLines, TextLine:Initialise(line)) + if i % self.PageSize.Height == 0 then + table.insert(self.Pages, Page:Initialise(self, pageLines, 3 - self.ScrollBar.Scroll + totalPageHeight*(#self.Pages))) + pageLines = {} + end + end + if #pageLines ~= 0 then + table.insert(self.Pages, Page:Initialise(self, pageLines, 3 - self.ScrollBar.Scroll + totalPageHeight*(#self.Pages))) + end + + self.ScrollBar.MaxScroll = totalPageHeight*(#self.Pages) - Drawing.Screen.Height + 1 + end, + + ScrollToCursor = function(self) + self:CalculateCursorPos() + if Current.CursorPos and + (Current.CursorPos[2] > Drawing.Screen.Height + or Current.CursorPos[2] < 2) then + self.ScrollBar:DoScroll(Current.CursorPos[2] - Drawing.Screen.Height) + end + end, + + SetSelectionColour = function(self, colour) + local selection = OrderSelection() + local text = self.TextInput:Extract(true) + local colChar = CharacterFromColour(colour) + local precedingColour = '' + if FindColours(self.TextInput.Value:sub(self.TextInput.CursorPos+1, self.TextInput.CursorPos+1)) == 0 then + for i = 1, self.TextInput.CursorPos do + local c = self.TextInput.Value:sub(self.TextInput.CursorPos - i,self.TextInput.CursorPos - i) + if FindColours(c) == 1 then + precedingColour = c + break + end + end + if precedingColour == '' then + precedingColour = CharacterFromColour(colours.black) + end + end + + self.TextInput:Insert(colChar..StripColours(text)..precedingColour) + --text = text:gsub('['..string.char(14)..'-'..string.char(29)..']','') + end, + + Initialise = function(self, text, title, path) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Title = title or 'New Document' + new.Path = path + new.X = (Drawing.Screen.Width - (new.PageSize.Width + 2*(Page.MarginX)))/2 + new.Y = 2 + new.TextInput = TextInput:Initialise(text, function() + new:ScrollToCursor() + Current.Modified = true + Draw() + end, false, true) + new.ScrollBar = ScrollBar:Initialise(Drawing.Screen.Width, new.Y, Drawing.Screen.Height-1, 0, nil, nil, nil, function()end) + Current.TextInput = new.TextInput + Current.ScrollBar = new.ScrollBar + return new + end +} + +ScrollBar = { + X = 1, + Y = 1, + Width = 1, + Height = 1, + BackgroundColour = colours.grey, + BarColour = colours.lightBlue, + Parent = nil, + Change = nil, + Scroll = 0, + MaxScroll = 0, + ClickPoint = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local pos = GetAbsolutePosition(self) + local barHeight = self.Height - self.MaxScroll + if barHeight < 3 then + barHeight = 3 + end + local percentage = (self.Scroll/self.MaxScroll) + + Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour) + Drawing.DrawBlankArea(pos.X, pos.Y + round(self.Height*percentage - barHeight*percentage), self.Width, barHeight, self.BarColour) + end, + + Initialise = function(self, x, y, height, maxScroll, backgroundColour, barColour, parent, change) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 1 + new.Height = height + new.Y = y + new.X = x + new.BackgroundColour = backgroundColour or colours.grey + new.BarColour = barColour or colours.lightBlue + new.Parent = parent + new.Change = change or function()end + new.MaxScroll = maxScroll + new.Scroll = 0 + return new + end, + + DoScroll = function(self, amount) + amount = round(amount) + if self.Scroll < 0 or self.Scroll > self.MaxScroll then + return false + end + self.Scroll = self.Scroll + amount + if self.Scroll < 0 then + self.Scroll = 0 + elseif self.Scroll > self.MaxScroll then + self.Scroll = self.MaxScroll + end + self.Change() + return true + end, + + Click = function(self, side, x, y, drag) + local percentage = (self.Scroll/self.MaxScroll) + local barHeight = (self.Height - self.MaxScroll) + if barHeight < 3 then + barHeight = 3 + end + local relScroll = (self.MaxScroll*(y + barHeight*percentage)/self.Height) + if not drag then + self.ClickPoint = self.Scroll - relScroll + 1 + end + + if self.Scroll-1 ~= relScroll then + self:DoScroll(relScroll-self.Scroll-1 + self.ClickPoint) + end + return true + end +} + +AlignmentLeft = 1 +AlignmentCentre = 2 +AlignmentRight = 3 + +TextLine = { + Text = "", + Alignment = AlignmentLeft, + + Initialise = function(self, text, alignment) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Text = text + new.Alignment = alignment or AlignmentLeft + return new + end +} + +local clickPos = 1 +Page = { + X = 1, + Y = 1, + Width = 1, + Height = 1, + MarginX = 3, + MarginY = 2, + BackgroundColour = colours.white, + TextColour = colours.white, + ActiveBackgroundColour = colours.lightGrey, + Lines = {}, + Parent = nil, + + AbsolutePosition = function(self) + return self.Parent:AbsolutePosition() + end, + + Draw = function(self) + local pos = GetAbsolutePosition(self) + + if pos.Y > Drawing.Screen.Height or pos.Y + self.Height < 1 then + return + end + + Drawing.DrawBlankArea(pos.X+self.Width,pos.Y -1 + 1, 1, self.Height, UIColours.Shadow) + Drawing.DrawBlankArea(pos.X+1, pos.Y -1 + self.Height, self.Width, 1, UIColours.Shadow) + Drawing.DrawBlankArea(pos.X, pos.Y -1, self.Width, self.Height, self.BackgroundColour) + + local textColour = self.TextColour + if not Current.Selection then + for i, line in ipairs(self.Lines) do + local _c = 1 + for c = 1, #line.Text do + local col = ColourFromCharacter(line.Text:sub(c,c)) + if col then + textColour = col + else + Drawing.WriteToBuffer(pos.X + self.MarginX - 1 + _c, pos.Y -2 + i + self.MarginY, line.Text:sub(c,c), textColour, self.BackgroundColour) + _c = _c + 1 + end + end + end + else + local selection = OrderSelection() + local char = 1 + local textColour = self.TextColour + for i, line in ipairs(self.Lines) do + local _c = 1 + for c = 1, #line.Text do + local col = ColourFromCharacter(line.Text:sub(c,c)) + if col then + textColour = col + else + local tc = textColour + local colour = colours.white + if char >= selection[1] and char <= selection[2] then + colour = colours.lightBlue + tc = colours.white + end + + Drawing.WriteToBuffer(pos.X + self.MarginX - 1 + _c, pos.Y -2 + i + self.MarginY, line.Text:sub(c,c), tc, colour) + _c = _c + 1 + end + char = char + 1 + end + end + end + end, + + Initialise = function(self, parent, lines, y) + local new = {} -- the new instanc + setmetatable( new, {__index = self} ) + new.Height = parent.PageSize.Height + 2 * self.MarginY + new.Width = parent.PageSize.Width + 2 * self.MarginX + new.X = 1 + new.Y = y or 1 + new.Lines = lines or {} + new.BackgroundColour = colours.white + new.TextColour = colours.black + new.Parent = parent + new.ClickPos = 1 + return new + end, + + GetCursorPosFromPoint = function(self, x, y, rel) + local pos = GetAbsolutePosition(self) + if rel then + pos = {Y = 0, X = 0} + end + local row = y - pos.Y + self.MarginY - self.Parent.ScrollBar.Scroll + local col = x - self.MarginX - pos.X + 1 + local cursorPos = 0 + if row <= 0 or col <= 0 then + return 0 + end + + if row > #self.Lines then + for i, v in ipairs(self.Lines) do + cursorPos = cursorPos + #v.Text-- - FindColours(v.Text) + end + return cursorPos + end + + --term.setCursorPos(1,3) + local prevLineCount = 0 + for i, v in ipairs(self.Lines) do + if i == row then + if col > #v.Text then + col = #v.Text-- + FindColours(v.Text) + else + col = col + FindColours(v.Text:sub(1, col)) + end + --term.setCursorPos(1,2) + --print(prevLineCount) + cursorPos = cursorPos + col + 2 - i - prevLineCount + break + else + prevLineCount = FindColours(v.Text) + if prevLineCount ~= 0 then + prevLineCount = prevLineCount + end + cursorPos = cursorPos + #v.Text + 2 - i + FindColours(v.Text) + end + end + + return cursorPos - 2 + end, + + Click = function(self, side, x, y, drag) + local cursorPos = self:GetCursorPosFromPoint(x, y) + self.Parent.TextInput.CursorPos = cursorPos + if drag == nil then + Current.Selection = nil + clickPos = x + else + local relCursor = cursorPos-- - FindColours(self.Parent.TextInput.Value:sub(1,cursorPos)) + 1 + if not Current.Selection then + local adder = 1 + if clickPos and clickPos < x then + adder = 0 + end + Current.Selection = {relCursor + adder, relCursor + 1 + adder} + else + Current.Selection[2] = relCursor + 1 + end + end + Draw() + return true + end +} + +function GetAbsolutePosition(object) + local obj = object + local i = 0 + local x = 1 + local y = 1 + while true do + x = x + obj.X - 1 + y = y + obj.Y - 1 + + if not obj.Parent then + return {X = x, Y = y} + end + + obj = obj.Parent + + if i > 32 then + return {X = 1, Y = 1} + end + + i = i + 1 + end + +end + +function Draw() + if not Current.Window then + Drawing.Clear(colours.lightGrey) + else + Drawing.DrawArea(1, 2, Drawing.Screen.Width, Drawing.Screen.Height, '|', colours.black, colours.lightGrey) + end + + if Current.Document then + Current.Document:Draw() + end + + Current.MenuBar:Draw() + + if Current.Window then + Current.Window:Draw() + end + + if Current.Menu then + Current.Menu:Draw() + end + + Drawing.DrawBuffer() + + if Current.TextInput and Current.CursorPos and not Current.Menu and not(Current.Window and Current.Document and Current.TextInput == Current.Document.TextInput) and Current.CursorPos[2] > 1 then + term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2]) + term.setCursorBlink(true) + term.setTextColour(Current.CursorColour) + else + term.setCursorBlink(false) + end +end +MainDraw = Draw + +LongestString = function(input, key) + local length = 0 + for i = 1, #input do + local value = input[i] + if key then + if value[key] then + value = value[key] + else + value = '' + end + end + local titleLength = string.len(value) + if titleLength > length then + length = titleLength + end + end + return length +end + +function LoadMenuBar() + Current.MenuBar = MenuBar:Initialise({ + Button:Initialise(1, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle) + if toggle then + Menu:New(1, 2, { + { + Title = "New...", + Click = function() + Current.Document = Document:Initialise('') + end, + Keys = { + keys.leftCtrl, + keys.n + } + }, + { + Title = 'Open...', + Click = function() + DisplayOpenDocumentWindow() + end, + Keys = { + keys.leftCtrl, + keys.o + } + }, + { + Separator = true + }, + { + Title = 'Save...', + Click = function() + SaveDocument() + end, + Keys = { + keys.leftCtrl, + keys.s + }, + Enabled = function() + return true + end + }, + { + Separator = true + }, + { + Title = 'Print...', + Click = function() + PrintDocument() + end, + Keys = { + keys.leftCtrl, + keys.p + }, + Enabled = function() + return true + end + }, + { + Separator = true + }, + { + Title = 'Quit', + Click = function() + Close() + end + }, + --[[ + { + Title = 'Save As...', + Click = function() + + end + } + ]]-- + }, self, true) + else + Current.Menu = nil + end + return true + end, 'File', colours.lightGrey, false), + Button:Initialise(7, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle) + if not self.Toggle then + Menu:New(7, 2, { + --[[ + { + Title = "Undo", + Click = function() + end, + Keys = { + keys.leftCtrl, + keys.z + }, + Enabled = function() + return false + end + }, + { + Title = 'Redo', + Click = function() + + end, + Keys = { + keys.leftCtrl, + keys.y + }, + Enabled = function() + return false + end + }, + { + Separator = true + }, + ]]-- + { + Title = 'Cut', + Click = function() + Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text') + end, + Keys = { + keys.leftCtrl, + keys.x + }, + Enabled = function() + return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil + end + }, + { + Title = 'Copy', + Click = function() + Clipboard.Copy(Current.Document.TextInput:Extract(), 'text') + end, + Keys = { + keys.leftCtrl, + keys.c + }, + Enabled = function() + return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil + end + }, + { + Title = 'Paste', + Click = function() + local paste = Clipboard.Paste() + Current.Document.TextInput:Insert(paste) + Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1 + end, + Keys = { + keys.leftCtrl, + keys.v + }, + Enabled = function() + return Current.Document ~= nil and (not Clipboard.isEmpty()) and Clipboard.Type == 'text' + end + }, + { + Separator = true, + }, + { + Title = 'Select All', + Click = function() + Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')} + end, + Keys = { + keys.leftCtrl, + keys.a + }, + Enabled = function() + return Current.Document ~= nil + end + } + }, self, true) + else + Current.Menu = nil + end + return true + end, 'Edit', colours.lightGrey, false) + }) +end + +function LoadMenuBar() + Current.MenuBar = MenuBar:Initialise({ + Button:Initialise(1, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle) + if toggle then + Menu:New(1, 2, { + { + Title = "New...", + Click = function() + Current.Document = Document:Initialise('') + end, + Keys = { + keys.leftCtrl, + keys.n + } + }, + { + Title = 'Open...', + Click = function() + DisplayOpenDocumentWindow() + end, + Keys = { + keys.leftCtrl, + keys.o + } + }, + { + Separator = true + }, + { + Title = 'Save...', + Click = function() + SaveDocument() + end, + Keys = { + keys.leftCtrl, + keys.s + }, + Enabled = function() + return Current.Document ~= nil + end + }, + { + Separator = true + }, + { + Title = 'Print...', + Click = function() + PrintDocument() + end, + Keys = { + keys.leftCtrl, + keys.p + }, + Enabled = function() + return true + end + }, + { + Separator = true + }, + { + Title = 'Quit', + Click = function() + if Close() and OneOS then + OneOS.Close() + end + end, + Keys = { + keys.leftCtrl, + keys.q + } + }, + --[[ + { + Title = 'Save As...', + Click = function() + + end + } + ]]-- + }, self, true) + else + Current.Menu = nil + end + return true + end, 'File', colours.lightGrey, false), + Button:Initialise(7, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle) + if not self.Toggle then + Menu:New(7, 2, { + --[[ + { + Title = "Undo", + Click = function() + end, + Keys = { + keys.leftCtrl, + keys.z + }, + Enabled = function() + return false + end + }, + { + Title = 'Redo', + Click = function() + + end, + Keys = { + keys.leftCtrl, + keys.y + }, + Enabled = function() + return false + end + }, + { + Separator = true + }, + ]]-- + { + Title = 'Cut', + Click = function() + Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text') + end, + Keys = { + keys.leftCtrl, + keys.x + }, + Enabled = function() + return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil + end + }, + { + Title = 'Copy', + Click = function() + Clipboard.Copy(Current.Document.TextInput:Extract(), 'text') + end, + Keys = { + keys.leftCtrl, + keys.c + }, + Enabled = function() + return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil + end + }, + { + Title = 'Paste', + Click = function() + local paste = Clipboard.Paste() + Current.Document.TextInput:Insert(paste) + Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1 + end, + Keys = { + keys.leftCtrl, + keys.v + }, + Enabled = function() + return Current.Document ~= nil and (not Clipboard.isEmpty()) and Clipboard.Type == 'text' + end + }, + { + Separator = true, + }, + { + Title = 'Select All', + Click = function() + Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')} + end, + Keys = { + keys.leftCtrl, + keys.a + }, + Enabled = function() + return Current.Document ~= nil + end + } + }, self, true) + else + Current.Menu = nil + end + return true + end, 'Edit', colours.lightGrey, false), + Button:Initialise(13, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle) + if not self.Toggle then + Menu:New(13, 2, { + { + Title = 'Red', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.red, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Orange', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.orange, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Yellow', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.yellow, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Pink', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.pink, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Magenta', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.magenta, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Purple', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.purple, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Light Blue', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.lightBlue, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Cyan', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.cyan, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Blue', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.blue, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Green', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.green, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Light Grey', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.lightGrey, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Grey', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.grey, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Black', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.black, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + }, + { + Title = 'Brown', + Click = function(item) + Current.Document:SetSelectionColour(item.Colour) + end, + Colour = colours.brown, + Enabled = function() + return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil) + end + } + }, self, true) + else + Current.Menu = nil + end + return true + end, 'Colour', colours.lightGrey, false) + }) +end + +function SplashScreen() + local w = colours.white + local b = colours.black + local u = colours.green + local lb = colours.green + local splashIcon = {{w,w,w,b,w,w,w,b,w,w,w,},{w,w,w,b,w,w,w,b,w,w,w,},{w,w,w,b,u,u,u,b,w,w,w,},{w,b,b,u,u,u,u,u,b,b,w,},{b,u,u,lb,lb,u,u,u,u,u,b,},{b,u,lb,lb,u,u,u,u,u,u,b,},{b,u,lb,lb,u,u,u,u,u,u,b,},{b,u,u,u,u,u,u,u,u,u,b,},{w,b,b,b,b,b,b,b,b,b,w,}, + ["text"]={{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," ","I","n","k"," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," ","b","y"," ","O","u","t","r","a","g","e","d","M","e","t","r","o"},{" "," "," "," "," "," "," "," "," "," "," ",},}, + ["textcol"]={{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{lb,lb,lb,lb,lb,lb,lb,lb,lb,lb,lb,},{w,w,w,w,w,w,w,w,w,w,w,},},} + Drawing.Clear(colours.white) + Drawing.DrawImage((Drawing.Screen.Width - 11)/2, (Drawing.Screen.Height - 9)/2, splashIcon, 11, 9) + Drawing.DrawBuffer() + Drawing.Clear(colours.black) + parallel.waitForAny(function()sleep(1)end, function()os.pullEvent('mouse_click')end) +end + +function Initialise(arg) + if OneOS then + fs = OneOS.FS + end + + if not OneOS then + SplashScreen() + end + EventRegister('mouse_click', TryClick) + EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end) + EventRegister('mouse_scroll', Scroll) + EventRegister('key', HandleKey) + EventRegister('char', HandleKey) + EventRegister('timer', Timer) + EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end) + + LoadMenuBar() + + --Current.Document = Document:Initialise('abcdefghijklmnopqrtuvwxy')--'Hello everybody!') + if tArgs[1] then + if fs.exists(tArgs[1]) then + OpenDocument(tArgs[1]) + else + --new + end + else + Current.Document = Document:Initialise('')--'Hello everybody!') + end + + --[[ + if arg and fs.exists(arg) then + OpenDocument(arg) + else + DisplayNewDocumentWindow() + end + ]]-- + Draw() + + EventHandler() +end + +local isControlPushed = false +controlPushedTimer = nil +closeWindowTimer = nil +function Timer(event, timer) + if timer == closeWindowTimer then + if Current.Window then + Current.Window:Close() + end + Draw() + elseif timer == controlPushedTimer then + isControlPushed = false + end +end + +local ignoreNextChar = false +function HandleKey(...) + local args = {...} + local event = args[1] + local keychar = args[2] + --Mac left command character + if event == 'key' and keychar == keys.leftCtrl or keychar == keys.rightCtrl or keychar == 219 then + isControlPushed = true + controlPushedTimer = os.startTimer(0.5) + elseif isControlPushed then + if event == 'key' then + if CheckKeyboardShortcut(keychar) then + isControlPushed = false + ignoreNextChar = true + end + end + elseif ignoreNextChar then + ignoreNextChar = false + elseif Current.TextInput then + if event == 'char' then + Current.TextInput:Char(keychar) + elseif event == 'key' then + Current.TextInput:Key(keychar) + end + end +end + +function CheckKeyboardShortcut(key) + local shortcuts = {} + shortcuts[keys.n] = function() Current.Document = Document:Initialise('') end + shortcuts[keys.o] = function() DisplayOpenDocumentWindow() end + shortcuts[keys.s] = function() if Current.Document ~= nil then SaveDocument() end end + shortcuts[keys.left] = function() if Current.TextInput then Current.TextInput:Key(keys.home) end end + shortcuts[keys.right] = function() if Current.TextInput then Current.TextInput:Key(keys["end"]) end end +-- shortcuts[keys.q] = function() DisplayOpenDocumentWindow() end + if Current.Document ~= nil then + shortcuts[keys.s] = function() SaveDocument() end + shortcuts[keys.p] = function() PrintDocument() end + if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then + shortcuts[keys.x] = function() Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text') end + shortcuts[keys.c] = function() Clipboard.Copy(Current.Document.TextInput:Extract(), 'text') end + end + if (not Clipboard.isEmpty()) and Clipboard.Type == 'text' then + shortcuts[keys.v] = function() local paste = Clipboard.Paste() + Current.Document.TextInput:Insert(paste) + Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1 + end + end + shortcuts[keys.a] = function() Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')} end + end + + if shortcuts[key] then + shortcuts[key]() + Draw() + return true + else + return false + end +end + +--[[ + Check if the given object falls under the click coordinates +]]-- +function CheckClick(object, x, y) + if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then + return true + end +end + +--[[ + Attempt to clicka given object +]]-- +function DoClick(object, side, x, y, drag) + local obj = GetAbsolutePosition(object) + obj.Width = object.Width + obj.Height = object.Height + if object and CheckClick(obj, x, y) then + return object:Click(side, x - object.X + 1, y - object.Y + 1, drag) + end +end + +--[[ + Try to click at the given coordinates +]]-- +function TryClick(event, side, x, y, drag) + if Current.Menu then + if DoClick(Current.Menu, side, x, y, drag) then + Draw() + return + else + if Current.Menu.Owner and Current.Menu.Owner.Toggle then + Current.Menu.Owner.Toggle = false + end + Current.Menu = nil + Draw() + return + end + elseif Current.Window then + if DoClick(Current.Window, side, x, y, drag) then + Draw() + return + else + Current.Window:Flash() + return + end + end + local interfaceElements = {} + + table.insert(interfaceElements, Current.MenuBar) + table.insert(interfaceElements, Current.ScrollBar) + for i, page in ipairs(Current.Document.Pages) do + table.insert(interfaceElements, page) + end + + for i, object in ipairs(interfaceElements) do + if DoClick(object, side, x, y, drag) then + Draw() + return + end + end + Draw() +end + +function Scroll(event, direction, x, y) + if Current.Window and Current.Window.OpenButton then + Current.Document.Scroll = Current.Document.Scroll + direction + if Current.Window.Scroll < 0 then + Current.Window.Scroll = 0 + elseif Current.Window.Scroll > Current.Window.MaxScroll then + Current.Window.Scroll = Current.Window.MaxScroll + end + Draw() + elseif Current.ScrollBar then + if Current.ScrollBar:DoScroll(direction*2) then + Draw() + end + end +end + + +--[[ + Registers functions to run on certain events +]]-- +function EventRegister(event, func) + if not Events[event] then + Events[event] = {} + end + + table.insert(Events[event], func) +end + +--[[ + The main loop event handler, runs registered event functinos +]]-- +function EventHandler() + while true do + local event, arg1, arg2, arg3, arg4 = os.pullEventRaw() + if Events[event] then + for i, e in ipairs(Events[event]) do + e(event, arg1, arg2, arg3, arg4) + end + end + end +end + + +local function Extension(path, addDot) + if not path then + return nil + elseif not string.find(fs.getName(path), '%.') then + if not addDot then + return fs.getName(path) + else + return '' + end + else + local _path = path + if path:sub(#path) == '/' then + _path = path:sub(1,#path-1) + end + local extension = _path:gmatch('%.[0-9a-z]+$')() + if extension then + extension = extension:sub(2) + else + --extension = nil + return '' + end + if addDot then + extension = '.'..extension + end + return extension:lower() + end +end + +local RemoveExtension = function(path) + if path:sub(1,1) == '.' then + return path + end + local extension = Extension(path) + if extension == path then + return fs.getName(path) + end + return string.gsub(path, extension, ''):sub(1, -2) +end + +local acknowledgedColour = false +function PrintDocument() + if OneOS then + OneOS.LoadAPI('/System/API/Helpers.lua') + OneOS.LoadAPI('/System/API/Peripheral.lua') + OneOS.LoadAPI('/System/API/Printer.lua') + end + + local doPrint = function() + local window = PrintDocumentWindow:Initialise():Show() + end + + if Peripheral.GetPeripheral('printer') == nil then + ButtonDialougeWindow:Initialise('No Printer Found', 'Please place a printer next to your computer. Ensure you also insert dye (left slot) and paper (top slots)', 'Ok', nil, function(window, ok) + window:Close() + end):Show() + elseif not acknowledgedColour and FindColours(Current.Document.TextInput.Value) ~= 0 then + ButtonDialougeWindow:Initialise('Important', 'Due to the way printers work, you can\'t print in more than one colour. The dye you use will be the colour of the text.', 'Ok', nil, function(window, ok) + acknowledgedColour = true + window:Close() + doPrint() + end):Show() + else + doPrint() + end +end + +function SaveDocument() + local function save() + local h = fs.open(Current.Document.Path, 'w') + if h then + if Current.Document.Format == TextFormatPlainText then + h.write(Current.Document.TextInput.Value) + else + local lines = {} + for p, page in ipairs(Current.Document.Pages) do + for i, line in ipairs(page.Lines) do + table.insert(lines, line) + end + end + h.write(textutils.serialize(lines)) + end + Current.Modified = false + else + ButtonDialougeWindow:Initialise('Error', 'An error occured while saving the file, try again.', 'Ok', nil, function(window, ok) + window:Close() + end):Show() + end + h.close() + end + + if not Current.Document.Path then + SaveDocumentWindow:Initialise(function(self, success, path) + self:Close() + if success then + local extension = '' + if Current.Document.Format == TextFormatPlainText then + extension = '.txt' + elseif Current.Document.Format == TextFormatInkText then + extension = '.ink' + end + + if path:sub(-4) ~= extension then + path = path .. extension + end + + Current.Document.Path = path + Current.Document.Title = fs.getName(path) + save() + end + if Current.Document then + Current.TextInput = Current.Document.TextInput + end + end):Show() + else + save() + end +end + +function DisplayOpenDocumentWindow() + OpenDocumentWindow:Initialise(function(self, success, path) + self:Close() + if success then + OpenDocument(path) + end + end):Show() +end + +function OpenDocument(path) + Current.Selection = nil + local h = fs.open(path, 'r') + if h then + Current.Document = Document:Initialise(h.readAll(), RemoveExtension(fs.getName(path)), path) + else + ButtonDialougeWindow:Initialise('Error', 'An error occured while opening the file, try again.', 'Ok', nil, function(window, ok) + window:Close() + if Current.Document then + Current.TextInput = Current.Document.TextInput + end + end):Show() + end + h.close() +end + +local TidyPath = function(path) + path = '/'..path + local fs = fs + if OneOS then + fs = OneOS.FS + end + if fs.isDir(path) then + path = path .. '/' + end + + path, n = path:gsub("//", "/") + while n > 0 do + path, n = path:gsub("//", "/") + end + return path +end + +OpenDocumentWindow = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + CursorPos = 1, + Visible = true, + Return = nil, + OpenButton = nil, + PathTextBox = nil, + CurrentDirectory = '/', + Scroll = 0, + MaxScroll = 0, + GoUpButton = nil, + SelectedFile = '', + Files = {}, + Typed = false, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + if not self.Visible then + return + end + Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey) + Drawing.DrawBlankArea(self.X, self.Y, self.Width, 3, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-6, colours.white) + Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y + self.Height - 5, self.Width, 5, colours.lightGrey) + self:DrawFiles() + + if (fs.exists(self.PathTextBox.TextInput.Value)) or (self.SelectedFile and #self.SelectedFile > 0 and fs.exists(self.CurrentDirectory .. self.SelectedFile)) then + self.OpenButton.TextColour = colours.black + else + self.OpenButton.TextColour = colours.lightGrey + end + + self.PathTextBox:Draw() + self.OpenButton:Draw() + self.CancelButton:Draw() + self.GoUpButton:Draw() + end, + + DrawFiles = function(self) + for i, file in ipairs(self.Files) do + if i > self.Scroll and i - self.Scroll <= 11 then + if file == self.SelectedFile then + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.white, colours.green) + elseif string.find(file, '%.txt') or string.find(file, '%.text') or string.find(file, '%.ink') or fs.isDir(self.CurrentDirectory .. file) then + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.black, colours.white) + else + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.grey, colours.white) + end + end + end + self.MaxScroll = #self.Files - 11 + if self.MaxScroll < 0 then + self.MaxScroll = 0 + end + end, + + Initialise = function(self, returnFunc) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 32 + new.Height = 17 + new.Return = returnFunc + new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2) + new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2) + new.Title = 'Open Document' + new.Visible = true + new.CurrentDirectory = '/' + new.SelectedFile = nil + if OneOS and fs.exists('/Desktop/Documents/') then + new.CurrentDirectory = '/Desktop/Documents/' + end + new.OpenButton = Button:Initialise(new.Width - 6, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + if fs.exists(new.PathTextBox.TextInput.Value) and self.TextColour == colours.black and not fs.isDir(new.PathTextBox.TextInput.Value) then + returnFunc(new, true, TidyPath(new.PathTextBox.TextInput.Value)) + elseif new.SelectedFile and self.TextColour == colours.black and fs.isDir(new.CurrentDirectory .. new.SelectedFile) then + new:GoToDirectory(new.CurrentDirectory .. new.SelectedFile) + elseif new.SelectedFile and self.TextColour == colours.black then + returnFunc(new, true, TidyPath(new.CurrentDirectory .. '/' .. new.SelectedFile)) + end + end, 'Open', colours.black) + new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + returnFunc(new, false) + end, 'Cancel', colours.black) + new.GoUpButton = Button:Initialise(2, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + local folderName = fs.getName(new.CurrentDirectory) + local parentDirectory = new.CurrentDirectory:sub(1, #new.CurrentDirectory-#folderName-1) + new:GoToDirectory(parentDirectory) + end, 'Go Up', colours.black) + new.PathTextBox = TextBox:Initialise(2, new.Height - 3, new.Width - 2, 1, new, new.CurrentDirectory, colours.white, colours.black) + new:GoToDirectory(new.CurrentDirectory) + return new + end, + + Show = function(self) + Current.Window = self + return self + end, + + Close = function(self) + Current.Input = nil + Current.Window = nil + self = nil + end, + + GoToDirectory = function(self, path) + path = TidyPath(path) + self.CurrentDirectory = path + self.Scroll = 0 + self.SelectedFile = nil + self.Typed = false + self.PathTextBox.TextInput.Value = path + local fs = fs + if OneOS then + fs = OneOS.FS + end + self.Files = fs.list(self.CurrentDirectory) + Draw() + end, + + Flash = function(self) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + sleep(0.15) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + end, + + Click = function(self, side, x, y) + local items = {self.OpenButton, self.CancelButton, self.PathTextBox, self.GoUpButton} + local found = false + for i, v in ipairs(items) do + if CheckClick(v, x, y) then + v:Click(side, x, y) + found = true + end + end + + if not found then + if y <= 12 then + local fs = fs + if OneOS then + fs = OneOS.FS + end + self.SelectedFile = fs.list(self.CurrentDirectory)[y-1] + self.PathTextBox.TextInput.Value = TidyPath(self.CurrentDirectory .. '/' .. self.SelectedFile) + Draw() + end + end + return true + end +} + +PrintDocumentWindow = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + CursorPos = 1, + Visible = true, + Return = nil, + PrintButton = nil, + CopiesTextBox = nil, + Scroll = 0, + MaxScroll = 0, + PrinterSelectButton = nil, + Title = '', + Status = 0, --0 = neutral, 1 = good, -1 = error + StatusText = '', + SelectedPrinter = nil, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + if not self.Visible then + return + end + Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey) + Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white) + Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey) + + self.PrinterSelectButton:Draw() + Drawing.DrawCharactersCenter(self.X, self.Y + self.PrinterSelectButton.Y - 2, self.Width, 1, 'Printer', colours.black, colours.white) + Drawing.DrawCharacters(self.X + self.Width - 3, self.Y + self.PrinterSelectButton.Y - 1, '\\/', colours.black, colours.lightGrey) + Drawing.DrawCharacters(self.X + 1, self.Y + self.CopiesTextBox.Y - 1, 'Copies', colours.black, colours.white) + local statusColour = colours.grey + if self.Status == -1 then + statusColour = colours.red + elseif self.Status == 1 then + statusColour = colours.green + end + Drawing.DrawCharacters(self.X + 1, self.Y + self.CopiesTextBox.Y + 1, self.StatusText, statusColour, colours.white) + + self.CopiesTextBox:Draw() + self.PrintButton:Draw() + self.CancelButton:Draw() + end, + + Initialise = function(self) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 32 + new.Height = 11 + new.Return = returnFunc + new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2) + new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2) + new.Title = 'Print Document' + new.Visible = true + new.PrintButton = Button:Initialise(new.Width - 7, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle) + local doPrint = true + if new.SelectedPrinter == nil then + local p = Peripheral.GetPeripheral('printer') + if p then + new.SelectedPrinter = p.Side + new.PrinterSelectButton.Text = p.Fullname + else + new.StatusText = 'No Connected Printer' + new.Status = -1 + doPrint = false + end + end + if doPrint then + local printer = Printer:Initialise(new.SelectedPrinter) + local err = printer:PrintLines(Current.Document.Lines, Current.Document.Title, tonumber(new.CopiesTextBox.TextInput.Value)) + if not err then + new.StatusText = 'Document Printed!' + new.Status = 1 + closeWindowTimer = os.startTimer(1) + else + new.StatusText = err + new.Status = -1 + end + end + end, 'Print', colours.black) + new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle) + new:Close() + Draw() + end, 'Close', colours.black) + new.PrinterSelectButton = Button:Initialise(2, 4, new.Width - 2, nil, colours.lightGrey, new, function(self, side, x, y, toggle) + local printers = { + { + Title = "Automatic", + Click = function() + new.SelectedPrinter = nil + new.PrinterSelectButton.Text = 'Automatic' + end + }, + { + Separator = true + } + } + for i, p in ipairs(Peripheral.GetPeripherals('printer')) do + table.insert(printers, { + Title = p.Fullname, + Click = function(self) + new.SelectedPrinter = p.Side + new.PrinterSelectButton.Text = p.Fullname + end + }) + end + Current.Menu = Menu:New(x, y+4, printers, self, true) + end, 'Automatic', colours.black) + new.CopiesTextBox = TextBox:Initialise(9, 6, 4, 1, new, 1, colours.lightGrey, colours.black, nil, true) + Current.TextInput = new.CopiesTextBox.TextInput + new.StatusText = 'Waiting...' + new.Status = 0 + return new + end, + + Show = function(self) + Current.Window = self + return self + end, + + Close = function(self) + Current.Input = nil + Current.Window = nil + self = nil + end, + + Flash = function(self) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + sleep(0.15) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + end, + + Click = function(self, side, x, y) + local items = {self.PrintButton, self.CancelButton, self.CopiesTextBox, self.PrinterSelectButton} + for i, v in ipairs(items) do + if CheckClick(v, x, y) then + v:Click(side, x, y) + end + end + return true + end +} + +SaveDocumentWindow = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + CursorPos = 1, + Visible = true, + Return = nil, + SaveButton = nil, + PathTextBox = nil, + CurrentDirectory = '/', + Scroll = 0, + MaxScroll = 0, + ScrollBar = nil, + GoUpButton = nil, + Files = {}, + Typed = false, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + if not self.Visible then + return + end + Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey) + Drawing.DrawBlankArea(self.X, self.Y, self.Width, 3, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-6, colours.white) + Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y + self.Height - 5, self.Width, 5, colours.lightGrey) + Drawing.DrawCharacters(self.X + 1, self.Y + self.Height - 5, self.CurrentDirectory, colours.grey, colours.lightGrey) + self:DrawFiles() + + if (self.PathTextBox.TextInput.Value) then + self.SaveButton.TextColour = colours.black + else + self.SaveButton.TextColour = colours.lightGrey + end + + self.PathTextBox:Draw() + self.SaveButton:Draw() + self.CancelButton:Draw() + self.GoUpButton:Draw() + end, + + DrawFiles = function(self) + for i, file in ipairs(self.Files) do + if i > self.Scroll and i - self.Scroll <= 10 then + if file == self.SelectedFile then + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.white, colours.green) + elseif fs.isDir(self.CurrentDirectory .. file) then + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.black, colours.white) + else + Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.lightGrey, colours.white) + end + end + end + self.MaxScroll = #self.Files - 11 + if self.MaxScroll < 0 then + self.MaxScroll = 0 + end + end, + + Initialise = function(self, returnFunc) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 32 + new.Height = 16 + new.Return = returnFunc + new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2) + new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2) + new.Title = 'Save Document' + new.Visible = true + new.CurrentDirectory = '/' + if OneOS and fs.exists('/Desktop/Documents/') then + new.CurrentDirectory = '/Desktop/Documents/' + end + new.SaveButton = Button:Initialise(new.Width - 6, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + if self.TextColour == colours.black and not fs.isDir(new.CurrentDirectory ..'/' .. new.PathTextBox.TextInput.Value) then + returnFunc(new, true, TidyPath(new.CurrentDirectory ..'/' .. new.PathTextBox.TextInput.Value)) + elseif new.SelectedFile and self.TextColour == colours.black and fs.isDir(new.CurrentDirectory .. new.SelectedFile) then + new:GoToDirectory(new.CurrentDirectory .. new.SelectedFile) + end + end, 'Save', colours.black) + new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + returnFunc(new, false) + end, 'Cancel', colours.black) + new.GoUpButton = Button:Initialise(2, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle) + local folderName = fs.getName(new.CurrentDirectory) + local parentDirectory = new.CurrentDirectory:sub(1, #new.CurrentDirectory-#folderName-1) + new:GoToDirectory(parentDirectory) + end, 'Go Up', colours.black) + new.PathTextBox = TextBox:Initialise(2, new.Height - 3, new.Width - 2, 1, new, '', colours.white, colours.black, function(key) + if key == keys.enter then + new.SaveButton:Click() + end + end) + new.PathTextBox.Placeholder = 'Document Name' + Current.TextInput = new.PathTextBox.TextInput + new:GoToDirectory(new.CurrentDirectory) + return new + end, + + Show = function(self) + Current.Window = self + return self + end, + + Close = function(self) + Current.Input = nil + Current.Window = nil + self = nil + end, + + GoToDirectory = function(self, path) + path = TidyPath(path) + self.CurrentDirectory = path + self.Scroll = 0 + self.Typed = false + local fs = fs + if OneOS then + fs = OneOS.FS + end + self.Files = fs.list(self.CurrentDirectory) + Draw() + end, + + Flash = function(self) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + sleep(0.15) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + end, + + Click = function(self, side, x, y) + local items = {self.SaveButton, self.CancelButton, self.PathTextBox, self.GoUpButton} + local found = false + for i, v in ipairs(items) do + if CheckClick(v, x, y) then + v:Click(side, x, y) + found = true + end + end + + if not found then + if y <= 11 then + local files = fs.list(self.CurrentDirectory) + if files[y-1] then + self:GoToDirectory(self.CurrentDirectory..files[y-1]) + Draw() + end + end + end + return true + end +} + +local WrapText = function(text, maxWidth) + local lines = {''} + for word, space in text:gmatch('(%S+)(%s*)') do + local temp = lines[#lines] .. word .. space:gsub('\n','') + if #temp > maxWidth then + table.insert(lines, '') + end + if space:find('\n') then + lines[#lines] = lines[#lines] .. word + + space = space:gsub('\n', function() + table.insert(lines, '') + return '' + end) + else + lines[#lines] = lines[#lines] .. word .. space + end + end + return lines +end + +ButtonDialougeWindow = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + CursorPos = 1, + Visible = true, + CancelButton = nil, + OkButton = nil, + Lines = {}, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + if not self.Visible then + return + end + Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey) + Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white) + Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey) + + for i, text in ipairs(self.Lines) do + Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white) + end + + self.OkButton:Draw() + if self.CancelButton then + self.CancelButton:Draw() + end + end, + + Initialise = function(self, title, message, okText, cancelText, returnFunc) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 28 + new.Lines = WrapText(message, new.Width - 2) + new.Height = 5 + #new.Lines + new.Return = returnFunc + new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2) + new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2) + new.Title = title + new.Visible = true + new.Visible = true + new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function() + returnFunc(new, true) + end, okText) + if cancelText then + new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function() + returnFunc(new, false) + end, cancelText) + end + + return new + end, + + Show = function(self) + Current.Window = self + return self + end, + + Close = function(self) + Current.Window = nil + self = nil + end, + + Flash = function(self) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + sleep(0.15) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + end, + + Click = function(self, side, x, y) + local items = {self.OkButton, self.CancelButton} + local found = false + for i, v in ipairs(items) do + if CheckClick(v, x, y) then + v:Click(side, x, y) + found = true + end + end + return true + end +} + +TextDialougeWindow = { + X = 1, + Y = 1, + Width = 0, + Height = 0, + CursorPos = 1, + Visible = true, + CancelButton = nil, + OkButton = nil, + Lines = {}, + TextInput = nil, + + AbsolutePosition = function(self) + return {X = self.X, Y = self.Y} + end, + + Draw = function(self) + if not self.Visible then + return + end + Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey) + Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey) + Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white) + Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey) + + for i, text in ipairs(self.Lines) do + Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white) + end + + + Drawing.DrawBlankArea(self.X + 1, self.Y + self.Height - 4, self.Width - 2, 1, colours.lightGrey) + Drawing.DrawCharacters(self.X + 2, self.Y + self.Height - 4, self.TextInput.Value, colours.black, colours.lightGrey) + Current.CursorPos = {self.X + 2 + self.TextInput.CursorPos, self.Y + self.Height - 4} + Current.CursorColour = colours.black + + self.OkButton:Draw() + if self.CancelButton then + self.CancelButton:Draw() + end + end, + + Initialise = function(self, title, message, okText, cancelText, returnFunc, numerical) + local new = {} -- the new instance + setmetatable( new, {__index = self} ) + new.Width = 28 + new.Lines = WrapText(message, new.Width - 2) + new.Height = 7 + #new.Lines + new.Return = returnFunc + new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2) + new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2) + new.Title = title + new.Visible = true + new.Visible = true + new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function() + if #new.TextInput.Value > 0 then + returnFunc(new, true, new.TextInput.Value) + end + end, okText) + if cancelText then + new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function() + returnFunc(new, false) + end, cancelText) + end + new.TextInput = TextInput:Initialise('', function(enter) + if enter then + new.OkButton:Click() + end + Draw() + end, numerical) + + Current.Input = new.TextInput + + return new + end, + + Show = function(self) + Current.Window = self + return self + end, + + Close = function(self) + Current.Window = nil + Current.Input = nil + self = nil + end, + + Flash = function(self) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + sleep(0.15) + self.Visible = false + Draw() + sleep(0.15) + self.Visible = true + Draw() + end, + + Click = function(self, side, x, y) + local items = {self.OkButton, self.CancelButton} + local found = false + for i, v in ipairs(items) do + if CheckClick(v, x, y) then + v:Click(side, x, y) + found = true + end + end + return true + end +} + +function PrintCentered(text, y) + local w, h = term.getSize() + x = math.ceil(math.ceil((w / 2) - (#text / 2)), 0)+1 + term.setCursorPos(x, y) + print(text) +end + +function DoVanillaClose() + term.setBackgroundColour(colours.black) + term.setTextColour(colours.white) + term.clear() + term.setCursorPos(1, 1) + PrintCentered("Thanks for using Ink!", (Drawing.Screen.Height/2)-1) + term.setTextColour(colours.lightGrey) + PrintCentered("Word Proccessor for ComputerCraft", (Drawing.Screen.Height/2)) + term.setTextColour(colours.white) + PrintCentered("(c) OutragedMetro 2019", (Drawing.Screen.Height/2)+3) + term.setCursorPos(1, Drawing.Screen.Height) + error('', 0) +end + +function Close() + if isQuitting or not Current.Document or not Current.Modified then + if not OneOS then + DoVanillaClose() + end + return true + else + local _w = ButtonDialougeWindow:Initialise('Quit Ink?', 'You have unsaved changes, do you want to quit anyway?', 'Quit', 'Cancel', function(window, success) + if success then + if OneOS then + OneOS.Close(true) + else + DoVanillaClose() + end + end + window:Close() + Draw() + end):Show() + --it's hacky but it works + os.queueEvent('mouse_click', 1, _w.X, _w.Y) + return false + end +end + +if OneOS then + OneOS.CanClose = function() + return Close() + end +end + +Initialise() diff --git a/programVersions b/programVersions index 30d9c83..a534534 100644 --- a/programVersions +++ b/programVersions @@ -1,92 +1,227 @@ { ["server"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/darksecurity/server.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darksecurity/server.lua", ["Version"]=6.37, ["Type"]="program", - ["Name"]="Dark Programs Server", - ["Description"]="Dark Programs Base Security Server", - ["Author"]="Darkrising", - ["Package"]="Dark Security", + ["Name"]="Outraged Security .INC Server", + ["Description"]="Outraged Security .INC Base Security Server", + ["Author"]="Outraged Security .INC", + ["Package"]="Outraged Security .INC", }, ["client"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/darksecurity/client.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darksecurity/client.lua", ["Version"]=4.26, ["Type"]="program", - ["Name"]="Dark Programs Client", - ["Description"]="Dark Programs Base Security Client", - ["Author"]="Darkrising", - ["Package"]="Dark Security", + ["Name"]="Outraged Security .INC Client", + ["Description"]="Outraged Security .INC Base Security Client", + ["Author"]="Outraged Security .INC", + ["Package"]="Outraged Security .INC", + }, +["Chat_Client"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darksecurity/chat_client.lua", + ["Version"]=4.26, + ["Type"]="program", + ["Name"]="Chat Client", + ["Description"]="Outraged Security .INC Emerald Wireless chat", + ["Author"]="Outraged Security .INC", + ["Package"]="Chat", }, +["chat_server"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darksecurity/chat_server.lua", + ["Version"]=4.26, + ["Type"]="program", + ["Name"]="Chat Server", + ["Description"]="Outraged Security .INC Emerald Wireless Server", + ["Author"]="Outraged Security .INC", + ["Package"]="Chat", + }, + ["Axiom"]={ + ["GitURL"]="https://raw.githubusercontent.com/nothjarnan/axiom/master/install.lua", + ["Version"]=2.95, + ["Type"]="program", + ["Name"]="Axiom Secure OS Downloader", + ["Description"]="Downloads A Secure OS Program from Outraged Security .INC Software Centre", + ["Author"]="Nothjarnan", + ["Package"]="Standalone", + }, +["Axiom"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/chatgpt", + ["Version"]=1.0, + ["Type"]="program", + ["Name"]="Chat GPT In computercraft", + ["Description"]="Installs chatgpt and runs code", + ["Author"]="Outraged Security .INC", + ["Package"]="Standalone", + }, + ["MetroOS"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/MetroOS/MetroOS", + ["Version"]=2.94, + ["Type"]="program", + ["Name"]="Metro Secure OS Downloader", + ["Description"]="Downloads A Secure OS Program from Outraged Security .INC Software Centre", + ["Author"]="Outraged Security .INC", + ["Package"]="Outraged Security .INC", + }, + ["SecureDoor"]={ + ["GitURL"]="https://raw.githubusercontent.com/OutragedMetro/darkprograms/darkprograms/SecurePdaDoor/SecureDoor", + ["Version"]=2.95, + ["Type"]="program", + ["Name"]="Ultimate Door Lock", + ["Description"]="Downloads A Secure Door Lock Program from Outraged Security .INC Software Centre", + ["Author"]="Outraged Security .INC", + ["Package"]="Standalone", + }, ["dark"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/dark.lua", ["Version"]=3.25, ["Type"]="api", - ["Name"]="Dark API", - ["Description"]="API that is used in most Dark Programs", - ["Author"]="Darkrising", + ["Name"]="Outraged Security .INC API", + ["Description"]="API that is used in most Outraged Security .INC Software", + ["Author"]="Outraged Security .INC", ["Package"]="API", }, ["darkfile"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/api/darkfile.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/darkfile.lua", ["Version"]=1.101, ["Type"]="api", - ["Name"]="Dark File API", + ["Name"]="Outraged Security .INC FILE API", ["Description"]="File API used for compression and other things", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="API", }, ["screen"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/screen.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/screen.lua", ["Version"]=3.361, ["Type"]="program", - ["Name"]="Dark Screen", + ["Name"]="Outraged Security .INC Screen", ["Description"]="Used to display information on monitors", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="Standalone", }, ["chat"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/chat.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/chat.lua", ["Version"]=1.51, ["Type"]="program", - ["Name"]="Dark Chat", + ["Name"]="Outraged Security .INC Secure Chat", ["Description"]="A standalone rednet chat program", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="Standalone", }, ["darkbuttons"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/darkbuttons.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darkbuttons.lua", ["Version"]=1.231, ["Type"]="program", - ["Name"]="Dark Buttons", + ["Name"]="Outraged Security Buttons", ["Description"]="Used to control coloured wires with buttons on a monitor", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="Standalone", }, ["turt"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/turt.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/turt.lua", ["Version"]=1.121, ["Type"]="program", - ["Name"]="Inturtlpler", + ["Name"]="Outraged Security .INC Inturtlpler", ["Description"]="Short hand turtle command interpreter", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="Standalone", }, ["stargatetouch"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/stargate/stargatetouch.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/stargatetouch.lua", ["Version"]=1.204, ["Type"]="program", - ["Name"]="Stargate Touch Program", + ["Name"]="Outraged Security .INC Stargate Touch Program", ["Description"]="A program that allows you to dial gates using a touch screen, stargate and terminal.", - ["Author"]="Darkrising", + ["Author"]="Outraged Security .INC", ["Package"]="Stargate", }, ["darkretriever"]={ - ["GitURL"]="https://raw.github.com/darkrising/darkprograms/darkprograms/darkretriever.lua", + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/darkretriever.lua", ["Version"]=2.12, ["Type"]="program", - ["Name"]="Dark Retriever", - ["Description"]="Downloads programs from github", - ["Author"]="Darkrising", + ["Name"]="Outraged Security .INC Retriever", + ["Description"]="Downloads programs from from Outraged Security .INC", + ["Author"]="Outraged Security .INC", ["Package"]="Standalone", }, + ["sign"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/signs/sign", + ["Version"]=2.12, + ["Type"]="program", + ["Name"]="Outraged Security .INC Signs", + ["Description"]="Downloads Sign Program from Outraged Security .INC", + ["Author"]="Outraged Security .INC", + ["Package"]="Standalone", + }, + ["setup"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/SecurePdaDoor/SecureDoor", + ["Version"]=2.12, + ["Type"]="program", + ["Name"]="Outraged Security .INC PDA Secure Door", + ["Description"]="Downloads A PDA Secure Door Program from Outraged Security .INC", + ["Author"]="Outraged Security .INC", + ["Package"]="Standalone", + }, + ["ink"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/notepad/ink", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="Outraged Security .INC Office Word Software", + ["Description"]="Downloads A Word writing office Program from Outraged Security .INC Software Centre", + ["Author"]="Outraged Security .INC", + ["Package"]="Standalone", + }, + ["Autorun"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/Autorun/Autorun", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="Autorun 2020 the game", + ["Description"]="Downloads the latest Autorun game from the Autorun series", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, + ["BrickBreaker"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/BrickBreaker/BrickBreaker", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="BrickBreaker the game", + ["Description"]="Downloads the latest BrickBreaker", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, + ["CookieClicker"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/CookieClicker/CookieClicker", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="CookieClicker the game", + ["Description"]="Downloads the latest Coockie Clicker", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, + ["LoadingSimulator"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/LoadingSimulator/LoadingSimulator", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="Loading Simulator the game", + ["Description"]="Downloads the latest Loading Simulator", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, + ["MinePowered10"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/MinePowered10/Minepowered", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="Mine Powered 10 the only game launcher 2020", + ["Description"]="Downloads the latest Mine Powered 10", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, + ["Pong"]={ + ["GitURL"]="https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/games/Pong/pong", + ["Version"]=2.16, + ["Type"]="program", + ["Name"]="Pong the game", + ["Description"]="Downloads the latest Pong", + ["Author"]="Outraged Security .INC", + ["Package"]="Games", + }, } diff --git a/screen.lua b/screen.lua index ca98dd8..91df55a 100644 --- a/screen.lua +++ b/screen.lua @@ -5,13 +5,13 @@ Version = 3.361 --Platform: ComputerCraft Lua Virtual Machine AutoUpdate = true if not fs.exists("dark") then -- load darkAPI - print("Missing DarkAPI") + print("Missing OSI API") if not http then - error("Enable the HTTP API to download DarkAPI") + error("Enable the HTTP API to download OSI API") end sleep(2) print("Attempting to download...") - getGit = http.get("https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua") + getGit = http.get("https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/api/dark.lua") getGit = getGit.readAll() file = fs.open("dark", "w") file.write(getGit) @@ -301,4 +301,4 @@ if arg[1] == "-mc" then Cou = 1 end end -end \ No newline at end of file +end diff --git a/securesigns b/securesigns new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/securesigns @@ -0,0 +1 @@ + diff --git a/signs/securitysigns b/signs/securitysigns new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/signs/securitysigns @@ -0,0 +1 @@ + diff --git a/signs/sign b/signs/sign new file mode 100644 index 0000000..f4f24e8 --- /dev/null +++ b/signs/sign @@ -0,0 +1,19 @@ +local pos = 18 +mon = peripheral.wrap("top") +mon.clear() +mon.setBackgroundColor(32768) +mon.setTextColor(32) +mon.setTextScale(5) + +while true do + if pos==-26 then + pos = 18 + end + + mon.clear() + mon.setCursorPos(pos,1) + mon.write("Insert Security Text Here") + pos = pos-1 + + os.sleep(0.15) +end diff --git a/turt.lua b/turt.lua index dde1a94..b2ac6e0 100644 --- a/turt.lua +++ b/turt.lua @@ -9,7 +9,7 @@ if #arg == 0 then end local function gitUpdate(ProgramName, Filename, ProgramVersion) if http then - local getGit = http.get("https://raw.github.com/darkrising/darkprograms/darkprograms/programVersions") + local getGit = http.get("https://raw.githubusercontent.com/rservices/darkprograms/darkprograms/programVersions") local getGit = getGit.readAll() NVersion = textutils.unserialize(getGit) if NVersion[ProgramName].Version > ProgramVersion then @@ -185,4 +185,4 @@ end file = fs.open(arg[1], "r") wFile = file.readAll() file.close() -inTur(wFile) \ No newline at end of file +inTur(wFile)