Advertisement
PaymentOption

CannonOS

May 28th, 2012
7,234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 52.94 KB | None | 0 0
  1. oldpullEvent = os.pullEvent
  2. os.pullEvent = os.pullEventRaw
  3.  
  4. -- Cannon OS by PaymentOption --
  5. VERSION = 2.01
  6. --------------------------------
  7.  
  8. rednet.open("top")
  9. rednet.open("bottom")
  10. rednet.open("back")
  11. rednet.open("front")
  12. rednet.open("right")
  13. rednet.open("left")
  14.  
  15. --[[ Notes:
  16.         User information like passwords are located in the User/<computerID>/.info.
  17.         E-Mails are stored in the /Mail Directory.
  18.         E-Mail preferences are stored in /Mail/.prefs.
  19.        
  20.         All printing functions like PrintMenu and PrintMainScreen do not clear the screen first; you must clear it before using them.
  21. --]]
  22.  
  23.  
  24. -- VARIABLES --
  25.  
  26. -- Update and Service Variables --
  27. nServerID = 1292 -- Update and key check server ID
  28. ----------------------------------
  29.  
  30. -- Screen Variables --
  31. screenWidth, screenHeight = term.getSize()
  32. selection = 1
  33.  
  34. sMenuState = "main"
  35. ----------------------
  36.  
  37. -- Account Variables --
  38. sUserName = ""
  39. sPassword = ""
  40.  
  41. bNewUser = true
  42. bLogin = true
  43.  
  44. bAdmin = true -- Switch to false to disable the following features: CraftOS, Computer, Email, Account Manipulation
  45. -----------------------
  46.  
  47. -- Authenticity Variables --
  48. sLocalKey = ""
  49. bIsAuthentic = true -- If the key entered by the user upon installation is correct, then this should be true
  50. ----------------------------
  51.  
  52. -- Mail --
  53. if(fs.isDir("Mail")) then nMail = #(fs.list("Mail"))-1
  54. else nMailCount = 0 end
  55. ----------
  56. ---------------
  57.  
  58. -- Security --
  59. sSecurityShell = [[
  60.  
  61. local parentShell = shell
  62.  
  63. local bExit = false
  64. local sDir = (parentShell and parentShell.dir()) or ""
  65. local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
  66. local tAliases = (parentShell and parentShell.aliases()) or {}
  67. local tProgramStack = {}
  68.  
  69. local shell = {}
  70. local tEnv = {
  71.     ["shell"] = shell,
  72. }
  73.  
  74. -- Install shell API
  75. function shell.run( _sCommand, ... )
  76.     local sPath = shell.resolveProgram( _sCommand )
  77.     if sPath ~= nil then
  78.         tProgramStack[#tProgramStack + 1] = sPath
  79.         local result = os.run( tEnv, sPath, ... )
  80.         tProgramStack[#tProgramStack] = nil
  81.         return result
  82.     else
  83.         print( "No such program" )
  84.         return false
  85.     end
  86. end
  87.  
  88. function shell.exit()
  89.     bExit = true
  90. end
  91.  
  92. function shell.dir()
  93.     return sDir
  94. end
  95.  
  96. function shell.setDir( _sDir )
  97.     sDir = _sDir
  98. end
  99.  
  100. function shell.path()
  101.     return sPath
  102. end
  103.  
  104. function shell.setPath( _sPath )
  105.     sPath = _sPath
  106. end
  107.  
  108. function shell.resolve( _sPath )
  109.     local sStartChar = string.sub( _sPath, 1, 1 )
  110.     if sStartChar == "/" or sStartChar == "\\" then
  111.         return fs.combine( "", _sPath )
  112.     else
  113.         return fs.combine( sDir, _sPath )
  114.     end
  115. end
  116.  
  117. function shell.resolveProgram( _sCommand )
  118.     -- Substitute aliases firsts
  119.     if tAliases[ _sCommand ] ~= nil then
  120.         _sCommand = tAliases[ _sCommand ]
  121.     end
  122.  
  123.     -- If the path is a global path, use it directly
  124.     local sStartChar = string.sub( _sCommand, 1, 1 )
  125.     if sStartChar == "/" or sStartChar == "\\" then
  126.         local sPath = fs.combine( "", _sCommand )
  127.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  128.             return sPath
  129.         end
  130.         return nil
  131.     end
  132.    
  133.     -- Otherwise, look on the path variable
  134.     for sPath in string.gmatch(sPath, "[^:]+") do
  135.         sPath = fs.combine( shell.resolve( sPath ), _sCommand )
  136.         if fs.exists( sPath ) and not fs.isDir( sPath ) then
  137.             return sPath
  138.         end
  139.     end
  140.    
  141.     -- Not found
  142.     return nil
  143. end
  144.  
  145. function shell.programs( _bIncludeHidden )
  146.     local tItems = {}
  147.    
  148.     -- Add programs from the path
  149.     for sPath in string.gmatch(sPath, "[^:]+") do
  150.         sPath = shell.resolve( sPath )
  151.         if fs.isDir( sPath ) then
  152.             local tList = fs.list( sPath )
  153.             for n,sFile in pairs( tList ) do
  154.                 if not fs.isDir( fs.combine( sPath, sFile ) ) and
  155.                    (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
  156.                     tItems[ sFile ] = true
  157.                 end
  158.             end
  159.         end
  160.     end
  161.  
  162.     -- Sort and return
  163.     local tItemList = {}
  164.     for sItem, b in pairs( tItems ) do
  165.         table.insert( tItemList, sItem )
  166.     end
  167.     table.sort( tItemList )
  168.     return tItemList
  169. end
  170.  
  171. function shell.getRunningProgram()
  172.     if #tProgramStack > 0 then
  173.         return tProgramStack[#tProgramStack]
  174.     end
  175.     return nil
  176. end
  177.  
  178. function shell.setAlias( _sCommand, _sProgram )
  179.     tAliases[ _sCommand ] = _sProgram
  180. end
  181.  
  182. function shell.clearAlias( _sCommand )
  183.     tAliases[ _sCommand ] = nil
  184. end
  185.  
  186. function shell.aliases()
  187.     -- Add aliases
  188.     local tCopy = {}
  189.     for sAlias, sCommand in pairs( tAliases ) do
  190.         tCopy[sAlias] = sCommand
  191.     end
  192.     return tCopy
  193. end
  194.    
  195. print( os.version() )
  196.  
  197. -- If this is the toplevel shell, run the startup programs
  198. if parentShell == nil then
  199.     -- Run the startup from the ROM first
  200.     local sRomStartup = shell.resolveProgram( "/rom/startup" )
  201.     if sRomStartup then
  202.         shell.run( sRomStartup )
  203.     end
  204.    
  205.     -- Then run the user created startup, from the disks or the root
  206.     local sUserStartup = shell.resolveProgram( "/startup" )
  207.     for n,sSide in pairs( redstone.getSides() ) do
  208.         if disk.isPresent( sSide ) and disk.hasData( sSide ) then
  209.             local sDiskStartup = shell.resolveProgram( fs.combine(disk.getMountPath( sSide ), "startup") )
  210.             if sDiskStartup then
  211.                 sUserStartup = sDiskStartup
  212.                 break
  213.             end
  214.         end
  215.     end
  216.    
  217.     if sUserStartup then
  218.         shell.run( sUserStartup )
  219.     end
  220. end
  221.  
  222. -- Run any programs passed in as arguments
  223. local tArgs = { ... }
  224. if #tArgs > 0 then
  225.     shell.run( ... )
  226. end
  227.  
  228. -- Read commands and execute them
  229. local tCommandHistory = {}
  230. while not bExit do
  231.     write( shell.dir() .. "> " )
  232.  
  233.     local sLine = read( nil, tCommandHistory )
  234.     table.insert( tCommandHistory, sLine )
  235.    
  236.     local tWords = {}
  237.     for match in string.gmatch(sLine, "[^ \t]+") do
  238.         table.insert( tWords, match )
  239.     end
  240.  
  241.     local sCommand = tWords[1]
  242.     if sCommand then
  243.         if sCommand == "edit" and tWords[2] == "startup" or string.find( tWords[2], ".info" ) then print( "I can't let you do that." )
  244.         else shell.run( sCommand, unpack( tWords, 2 ) ) end
  245.     end
  246. end
  247.  
  248. -- If this is the toplevel shell, run the shutdown program
  249. if parentShell == nil then
  250.     if shell.resolveProgram( "shutdown" ) then
  251.         shell.run( "shutdown" )
  252.     end
  253.     os.shutdown() -- just in case
  254. end
  255.  
  256. ]]
  257. --------------
  258.  
  259. -- Software Validation --
  260. function checkKey(sKey)
  261.     rednet.send(nServerID, "CHECKMYKEY")
  262.     rednet.send(nServerID, tostring(sKey))
  263.    
  264.     sender, message = rednet.receive(1)
  265.    
  266.     if sender == nServerID then
  267.         if message ~= "authentic" then bAuthentic = false; return false
  268.         else bAuthentic = true; return true end
  269.     end
  270. end
  271.  
  272. function getKey()
  273.     if fs.exists(".key") then return end
  274.     if bIsAuthentic == true then return end -- To avoid embarassing double authentication!
  275.    
  276.     clear()
  277.     printMainScreen()
  278.     sleep(2)
  279.    
  280.     clear()
  281.     printBorder()
  282.    
  283.     cPrint(3, "Welcome!")
  284.     cPrint(5, "You're about to install:")
  285.     cPrint(6, "Cannon OS V:"..VERSION.."!")
  286.     cPrint(7, " The installation wizard will walk you")
  287.     cPrint(8, " through product validation to installation.")
  288.     cPrint(10, "Before you continue, make sure that you have")
  289.     cPrint(11, " the product key given by your distributor.")
  290.    
  291.     cPrint(15, "[ Continue ]")
  292.     while true do
  293.         event, key = os.pullEvent("key")
  294.        
  295.         if key == 28 then break end
  296.     end
  297.    
  298.     clear()
  299.     printBorder()
  300.    
  301.     rPrint(17, "Cannon OS Version: "..VERSION.."*")
  302.     rPrint(16, "Software: LOCKED*")
  303.    
  304.     cPrint(8, "Please enter your product key here:")
  305.     term.setCursorPos(15, 9); write("Key: ")
  306.     local sProductKey = newRead()
  307.    
  308.     if checkKey(sProductKey) then
  309.         clear()
  310.         printBorder()
  311.        
  312.         cPrint(9, "Congradulations,")
  313.         cPrint(10, "Your software has successfully been")
  314.         cPrint(11, "VALIDATED!")
  315.         sleep(3)
  316.        
  317.         local file = fs.open(".key", "w")
  318.         file.writeLine(sProductKey)
  319.         file.close()
  320.         bIsAuthentic = true
  321.     else
  322.         clear()
  323.         printBorder()
  324.        
  325.         cPrint(8, "I'm sorry, but the key")
  326.         cPrint(9, "entered doesn't seem to be valid.")
  327.         sleep(3)
  328.         os.shutdown()
  329.     end
  330. end
  331. -------------------------
  332.  
  333.  
  334. -- Helper Functions --
  335. function cPrint(height, string)
  336.     local xPos = screenWidth/2 - string.len(string)/2
  337.     term.setCursorPos(xPos, height); term.write(string)
  338. end
  339.  
  340. function rPrint(height, string)
  341.     local xPos = screenWidth - string.len(string)
  342.     term.setCursorPos(xPos, height); term.write(string)
  343. end
  344.  
  345. function clear() term.clear(); term.setCursorPos(1,1) end
  346.  
  347. function printBorder()
  348.     write(" "..string.rep("*", screenWidth-2).."\n")
  349.     for i=1, screenHeight-2 do
  350.         write(" *"..string.rep(" ", screenWidth-4).."*\n")
  351.     end
  352.     write(" "..string.rep("*", screenWidth-2))
  353. end
  354.  
  355. function customWrite(height, string)
  356.     term.setCursorPos(3, height)
  357.     term.write(string)
  358. end
  359.  
  360. function clearCenter()
  361.     cPrint(2, "* "..sUserName.." *")
  362.     cPrint(3, "*"..string.rep("*", string.len(sUserName)+2).."*")
  363.     rPrint(17, "Cannon OS Version: "..VERSION.. "*")
  364.    
  365.     local line = 4
  366.     term.setCursorPos(34, 3); term.write("  ") -- Remove the very top part of the cannon logo
  367.     repeat
  368.         term.setCursorPos(1, line); term.clearLine()
  369.         line = line+1
  370.     until line == 12
  371.    
  372.     line = 4
  373.     term.setCursorPos(1, 4)
  374.    
  375.     repeat
  376.         write(" *"..string.rep(" ", screenWidth-4).."*\n")
  377.         line = line+1
  378.     until line == 12
  379. end
  380.  
  381. function printContainer()
  382.     term.setCursorPos(4, 5); term.write(string.rep("*", screenWidth-6))
  383.     local y = 6
  384.     for i=1, screenHeight - 13 do
  385.         term.setCursorPos(4, y); term.write("*"..string.rep(" ", screenWidth-8).."*")
  386.         y = y+1
  387.     end
  388.     term.setCursorPos(4, 11); term.write(string.rep("*", screenWidth-6))
  389. end
  390.  
  391. -- Perfecting the pullEvent backspace attempt 1! --
  392.  
  393. function newRead( _charLimit, _ReplaceChar) -- The filter can either be a 1, 0, or nil. 1 is Numbers only, 0 is letters only, and nil is both
  394.     local sMessage = ""
  395.     term.setCursorBlink(true)
  396.     local originalCursorX, originalCursorY = term.getCursorPos()
  397.  
  398.     while true do
  399.         local cursorX, cursorY = term.getCursorPos()
  400.         local event, p1 = os.pullEvent()
  401.        
  402.         if _charLimit ~= nil then
  403.             if string.len(sMessage) == _charLimit then term.setCursorBlink(false); return sMessage end
  404.         end
  405.        
  406.         if event == "char" then sMessage = sMessage..p1
  407.         --[[elseif event == "key" then -- The escape key has keyID 1 so: 0 = keyID: 11, 1 = keyID: 2, 2 = keyID : 3 etc etc....
  408.             if p1 == 11 or p1 == 2 or p1 == 3 or p1 == 4 or p1 == 5 or p1 == 6 or p1 == 7 or p1 == 8 or p1 == 9 or p1 == 10 then
  409.             --        0       1          2          3          4          5          6          7          8           9
  410.                 sMessage = sMessage..(p1-1)
  411.             end--]]
  412.         end
  413.        
  414.         if event == "key" and p1 == 28 then term.setCursorBlink(false); return sMessage end-- Enter key; end the loop and let's see the string
  415.        
  416.         if event == "key" and p1 == 14 then -- Backspace...
  417.             sMessage = string.sub(sMessage, 1, string.len(sMessage)-1)
  418.             -- Set our message to the substring of the first charcter      
  419.             -- To the length of the message minus 1 to achieve one less letter.
  420.            
  421.             term.setCursorPos(originalCursorX, cursorY)
  422.             term.write(sMessage.." ") -- Adding this empty space clears the removed character from the line, but may pose future issues
  423.         end
  424.        
  425.         term.setCursorPos(originalCursorX, cursorY); term.write(string.rep(" ", string.len(sMessage)))
  426.         -- Clear the previous line just in case we get a new line
  427.         -- Now write the message on the new line
  428.         if _ReplaceChar ~= nil then
  429.             term.setCursorPos(originalCursorX, cursorY)
  430.             term.write(string.rep( _ReplaceChar, string.len(sMessage) ))
  431.         else
  432.             term.setCursorPos(originalCursorX, cursorY)
  433.             term.write(sMessage)
  434.         end
  435.     end
  436. end
  437. ----------------------
  438.  
  439.  
  440. -- System Functions --
  441. function checkInstalltion()
  442.     if fs.exists("SYSTEM/.installed") then return true
  443.     else return false end
  444. end
  445.  
  446. function runShell() shell.run("/rom/programs/shell") end
  447.  
  448. function getVersion() return VERSION end
  449.  
  450. function checkVersion()
  451.     local sCommand = "get"
  452.     if sCommand == "get" then
  453.         local sCode = "c17Hgq1A"
  454.         local sPath = ".tempVersion"
  455.  
  456.         while true do
  457.             local response = http.get(
  458.                 "http://pastebin.com/raw.php?i="..textutils.urlEncode( sCode )
  459.                 )
  460.            
  461.             if response then
  462.                 local sResponse = response.readAll()
  463.                 response.close()
  464.                 if tonumber(sResponse) > VERSION then return true
  465.                 else return false end
  466.                 break
  467.             else return false end
  468.         end
  469.     end
  470. end
  471.  
  472. function updateSelf()
  473.     local sCommand = "get"
  474.     if sCommand == "get" then
  475.         local sCode = "6a92bGGZ"
  476.         local sFile = "startup"
  477.         local sPath = shell.resolve( sFile )
  478.  
  479.         while true do
  480.             local response = http.get(
  481.                 "http://pastebin.com/raw.php?i="..textutils.urlEncode( sCode )
  482.                 )
  483.                
  484.             if response then
  485.                 local sResponse = response.readAll()
  486.                 response.close()
  487.                
  488.                 local file = fs.open( sPath, "w" )
  489.                 file.write( sResponse )
  490.                 file.close()
  491.                 return true
  492.             else return false end
  493.         end
  494.     end
  495. end
  496.  
  497. function checkDirs()
  498.     if not fs.isDir("Mail") then shell.run("rom/programs/mkdir", "Mail"); nMailCount = (#(fs.list("/Mail"))) end
  499.     if not fs.isDir("User") then shell.run("rom/programs/mkdir", "User"); shell.run("rom/programs/mkdir", "User/"..tostring(os.getComputerID())) end
  500.         if not fs.isDir("User/"..tostring(os.getComputerID()).."/Projects") then shell.run("rom/programs/mkdir", "User/"..tostring(os.getComputerID()).."/Projects") end
  501.         if not fs.isDir("User/"..tostring(os.getComputerID()).."/Desktop") then shell.run("rom/programs/mkdir", "User/"..tostring(os.getComputerID()).."/Desktop") end
  502.             if not fs.isDir("User/"..tostring(os.getComputerID()).."/Desktop/Shortcuts") then shell.run("rom/programs/mkdir", "User/"..tostring(os.getComputerID()).."/Desktop/Shortcuts") end
  503.         if not fs.isDir("User/"..tostring(os.getComputerID()).."/Files") then shell.run("rom/programs/mkdir", "User/"..tostring(os.getComputerID()).."/Files") end
  504.    
  505.     if not fs.isDir("Mail/Contacts") then shell.run("rom/programs/mkdir", "Mail/Contacts") end
  506.     if not fs.isDir("SYSTEM") then shell.run("rom/programs/mkdir", "SYSTEM") end
  507.         if not fs.exists("SYSTEM/Version") then
  508.             local file = fs.open("SYSTEM/Version", "w"); file.writeLine(tostring(VERSION))
  509.             file.close()
  510.         end
  511.     if not fs.exists("SYSTEM/.shell") then file = fs.open("SYSTEM/.shell", "w"); file.write(sSecurityShell); file.close() end
  512.     file = fs.open("SYSTEM/.installed", "w")
  513.     file.writeLine("TRUE")
  514.     file.close()
  515. end
  516.  
  517.  
  518. function checkUserInformation()
  519.     if fs.exists("User/"..os.getComputerID().."/.info") then
  520.         local file = fs.open("User/"..os.getComputerID().."/.info", "r")
  521.         sUserName = file.readLine()
  522.         sPassword = file.readLine()
  523.         file.close()
  524.         bNewUser = false
  525.     else
  526.         bNewUser = true
  527.     end
  528. end
  529.  
  530. function getUserInformation()
  531.     if bNewUser == false then return nil -- This is to prevent accidental account resets
  532.     else
  533.         printNewUserScreen()
  534.     end
  535. end
  536.  
  537. function handleLogin()
  538.     if fs.exists(".login") then
  539.         file = fs.open(".login", "r")
  540.         fileContents = file.readAll()
  541.         file.close()
  542.         fs.delete(".login")
  543.         bLogin = false
  544.            
  545.         if fileContents == "false" then return end
  546.     end
  547.        
  548.     if bNewUser == false then
  549.         printMainScreen(); sleep(2)
  550.         clear()
  551.        
  552.         printBorder()
  553.         cPrint(4, "***************************")
  554.         cPrint(5, "* Identification required *")
  555.         cPrint(6, "***************************")
  556.        
  557.         cPrint(8, "Username: ")
  558.         cPrint(9, "Password: ")
  559.         rPrint(17, "Cannon OS Version: "..VERSION.."*")
  560.         rPrint(16, "LOCKED*")
  561.        
  562.         term.setCursorPos(screenWidth/2 - string.len("Username: ")/2 + string.len("Username: "), 8)
  563.         local tempUserName = newRead(14, nil)
  564.         term.setCursorPos(screenWidth/2 - string.len("Password: ")/2 + string.len("Password: "), 9)
  565.         local tempPassword = newRead(14, "*")
  566.        
  567.         if tempUserName == sUserName and tempPassword == sPassword then
  568.             rPrint(16, "UNLOCKED*")
  569.             cPrint(11, "**********************")
  570.             cPrint(12, "* Successfull login! *")
  571.             cPrint(13, "**********************")
  572.             sleep(2)
  573.             return
  574.         else
  575.             cPrint(11, "************************")
  576.             cPrint(12, "* Unsuccessfull login! *")
  577.             cPrint(13, "************************")
  578.             sleep(2)
  579.             os.shutdown()
  580.         end
  581.     end
  582. end
  583.  
  584. function printInstallation()
  585.     if checkInstalltion() then return end
  586.     printBorder()
  587.     cPrint(4, "*************************")
  588.     cPrint(5, "* Installation Progress *")
  589.     cPrint(6, "*************************")
  590.    
  591.     local progressPosition = 6; -- X position to represent where the progress bars will be drawn
  592.     local nProgressPercent = 0;
  593.    
  594.     cPrint(8, " * "..string.rep("*", screenWidth - 6))
  595.     cPrint(9, " * *"..string.rep(" ", screenWidth - 8).."*")
  596.     cPrint(10, " * "..string.rep("*", screenWidth - 6))
  597.    
  598.     cPrint(12, "********")
  599.     cPrint(13, "* "..string.rep(" ", string.len("100%")).." *")
  600.     cPrint(14, "********")
  601.    
  602.     for i=1, 80 do
  603.         if i%2 == 0 then
  604.             term.setCursorPos(progressPosition, 9); term.write("|")
  605.             progressPosition = progressPosition+1
  606.             sleep(0.2)
  607.         end
  608.         nProgressPercent = nProgressPercent+1
  609.         if nProgressPercent == 75 then nProgressPercent = 95 end
  610.         if nProgressPercent == 95 then sleep(1.1) end
  611.         term.setCursorPos(24, 13); term.write(nProgressPercent)
  612.     end
  613.     checkDirs()
  614. end
  615.  
  616. -- Background Processes --
  617. function checkMail(sender, message)
  618.     if string.find(message, "CANNONMAILMESSAGE") then
  619.         local file = fs.open("Mail/Unread"..nMailCount, "w")
  620.         message =  string.gsub(message, "CANNONMAILMESSAGE", "")
  621.         file.write(tostring(sender).."\n"..tostring(message))
  622.         file.close()
  623.        
  624.         nMailCount = nMailCount+1
  625.     end
  626. end
  627. --------------------------
  628. ----------------------
  629.  
  630.  
  631. -- Menues and other screens --
  632. function printNewUserScreen()
  633.     if bNewUser == false then return end
  634.     local bPasswordsMatch = false
  635.    
  636.     printBorder()
  637.     printWelcome()
  638.     sleep(3)
  639.     clear()
  640.    
  641.     printBorder()
  642.     cPrint(2, "* New User *")
  643.     cPrint(3, "************")
  644.    
  645.     rPrint(17, "Cannon OS Version: "..VERSION.."*")
  646.    
  647.     cPrint(6, "Username: ")
  648.     cPrint(7, "Password: ")
  649.     cPrint(8, " Confirm: ")
  650.         cPrint(12, "************************")
  651.         cPrint(13, "*Password not optional!*")
  652.         cPrint(14, "************************")
  653.    
  654.     term.setCursorPos(screenWidth/2-string.len("Username: ")/2+string.len("Username: "), 6)
  655.         sUserName = newRead(14, nil)
  656.         if string.len(sUserName) > 14 then
  657.             cPrint(10, "Username is too long!"); sleep(1.3)
  658.                     term.setCursorPos(1, 10); term.clearLine() -- Clear the line 10
  659.                     term.write(" *"..string.rep(" ", screenWidth-4).."*")
  660.            
  661.             term.setCursorPos(1, 6); term.clearLine() -- Clear the line
  662.             term.write(" *"..string.rep(" ", screenWidth-4).."*")
  663.             cPrint(6, "Username: ")
  664.             term.setCursorPos(screenWidth/2-string.len("Username: ")/2+string.len("Username: "), 6)
  665.             sUserName = newRead(14, nil)
  666.         end
  667.     while bPasswordsMatch == false do
  668.         term.setCursorPos(screenWidth/2-string.len("Password: ")/2+string.len("Password: "), 7)
  669.             sPassword = newRead(14, "*")
  670.         if sPassword ~= nil and sPassword ~= "" then
  671.                 term.setCursorPos(screenWidth/2-string.len(" Confirm: ")/2+string.len(" Confirm: "), 8)
  672.                 local sConfirm = newRead(14, "*")
  673.                 if sConfirm ~= sPassword then
  674.                     cPrint(10, "Passwords do not match!"); sleep(1.3)
  675.                     term.setCursorPos(1, 10); term.clearLine() -- Clear the line 10
  676.                     term.write(" *"..string.rep(" ", screenWidth-4).."*")
  677.                    
  678.                     term.setCursorPos(1, 7); term.clearLine() -- Clear the line 7
  679.                     term.write(" *"..string.rep(" ", screenWidth-4).."*")
  680.                     cPrint(7, "Password: ")
  681.                    
  682.                     term.setCursorPos(1, 8); term.clearLine() -- Clear the line 8
  683.                     term.write(" *"..string.rep(" ", screenWidth-4).."*")
  684.                     cPrint(8, " Confirm: ")
  685.                 else sPassword = sConfirm; bPasswordsMatch = true end
  686.         else sPassword = ""
  687.         end
  688.     end
  689.    
  690.     local file = fs.open("User/"..os.getComputerID().."/.info", "w")
  691.     file.writeLine(tostring(sUserName))
  692.     if sPassword == "" then file.writeLine("N/A")
  693.     else                    file.writeLine(tostring(sPassword))
  694.     end
  695.     file.close()
  696.    
  697.     cPrint(10, "Account '"..sUserName.. "' succesfully created!"); sleep(1.3)
  698. end
  699.  
  700. function printWelcome()
  701.     customWrite(3, "__          __   _                           ")
  702.     customWrite(4, "\\ \\        / /  | |                          ")
  703.     customWrite(5, " \\ \\  /\\  / /___| | ___  ___  _ __ ___   ___ ")
  704.     customWrite(6, "  \\ \\/  \\/ // _ \\ |/ __|/ _ \\| '_ ' _ \\ / _ \\")
  705.     customWrite(7, "   \\  /\\  /|  __/ | (__| (_) | | | | | |  __/")
  706.     customWrite(8, "    \\/  \\/  \\___|_|\\___|\\___/|_| |_| |_|\\___|")
  707.     customWrite(9, "          _    _               ")
  708.     customWrite(10, "         | |  | |              ")
  709.     customWrite(11, "         | |  | |___  ___ _ __ ")
  710.     customWrite(12, "         | |  | / __|/ _ \\ '__|")
  711.     customWrite(13, "         | |__| \\__ \\  __/ |   ")
  712.     customWrite(14, "          \\____/|___/\\___|_|   ")
  713.  
  714.     rPrint(17, "Cannon OS Version: "..VERSION.."*")
  715. end
  716.  
  717. function printMainScreen()
  718.     printBorder()
  719.     customWrite(2, "                          ________")
  720.     customWrite(3, "                         | ______o|")
  721.     customWrite(4, "         _______________ ||__---_||")
  722.     customWrite(5, "        |  ___________  || ______ |")
  723.     customWrite(6, "        | |           | |||______||")
  724.     customWrite(7, "        | | Cannon OS | ||--------|")
  725.     customWrite(8, "        | |    By     | ||      O |")
  726.     customWrite(9, "        | |  Payment  | ||      | |")
  727.     customWrite(10, "        | '-----------' ||      | |")
  728.     customWrite(11, "        |_____________-_||      | |")
  729.     customWrite(12, "          __/_______\\__  |::::::::|")
  730.     customWrite(13, "         ________________'-.__")
  731.     customWrite(14, "        /:::::::::':::'::\\ .\\\\\\---.")
  732.     customWrite(15, "       /::======::: .:.:::\\ \\\\_)   \\")
  733.     customWrite(16, '       """"""""""""""""""""  -----')
  734.  
  735.     term.setCursorPos(3, 17); term.write("By PaymentOption")
  736.     rPrint(17, "Version: "..VERSION.. "*")
  737. end
  738.  
  739. function printLogo()
  740.     term.setCursorPos(34, 3); term.write("__")
  741.     customWrite(4, "                              /  \\")
  742.     customWrite(5, "                        .-.  |    |")
  743.     customWrite(6, "                *    _.-'  \\  \\__/")
  744.     customWrite(7, "                 \\.-'       \\")
  745.     customWrite(8, "                /          _/")
  746.     customWrite(9, "               |      _  /")
  747.     customWrite(10, "               |     /_\\'")
  748.     customWrite(11, "                \\____\\_/")
  749. end
  750.  
  751. function printLogout()
  752.     term.setCursorPos(34, 3); term.write("  ")
  753.    
  754.     clearCenter()
  755.    
  756.     cPrint(5, "********")
  757.     cPrint(6, "*Logout*")
  758.     cPrint(7, "********")
  759.     cPrint(8, "/   \\")
  760.     cPrint(9, "***************")
  761.     cPrint(10, "*[ Yes ]  No  *")
  762.     cPrint(11, "***************")
  763.    
  764.     while true do
  765.         event, key = os.pullEvent("key")
  766.        
  767.         if key == 205 and selection < 2 then selection = 2
  768.         elseif key == 203 and selection > 1 then selection = 1
  769.        
  770.         elseif key == 28 and selection == 1 then os.reboot()
  771.         elseif key == 28 and selection == 2 then sMenuState = "main"; selection = 6; break
  772.         end
  773.        
  774.         if selection == 1 then cPrint(10, "*[ Yes ]  No  *")
  775.         else                   cPrint(10, "*  Yes  [ No ]*") end
  776.     end
  777. end
  778.  
  779. function printMainMenu()
  780.     printBorder()
  781.     cPrint(2, "* "..sUserName.." *")
  782.     cPrint(3, "*"..string.rep("*", string.len(sUserName)+2).."*")
  783.     rPrint(17, "Cannon OS Version: "..VERSION.. "*")
  784.    
  785.     if sMenuState == "main" then printLogo(); rPrint(2, "Mail: "..nMailCount.."*") end
  786.    
  787.     if selection == 1 then cPrint(13, "[ Computer ]     Craft OS     IRC          ")
  788.                            cPrint(15, "  E-Mail         Account      Update       ")
  789.     end
  790.    
  791.     if selection == 2 then cPrint(13, "  Computer     [ Craft OS ]   IRC          ")
  792.                            cPrint(15, "  E-Mail         Account      Update       ")
  793.     end
  794.    
  795.     if selection == 3 then cPrint(13, "  Computer       Craft OS   [ IRC ]        ")
  796.                            cPrint(15, "  E-Mail         Account      Update       ")
  797.     end
  798.    
  799.     if selection == 4 then cPrint(13, "  Computer       Craft OS     IRC          ")
  800.                            cPrint(15, "[ E-Mail ]       Account      Update       ")
  801.     end
  802.    
  803.     if selection == 5 then cPrint(13, "  Computer       Craft OS     IRC          ")
  804.                            cPrint(15, "  E-Mail       [ Account ]    Update       ")
  805.     end
  806.    
  807.     if selection == 6 then cPrint(13, "  Computer       Craft OS     IRC          ")
  808.                            cPrint(15, "  E-Mail         Account    [ Update ]     ")
  809.     end
  810. end
  811. ------------------------------
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824. -- Mail related things --
  825. function loadContacts()
  826.     local tContacts = fs.list("Mail/Contacts")
  827.     for i=1, #tContacts do -- Set the correct computer adress found
  828.         local file = fs.open("Mail/Contacts/"..tContacts[i], "r")
  829.         local fileContents = file.readAll()
  830.         file.close()       
  831.         tContacts[i] = { name = tContacts[i], id = fileContents }
  832.     end
  833.    
  834.     return tContacts
  835. end
  836.  
  837. function mailMenu()
  838.     recipientID = 0
  839.     sLine1 = "" -- The message will be split into two lines due to lack of multiline functionality of newread()
  840.     sLine2 = ""
  841.     sMessage = "" -- The two lines will be combined into the whole message in this variable
  842.  
  843.     selection = 1
  844.     nMailCount = 0
  845.     screenWidth, screenHeight = term.getSize()
  846.  
  847.     function cPrint(height, string)
  848.         local xPos = screenWidth/2 - string.len(string)/2
  849.         term.setCursorPos(xPos, height)
  850.         term.write(string)
  851.     end
  852.  
  853.     function rPrint(height, string)
  854.         local xPos = screenWidth - string.len(string)
  855.         term.setCursorPos(xPos, height)
  856.         term.write(string)
  857.     end
  858.  
  859.     clearCenter() -- Remove the cannon logo
  860.  
  861.     local function sendMessage()
  862.         sMessage = ";alkdjien".."\n"..sMessage
  863.         rednet.send(tonumber(recipientID), sMessage)
  864.     end
  865.  
  866.     local function printMailMenu()
  867.         rPrint(2, "Mail: "..tostring((#(fs.list("Mail"))-1).."*"))
  868.        
  869.                                cPrint(5, "***********")
  870.         if selection == 1 then cPrint(6, "*[ Write ]*")
  871.         else                   cPrint(6, "*  Write  *") end
  872.        
  873.         if selection == 2 then cPrint(7, "*[ eMail ]*")
  874.         else                   cPrint(7, "*  eMail  *") end
  875.        
  876.         if selection == 3 then cPrint(8, "*[ Cont. ]*")
  877.         else                   cPrint(8, "*  Cont.  *") end
  878.        
  879.         if selection == 4 then cPrint(9, "*[ Leave ]*")
  880.         else                   cPrint(9, "*  Leave  *") end
  881.                                cPrint(10, "***********")
  882.         -- End these damn lines ^^
  883.     end
  884.  
  885.     local function printRevise()
  886.         local nSelect = 1 -- Too much sharing of the 'select' variable
  887.        
  888.         local function cDraw(width, height, string)
  889.             term.setCursorPos(width, height)
  890.             term.write(string)
  891.         end
  892.        
  893.         local function printRevMenu()
  894.             cDraw(29, 5, "*****************")
  895.             if nSelect == 1 then cDraw(29, 6, "*[ Send ] Exit  *")
  896.             else                    cDraw(29, 6, "*  Send [ Exit ]*") end
  897.             cDraw(29, 7, "*****************")
  898.         end
  899.        
  900.         while true do
  901.             printRevMenu()
  902.             event, key = os.pullEvent("key")
  903.             -- Freakin' lines man ^^
  904.            
  905.             if key == 205 and nSelect == 1 then nSelect = nSelect+1
  906.             elseif key == 203 and nSelect == 2 then nSelect = nSelect-1
  907.            
  908.             elseif key == 28 and nSelect == 1 then sendMessage(); clearCenter(); term.setCursorPos(4, 12); term.write(string.rep(" ", 42)); break
  909.             elseif key == 28 and nSelect == 2 then clearCenter(); break
  910.             end
  911.         end
  912.     end
  913.  
  914.     local function composeMail()
  915.         clearCenter()
  916.        
  917.         term.setCursorPos(4, 5); term.write("****************************")
  918.         term.setCursorPos(4, 6); term.write("*Recipient:                *") -- 15 is the x position for the retrieving of 'recipietID'
  919.         term.setCursorPos(4, 7); term.write("****************************")
  920.        
  921.         term.setCursorPos(4, 9); term.write(string.rep("*", 42))
  922.         term.setCursorPos(4, 10); term.write("*"..string.rep(" ", 40).."*") -- 2 lines to write the body of the message; 38 spaces per line
  923.         term.setCursorPos(4, 11); term.write("*"..string.rep(" ", 40).."*")
  924.         term.setCursorPos(4, 12); term.write(string.rep("*", 42))
  925.        
  926.         term.setCursorPos(15, 6) -- Get the recipient ID
  927.         recipientID = newRead(14) -- If they entered a contact name then find the id
  928.         local tContacts = loadContacts()
  929.        
  930.         for i=1, #tContacts do
  931.             if tostring(recipientID) == tContacts[i].name then recipientID = tContacts[i].id end
  932.         end
  933.        
  934.         term.setCursorPos(6, 10); sLine1 = newRead(38) -- Character only filter
  935.         term.setCursorPos(6, 11); sLine2 = newRead(38)
  936.        
  937.         sMessage = sLine1.." "..sLine2
  938.        
  939.         printRevise()
  940.     end
  941.    
  942.     local function contacts()
  943.         local nSelect = 1
  944.         local scroll = 0;
  945.         local tContacts = fs.list("Mail/Contacts")
  946.        
  947.         local function printContacts()
  948.             local y = 6
  949.             local tContacts = loadContacts()
  950.            
  951.             for i = 1+scroll, #tContacts do
  952.                 term.setCursorPos(5, y)
  953.                 if nSelect == i then term.write("[ "..tContacts[i].name.." ]")
  954.                 else                 term.write("  "..tContacts[i].name.."  ") end
  955.                
  956.                 term.setCursorPos(43, y); term.write(tContacts[i].id)
  957.                 y = y+1
  958.                 if y == 11 then break end
  959.             end
  960.            
  961.             term.setCursorPos(4, 3); term.write("********************")
  962.             term.setCursorPos(4, 4); term.write("* Ctrl:New Contact *")
  963.         end
  964.        
  965.         while true do
  966.             clearCenter()
  967.             printContainer()
  968.             printContacts()
  969.            
  970.             local event, key = os.pullEvent("key")
  971.             if key == 208 and nSelect < #(fs.list("Mail/Contacts")) then
  972.                 if nSelect >= 4 and scroll < #tContacts then scroll = scroll+1; nSelect = nSelect+1
  973.                 else nSelect = nSelect+1 end
  974.             elseif key == 200 and nSelect > 1 then
  975.                 if nSelect >= 4 and scroll > 0 then scroll = scroll-1; nSelect = nSelect-1
  976.                 else nSelect = nSelect-1 end
  977.             elseif key == 29 or key == 157 then
  978.                 term.setCursorPos(5, 6); term.write(string.rep(" ", screenWidth-8))
  979.                 term.setCursorPos(5, 6); term.write("Contact Name: ")
  980.                 local sContact = newRead(14)
  981.                
  982.                 term.setCursorPos(5, 6); term.write(string.rep(" ", screenWidth-8))
  983.                 term.setCursorPos(5, 6); term.write("Contact ID: ")
  984.                 local nContactID = newRead(14)
  985.                
  986.                 local file = fs.open("Mail/Contacts/"..sContact, "w")
  987.                 file.write(tostring(nContactID))
  988.                 file.close()
  989.             elseif key == 14 then break
  990.            
  991.             elseif key == 28 then
  992.                 nSelected = 1
  993.                 while true do
  994.                     if nSelected == 1 then
  995.                         term.setCursorPos(5, 6)
  996.                         term.write("Delete? [ Yes ] No  ")
  997.                     else
  998.                         term.setCursorPos(5, 6)
  999.                         term.write("Delete?   Yes [ No ]")
  1000.                     end
  1001.                    
  1002.                     local event, key = os.pullEvent("key")
  1003.                    
  1004.                     if key == 205 and nSelected == 1 then nSelected = nSelected+1
  1005.                     elseif key == 203 and nSelected == 2 then nSelected = nSelected-1
  1006.                    
  1007.                     elseif key == 28 and nSelected == 1 then
  1008.                         local tContacts = loadContacts()
  1009.                        
  1010.                         for i=1, #tContacts do
  1011.                             if nSelected == i then fs.delete("Mail/Contacts/"..tContacts[i].name) end
  1012.                         end
  1013.                         break
  1014.                     elseif key == 28 and nSelected == 2 then break
  1015.                     end
  1016.                 end
  1017.             end
  1018.         end
  1019.     end
  1020.  
  1021.     while true do
  1022.         printMailMenu()
  1023.        
  1024.         event, key = os.pullEvent("key")
  1025.        
  1026.         if key == 200 and selection > 1 then selection = selection-1
  1027.         elseif key == 208 and selection < 4 then selection = selection+1
  1028.        
  1029.         elseif key == 28 and selection == 1 then composeMail(); sMenuState = "main"; break
  1030.         elseif key == 28 and selection == 2 then readMail(); sMenuState = "main"; break
  1031.         elseif key == 28 and selection == 3 then contacts(); selection = 1; term.setCursorPos(4, 3); term.write(string.rep(" ", 17)); clearCenter();
  1032.         elseif key == 28 and selection == 4 then selection = 4; sMenuState = "main"; break
  1033.         end
  1034.     end
  1035. end
  1036.  
  1037. function newMessage(nSender, sContents)
  1038.     rPrint(2, "Mail: "..nMailCount.."*")
  1039.     sMenuState = "newMessage"
  1040.     local nSelect = 1
  1041.     local bReading = false -- This is to handle whether or not we should print the reception menu
  1042.     clearCenter()
  1043.    
  1044.     local function printMessageMenu()
  1045.                              cPrint(5, "*****************")
  1046.                              cPrint(6, "*  New Message  *")
  1047.                              cPrint(7, "*****************")
  1048.         if nSelect == 1 then cPrint(8, "*[ Read ] Exit  *")
  1049.         else                 cPrint(8, "*  Read [ Exit ]*") end
  1050.                              cPrint(9, "*****************")
  1051.     end
  1052.    
  1053.     while true do
  1054.         if not bReading then printMessageMenu() end
  1055.         local event, key = os.pullEvent("key")
  1056.        
  1057.         if key == 205 then nSelect = nSelect+1
  1058.         elseif key == 203 then nSelect = nSelect-1
  1059.        
  1060.         elseif key == 28 and nSelect == 1 then
  1061.             nMailCount = nMailCount-1
  1062.             bReading = true
  1063.             clearCenter()
  1064.             term.setCursorPos(4, 5); term.write("From: "..nSender)
  1065.             term.setCursorPos(4, 6); term.write("******"..string.rep("*", string.len(nSender)))
  1066.  
  1067.             term.setCursorPos(4, 7)
  1068.             if string.len(sContents) > 42 then
  1069.                 local sContentsLine1 = string.sub(sContents, 1, 42) -- Split the message into two lines if it is greater than 38
  1070.                 local sContentsLine2 = string.sub(sContents, 43, string.len(sContents))
  1071.            
  1072.                 term.write(sContentsLine1)
  1073.                 term.setCursorPos(4, 9)
  1074.                 term.write(sContentsLine2)
  1075.             else
  1076.                 term.write(sContents)
  1077.             end
  1078.             break -- Print the message then end
  1079.         elseif key == 28 and nSelect == 2 then
  1080.             clearCenter()
  1081.             sMenuState = "main"
  1082.             return
  1083.         end
  1084.     end
  1085.    
  1086.     while true do
  1087.         cPrint(9, "**********")
  1088.         cPrint(10, "*[ Exit ]*")
  1089.         cPrint(11, "**********")
  1090.        
  1091.         local event, key = os.pullEvent("key")
  1092.        
  1093.         if key == 28 then sMenuState = "main"; break end
  1094.     end
  1095. end
  1096.  
  1097. function readMail()
  1098.     local sFileOpen = ""
  1099.     sMenuState = "archive"
  1100.     clearCenter()
  1101.    
  1102.     if #(fs.list("Mail"))-1 == 0 then
  1103.         cPrint(6, "***************")
  1104.         cPrint(7, "* No messages *")
  1105.         cPrint(8, "***************")
  1106.         sleep(1.3)
  1107.         clearCenter()
  1108.         cPrint(12, "                     ") -- Clear line 12
  1109.         return
  1110.     end
  1111.    
  1112.     term.setCursorPos(4, 5); term.write(string.rep("*", screenWidth-6))
  1113.     local y = 6
  1114.     for i=1, screenHeight - 13 do
  1115.         term.setCursorPos(4, y); term.write("*"..string.rep(" ", screenWidth-8).."*")
  1116.         y = y+1
  1117.     end
  1118.     term.setCursorPos(4, 11); term.write(string.rep("*", screenWidth-6))
  1119.    
  1120.     local tMessages = fs.list("Mail")
  1121.     local nSelections = #tMessages -- How many selections for mail we have
  1122.     local nSelected = 1
  1123.    
  1124.     local function clearMessageRectangle()
  1125.         local y = 6
  1126.         for i=1, 5 do
  1127.             term.setCursorPos(5, y); term.write(string.rep(" ", screenWidth - 8))
  1128.             y = y+1
  1129.         end
  1130.     end
  1131.    
  1132.     local function printMessages()
  1133.         term.setCursorPos(5, 13); term.write(string.rep(" ", screenWidth - (string.len("*********************")+2)))
  1134.         term.setCursorPos(screenWidth - (string.len("*********************")+2), 13)
  1135.                                         term.write("*********************")
  1136.         term.setCursorPos(screenWidth - (string.len("* Backspace to exit *")+2), 12)
  1137.                                         term.write("* Backspace to exit *")
  1138.        
  1139.         tMessages = fs.list("Mail")
  1140.         for i=1, #tMessages do
  1141.             if tMessages[i] == "Contacts" then table.remove(tMessages, i) end
  1142.         end -- Remove the 'Contacts' directory from the list
  1143.        
  1144.         term.setCursorPos(4, 5); term.write(string.rep("*", screenWidth-6))
  1145.         local y = 6
  1146.         for i=1, screenHeight - 13 do
  1147.             term.setCursorPos(4, y); term.write("*"..string.rep(" ", screenWidth-8).."*")
  1148.             y = y+1
  1149.         end
  1150.         term.setCursorPos(4, 11); term.write(string.rep("*", screenWidth-6))
  1151.        
  1152.    
  1153.         local recX = 6
  1154.         local recY = 6 -- Positions to hold the x and y coords of where we'll draw the mail
  1155.         for i=1, #tMessages do
  1156.             if recX > 41 or recX+string.len(tMessages[i]) > 41 then
  1157.                 recY = recY+2
  1158.                 recX = 6
  1159.             end
  1160.             if recY >= 10 then break end
  1161.            
  1162.             if nSelected == i then recX = recX-1 end
  1163.             term.setCursorPos(recX, recY)
  1164.             if nSelected == i then term.write("["..tMessages[i].."]"); recX = recX+1 end
  1165.             if nSelected ~= i then term.write(tMessages[i]) end
  1166.            
  1167.             if nSelected == i then
  1168.                 recX = recX + string.len(tMessages[i]) + 2 -- The 2 is for the spaces between the options
  1169.             else recX = recX + string.len(tMessages[i]) + 2 end
  1170.         end
  1171.     end
  1172.    
  1173.     while true do
  1174.         cPrint(12, "                     ") -- Clear the last line from the 'return' or 'delete' menu from reading a message
  1175.         printMessages()
  1176.        
  1177.         local event, key = os.pullEvent("key")
  1178.        
  1179.         if key == 205 and nSelected < #tMessages then nSelected = nSelected+1
  1180.         elseif key == 203 and nSelected > 1 then nSelected = nSelected-1
  1181.        
  1182.         elseif key == 14 then clearCenter(); term.setCursorPos(5, 12); term.write(string.rep(" ", screenWidth - 7)); term.setCursorPos(5, 13); term.write(string.rep(" ", screenWidth - 7)); cPrint(13, "  Computer       Craft OS     File Browser "); return
  1183.         elseif key == 28 then
  1184.             clearCenter()
  1185.             local sFileOpen = "Mail/"..tMessages[nSelected]
  1186.             local file = fs.open("Mail/"..tMessages[nSelected], "r")
  1187.             local nSender = file.readLine()
  1188.             local sMessage = file.readAll(); -- We'll be using the File Contents as the message to read
  1189.             file.close()
  1190.            
  1191.             sMessage = string.gsub(sMessage, tostring(nSender), "") -- Get the message string without the sender
  1192.             if string.len(sMessage) > 38 then
  1193.                 local sMessageLine1 = string.sub(sMessage, 1, 19)
  1194.                 local sMessageLine2 = string.sub(sMessage, 20, 38)
  1195.             end
  1196.            
  1197.             term.setCursorPos(4, 3); term.write("From: "..nSender)
  1198.             term.setCursorPos(4, 4); term.write("******"..string.rep("*", string.len(tostring(nSender))))
  1199.             term.setCursorPos(4, 5)
  1200.             if sMessageLine1 ~= nil then
  1201.                 term.write(sMessageLine1)
  1202.                 term.setCursorPos(4, 6)
  1203.                 term.write(sMessageLine2)
  1204.             else
  1205.                 term.write(sMessage)
  1206.             end
  1207.            
  1208.             nSelected = 1 -- Reset the selection for the 'back' or 'delete' option
  1209.             term.setCursorPos(5, 12); term.write(string.rep(" ", screenWidth - 7)); term.setCursorPos(5, 13); term.write(string.rep(" ", screenWidth - 7))
  1210.             while true do
  1211.                                        cPrint(10, "*********************")
  1212.                 if nSelected == 1 then cPrint(11, "*[ Return ] Delete  *")
  1213.                 else                   cPrint(11, "*  Return [ Delete ]*") end
  1214.                                        cPrint(12, "*********************")
  1215.                 --
  1216.                
  1217.                 local event, key = os.pullEvent("key")
  1218.                
  1219.                 if key == 205 and nSelected == 1 then nSelected = 2
  1220.                 elseif key == 203 and nSelected == 2 then nSelected = 1
  1221.                
  1222.                 elseif key == 28 and nSelected == 1 then term.setCursorPos(4, 3); term.write(string.rep(" ", string.len("From: "..nSender))); term.setCursorPos(4, 4); term.write(string.rep(" ", string.len("From: "..nSender))) break
  1223.                 elseif key == 28 and nSelected == 2 then
  1224.                     fs.delete(sFileOpen)
  1225.                     sFileOpened = ""
  1226.                     nSelected = 1
  1227.                     term.setCursorPos(4, 3); term.write(string.rep(" ", string.len("From: "..nSender)))
  1228.                     term.setCursorPos(4, 4); term.write(string.rep(" ", string.len("From: "..nSender)))
  1229.                     break
  1230.                 end
  1231.             end
  1232.         end
  1233.     end
  1234. end
  1235. -------------------------
  1236.  
  1237.  
  1238. -- Filbrowser --
  1239. function fileBrowser()
  1240.     sMenuState = "browseing"
  1241.     clearCenter()
  1242.    
  1243.     local scroll = 0
  1244.     local y = 0
  1245.     local sObjectName = ""
  1246.     local sObjectType = ""
  1247.     local nObjectHeight = 0
  1248.    
  1249.     local nSelect = 1
  1250.     local tFiles = {}
  1251.    
  1252.     local function printOptionMenu()
  1253.         local previousSelection = nSelect
  1254.         nSelect = 1
  1255.        
  1256.         while true do
  1257.             term.setCursorPos(6, 8); term.write(string.rep(" ", 40))
  1258.             if nSelect == 1 and sObjectType == "File" then cPrint(8, "[Run] Edit  Delete  Exit ")
  1259.         elseif nSelect == 2 and sObjectType == "File" then cPrint(8, " Run [Edit] Delete  Exit ")
  1260.         elseif nSelect == 3 and sObjectType == "File" then cPrint(8, " Run  Edit [Delete] Exit ")
  1261.         elseif nSelect == 4 and sObjectType == "File" then cPrint(8, " Run  Edit  Delete [Exit]")
  1262.         end
  1263.        
  1264.             local event, key = os.pullEvent("key")
  1265.            
  1266.             if key == 205 and nSelect < 4 then nSelect = nSelect+1
  1267.             elseif key == 203 and nSelect > 1 then nSelect = nSelect-1
  1268.             elseif key == 14 or key == 28 and nSelect == 4 then nSelect = previousSelection; return false
  1269.             elseif nSelect == 1 and key == 28 then clear(); shell.run(sObjectName); sMenuState = "main"; return true
  1270.             elseif nSelect == 2 and key == 28 then clear(); shell.run("edit", sObjectName); sMenuState = "main"; return true
  1271.             elseif nSelect == 3 and key == 28 then fs.delete(shell.dir().."/"..sObjectName); sMenuState = "main"; return true
  1272.             end
  1273.         end
  1274.     end
  1275.    
  1276.     local function printFileContainer()
  1277.         term.setCursorPos(4, 5); term.write(string.rep("*", screenWidth-6))
  1278.         local y = 6
  1279.         for i=1, screenHeight - 13 do
  1280.             term.setCursorPos(4, y); term.write("*"..string.rep(" ", screenWidth-8).."*")
  1281.             y = y+1
  1282.         end
  1283.         term.setCursorPos(4, 11); term.write(string.rep("*", screenWidth-6))
  1284.     end
  1285.    
  1286.     local function printFiles()
  1287.         local sDir = shell.dir()
  1288.         clearCenter()
  1289.         printFileContainer() -- This is the rectangle we'll be displaying the options in
  1290.         y = 6
  1291.         tFiles = fs.list( sDir )
  1292.        
  1293.         for i=1, #tFiles do
  1294.             if tFiles[i] == "startup" then table.remove(tFiles, i) end
  1295.         end
  1296.        
  1297.         for i=1+scroll, #tFiles do
  1298.             if i == nSelect then nObjectHeight = y end
  1299.             sObjectName = tostring(shell.dir()).."/"..tFiles[nSelect]
  1300.             if fs.isDir(tostring(shell.dir()).."/"..tFiles[nSelect]) then sObjectType = "Dir"
  1301.             else                        sObjectType = "File"
  1302.             end
  1303.            
  1304.             term.setCursorPos(6, y)
  1305.            
  1306.             if nSelect == i then term.write("["..tFiles[i].."]")
  1307.             else                 term.write(" "..tFiles[i].." ") end
  1308.            
  1309.             if fs.isDir(tostring(shell.dir()).."/"..tFiles[i]) then term.setCursorPos(42, y); term.write("D ")
  1310.             else                        term.setCursorPos(42, y); term.write("F ") end
  1311.            
  1312.             y = y+1
  1313.             if y == 11 then break end
  1314.         end
  1315.     end
  1316.    
  1317.     while true do
  1318.         printFiles()
  1319.        
  1320.         local event, key = os.pullEvent("key")
  1321.        
  1322.         if key == 200 and nSelect == 1 then nSelect = 1
  1323.         elseif key == 208 and nSelect == #tFiles then nSelect = #tFiles
  1324.        
  1325.         elseif key == 208 and nSelect < #tFiles then
  1326.             if nSelect >= 5 and scroll < #tFiles then scroll = scroll+1; nSelect = nSelect+1
  1327.             else nSelect = nSelect+1 end
  1328.         elseif key == 200 and nSelect > 1 then
  1329.             if nSelect >= 5 and scroll > 0 then scroll = scroll-1; nSelect = nSelect-1
  1330.             else nSelect = nSelect-1 end
  1331.        
  1332.         elseif key == 28 and sObjectType == "File" then
  1333.             if printOptionMenu() then return end
  1334.         elseif key == 28 and sObjectType == "Dir" then shell.setDir(sObjectName); scroll = 0; nSelect = 1
  1335.         elseif key == 14 and shell.dir() ~= "" then shell.run("cd", ".."); scroll = 0; nSelect = 1
  1336.         elseif key == 14 and shell.dir() == "/" or shell.dir() == "" then sMenuState = "main"; break
  1337.         end
  1338.     end
  1339. end
  1340. ----------------
  1341.  
  1342.  
  1343. -- IRC Client --
  1344. function IRC_Client()
  1345.     sMenuState = "irc"
  1346.    
  1347.         -- VARS --
  1348.     local sServerName = ""
  1349.     local nServerID = 0
  1350.     local bConnected = false
  1351.  
  1352.     local sUserName = ""
  1353.     local sText = ""
  1354.  
  1355.     nConversationY = 3
  1356.     ----------
  1357.  
  1358.     -- Helper local functions --
  1359.     local function newReadIRC( _charLimit, _ReplaceChar) -- The filter can either be a 1, 0, or nil. 1 is Numbers only, 0 is letters only, and nil is both
  1360.         local sMessage = ""
  1361.         term.setCursorBlink(true)
  1362.         local originalCursorX, originalCursorY = term.getCursorPos()
  1363.  
  1364.         while true do
  1365.             local cursorX, cursorY = term.getCursorPos()
  1366.             local event, p1, p2 = os.pullEvent()
  1367.            
  1368.             if _charLimit ~= nil then
  1369.                 if string.len(sMessage) == _charLimit then term.setCursorBlink(false); return sMessage end
  1370.             end
  1371.            
  1372.             if event == "char" then sMessage = sMessage..p1
  1373.             --[[elseif event == "key" then -- The escape key has keyID 1 so: 0 = keyID: 11, 1 = keyID: 2, 2 = keyID : 3 etc etc....
  1374.                 if p1 == 11 or p1 == 2 or p1 == 3 or p1 == 4 or p1 == 5 or p1 == 6 or p1 == 7 or p1 == 8 or p1 == 9 or p1 == 10 then
  1375.                 --        0       1          2          3          4          5          6          7          8           9
  1376.                     sMessage = sMessage..(p1-1)
  1377.                 end--]]
  1378.             end
  1379.            
  1380.             if event == "key" and p1 == 28 then
  1381.                 term.setCursorBlink(false)
  1382.                 term.setCursorPos(1, screenHeight)
  1383.                 term.write(string.rep(" ", screenWidth))
  1384.                 return sMessage
  1385.             end-- Enter key; end the loop and let's see the string
  1386.            
  1387.             if event == "key" and p1 == 14 then -- Backspace...
  1388.                 sMessage = string.sub(sMessage, 1, string.len(sMessage)-1)
  1389.                 -- Set our message to the substring of the first charcter      
  1390.                 -- To the length of the message minus 1 to achieve one less letter.
  1391.                
  1392.                 term.setCursorPos(originalCursorX, cursorY)
  1393.                 term.write(sMessage.." ") -- Adding this empty space clears the removed character from the line, but may pose future issues
  1394.             end
  1395.            
  1396.             if event == "rednet_message" and p1 == nServerID then
  1397.                 if nConversationY == 10 then
  1398.                     for i=3, 14 do
  1399.                         term.setCursorPos(3, i); term.write(string.rep(" ", screenWidth-4))
  1400.                     end
  1401.                    
  1402.                     term.setCursorPos(3, 2); term.write(sServerName..":")
  1403.                     term.setCursorPos(5, screenHeight-1)
  1404.                     nConversationY = 3
  1405.                 end
  1406.                
  1407.                 if p1 == nServerID and p2 == "dlskjfiejdlijfklsdj" then bConnected = false; return nil end
  1408.                 term.setCursorPos(3, nConversationY); term.write(p2)
  1409.                 nConversationY = nConversationY+1
  1410.                 term.setCursorPos(string.len(sMessage)+6, screenHeight)
  1411.             end
  1412.            
  1413.             term.setCursorPos(originalCursorX, cursorY); term.write(string.rep(" ", string.len(sMessage)))
  1414.             -- Clear the previous line just in case we get a new line
  1415.             -- Now write the message on the new line
  1416.             if _ReplaceChar ~= nil then
  1417.                 term.setCursorPos(originalCursorX, cursorY)
  1418.                 term.write(string.rep( _ReplaceChar, string.len(sMessage) ))
  1419.             else
  1420.                 term.setCursorPos(originalCursorX, cursorY)
  1421.                 term.write(sMessage)
  1422.             end
  1423.         end
  1424.     end
  1425.     ----------------------
  1426.  
  1427.     -- Input related local functions --
  1428.     local function getInput()
  1429.         cPrint(4, "IRC Version: Beta 1.0")
  1430.         cPrint(5, "Server ID: ")
  1431.         cPrint(6, " Username: ")
  1432.        
  1433.         rPrint(17, "Common channels: 146, 174, 175, 176, 177*")
  1434.        
  1435.         term.setCursorPos(screenWidth/2 - string.len("Server ID: ")/2 + string.len("Server ID: "), 5)
  1436.         nServerID = tonumber(newRead(5))
  1437.        
  1438.         term.setCursorPos(screenWidth/2 - string.len(" Username: ")/2 + string.len(" Username: "), 6)
  1439.         sUserName = newRead(14)
  1440.     end
  1441.     -----------------------------
  1442.  
  1443.     -- Networking related local functions --
  1444.     local function connectToServer()
  1445.         if bConnected == true then return nil end
  1446.        
  1447.         if nServerID ~= nil then
  1448.             rednet.send(tonumber(nServerID), "dlsk;fje3ijoidsjfl")
  1449.            
  1450.             sender, message = rednet.receive(0.2)
  1451.            
  1452.             if sender == nServerID and message == "a;sodifu39798d0f3" then
  1453.                 rednet.send(tonumber(nServerID), tostring(sUserName))
  1454.                
  1455.                 sender, message = rednet.receive(0.1)
  1456.                
  1457.                 if sender == nServerID and message == "ifjdslfije" then
  1458.                     bConnected = true
  1459.                    
  1460.                     sender, message = rednet.receive(0.2)
  1461.                    
  1462.                     if sender == nServerID then sServerName = message end
  1463.                 end
  1464.             end
  1465.         else os.shutdown() end
  1466.     end
  1467.  
  1468.     local function sendMessage( _sMessage )
  1469.         rednet.send( tonumber(nServerID), _sMessage )
  1470.     end
  1471.     ----------------------------------
  1472.  
  1473.     printBorder()
  1474.     getInput()
  1475.     connectToServer()
  1476.     clear()
  1477.     printBorder()
  1478.     term.setCursorPos(3, 2); term.write(sServerName..":")
  1479.     term.setCursorPos(3, screenHeight-1); term.write("> ")
  1480.  
  1481.     while bConnected do
  1482.         if nConversationY == 10 then
  1483.             for i=3, 14 do
  1484.                 term.setCursorPos(3, i); term.write(string.rep(" ", screenWidth-4))
  1485.             end
  1486.            
  1487.             term.setCursorPos(3, 2); term.write(sServerName..":")
  1488.             term.setCursorPos(5, screenHeight-1)
  1489.             nConversationY = 3
  1490.         end
  1491.        
  1492.         sText = newReadIRC(14) -- This will be our disconnection message: dslifj
  1493.         if sText == "!exit" then clear(); sendMessage("dslifj"); sMenuState = "main"; break end
  1494.         if sText == nil then term.setCursorBlink(false); sMenuState = "main"; break end
  1495.        
  1496.         if sText ~= sUserName then sendMessage(sText)
  1497.         else nConversationY = nConversationY-1 end
  1498.         sText = ""
  1499.         term.setCursorPos(3, screenHeight-1); term.write(string.rep(" ", screenWidth-4))
  1500.         term.setCursorPos(3, screenHeight-1); term.write("> ")
  1501.        
  1502.         term.setCursorPos(2, screenHeight); term.write(string.rep("*", screenWidth-2))
  1503.         term.setCursorPos(5, screenHeight-1)
  1504.     end
  1505.     clear()
  1506.     sMenuState = "main"
  1507. end
  1508. ---------------------
  1509.  
  1510.  
  1511. -- Account --
  1512. function editAccount()
  1513.     sMenuState = "account"
  1514.     local nSelect = 1
  1515.    
  1516.     clearCenter()
  1517.     local function printInfoContainer()
  1518.         term.setCursorPos(4, 5); term.write(string.rep("*", screenWidth-6))
  1519.         local y = 6
  1520.         for i=1, screenHeight - 13 do
  1521.             term.setCursorPos(4, y); term.write("*"..string.rep(" ", screenWidth-8).."*")
  1522.             y = y+1
  1523.         end
  1524.         term.setCursorPos(4, 11); term.write(string.rep("*", screenWidth-6))
  1525.     end
  1526.    
  1527.     printInfoContainer()
  1528.     while true do
  1529.         if nSelect == 3 then sMenuState = "main"; break end
  1530.        
  1531.         term.setCursorPos(5, 7); term.write("Username: "..sUserName)
  1532.         term.setCursorPos(5, 8); term.write("Password: "..string.rep("*", string.len(sPassword)))
  1533.        
  1534.         if nSelect == 1 then term.setCursorPos((screenWidth-6)-(string.len("[ Change ]*")-4), 7); term.write("[ Change ]*")
  1535.         else                 term.setCursorPos((screenWidth-6)-(string.len("[ Change ]*")-4), 7); term.write("  Change  *") end
  1536.        
  1537.         if nSelect == 2 then term.setCursorPos((screenWidth-6)-(string.len("[ Change ]*")-4), 8); term.write("[ Change ]*")
  1538.         else                 term.setCursorPos((screenWidth-6)-(string.len("[ Change ]*")-4), 8); term.write("  Change  *") end
  1539.        
  1540.         local event, key = os.pullEvent("key")
  1541.        
  1542.         if key == 208 and nSelect == 1 then nSelect = nSelect+1
  1543.         elseif key == 200 and nSelect == 2 then nSelect = nSelect-1
  1544.        
  1545.         elseif key == 28 and nSelect == 1 then
  1546.             term.setCursorPos(5, 7); term.write(string.rep(" ", screenWidth-8))
  1547.             term.setCursorPos(5, 7); term.write("New Username: ")
  1548.             sUserName = newRead(14)
  1549.             term.setCursorPos(5, 7); term.write(string.rep(" ", screenWidth-8))
  1550.            
  1551.             local file = fs.open("User/"..os.getComputerID().."/.info", "w")
  1552.             file.write(sUserName.."\n"..sPassword)
  1553.             file.close()
  1554.         elseif key == 28 and nSelect == 2 then
  1555.             term.setCursorPos(5, 8); term.write(string.rep(" ", screenWidth-8))
  1556.             term.setCursorPos(5, 8); term.write("Old Password: ")
  1557.             local sCheckPassword = newRead(14, "*")
  1558.            
  1559.             if sCheckPassword == sPassword then
  1560.                 term.setCursorPos(5, 8); term.write(string.rep(" ", screenWidth-8))
  1561.                 term.setCursorPos(5, 8); term.write("New Password: ")
  1562.                 sPassword = newRead(14, "*")
  1563.                
  1564.                 local file = fs.open("User/"..os.getComputerID().."/.info", "w")
  1565.                 file.write(sUserName.."\n"..sPassword)
  1566.                 file.close()
  1567.             end
  1568.             term.setCursorPos(5, 8); term.write(string.rep(" ", screenWidth-8))
  1569.         elseif key == 14 then nSelect = 3
  1570.         end
  1571.     end
  1572. end
  1573. -------------
  1574.  
  1575. function printError()
  1576.     sMenuState = "perms"; clearCenter()
  1577.     cPrint(6, "*********************")
  1578.     cPrint(7, "* Restricted Access *")
  1579.     cPrint(8, "*********************")
  1580.     sleep(2)
  1581.     sMenuState = "main"
  1582. end
  1583.  
  1584.  
  1585.  
  1586. clear()
  1587. getKey() -- b8v2a6b8i1e2j8g91
  1588. clear()
  1589. printInstallation()
  1590. clear()
  1591. checkUserInformation()
  1592. getUserInformation()
  1593. handleLogin()
  1594.  
  1595. if bLogin then
  1596.     if checkVersion() then
  1597.         sMenuState = "updateScreen"
  1598.         clear()
  1599.         printBorder()
  1600.         rPrint(17, "Cannon OS Version: "..VERSION.."*")
  1601.         cPrint(6, "********************")
  1602.         cPrint(7, "* Update Available *")
  1603.         cPrint(8, "********************")
  1604.        
  1605.         local select = 1
  1606.         while true do
  1607.             if select == 1 then cPrint(9, "*   [ Yes ] No     *")
  1608.             else                cPrint(9, "*     Yes [ No ]   *")
  1609.             end
  1610.             cPrint(10, "********************")
  1611.            
  1612.             local event, key = os.pullEvent("key")
  1613.            
  1614.             if key == 205 and select == 1 then select = 2
  1615.             elseif key == 203 and select == 2 then select = 1
  1616.            
  1617.             elseif key == 28 and select == 1 then clear(); printBorder(); rPrint(17, "Cannon OS Version: "..VERSION.."*"); fs.delete("SYSTEM"); fs.delete("User"); term.setCursorPos(screenWidth/2-string.len("Updating...")/2, 9); textutils.slowPrint("Updating..."); updateSelf(); shell.run("startup")
  1618.             elseif key == 28 and select == 2 then sMenuState = "main"; clearCenter(); break
  1619.             end
  1620.         end
  1621.     end
  1622. end
  1623.  
  1624. -- Main OS Loop --
  1625. while true do
  1626.     clear()
  1627.     nMailCount = #(fs.list("Mail"))-1 -- -1 To eliminate the 'Contacts' directory from the list
  1628.     printMainMenu()
  1629.    
  1630.     event, key, p2 = os.pullEvent() -- Key will be p1, laziness has struck again
  1631.    
  1632.     if event == "key" and key == 205 and selection < 6 and selection ~= 3 then selection = selection+1
  1633.     elseif event == "key" and key == 203 and selection > 1 and selection ~= 4 then selection = selection-1
  1634.     elseif event == "key" and key == 208 and selection < 6 and selection+3 <= 6 then selection = selection+3
  1635.     elseif event == "key" and key == 200 and selection > 1 and selection-3 >= 1 then selection = selection-3
  1636.    
  1637.     elseif event == "key" and key == 28 and selection == 6 then
  1638.         clear(); printBorder(); rPrint(17, "Cannon OS Version: "..VERSION.."*"); term.setCursorPos(screenWidth/2-string.len("Updating...")/2, 9); textutils.slowPrint("Updating...")
  1639.         if not updateSelf() then cPrint(9, "Update Failed"); sleep(1.3); shell.run("startup")
  1640.         else fs.delete("SYSTEM"); fs.delete("User"); cPrint(9, "Update Successfull"); sleep(1.3); shell.run("startup")
  1641.         end
  1642.     elseif event == "key" and key == 28 and selection == 2 and bAdmin then
  1643.         clear()
  1644.         printBorder()
  1645.         cPrint(6, "Password: ")
  1646.         sInput = newRead(string.len(sPassword), "*")
  1647.        
  1648.         if sInput == sPassword then clear(); shell.run("SYSTEM/.shell");
  1649.         else cPrint(8, "Incorrect Password."); sleep(1.3) end
  1650.     elseif event == "key" and key == 28 and selection == 2 and not bAdmin then printError()
  1651.    
  1652.     elseif event == "key" and key == 28 and selection == 4 and bAdmin then mailMenu()
  1653.     elseif event == "key" and key == 28 and selection == 4 and not bAdmin then printError()
  1654.    
  1655.     elseif event == "key" and key == 28 and selection == 1 and bAdmin then fileBrowser()
  1656.     elseif event == "key" and key == 28 and selection == 1 and not bAdmin then printError()
  1657.    
  1658.     elseif event == "key" and key == 28 and selection == 3 then clear(); IRC_Client()
  1659.    
  1660.     elseif event == "key" and key == 28 and selection == 5 and bAdmin then editAccount()
  1661.     elseif event == "key" and key == 28 and selection == 5 and not bAdmin then printError()
  1662.    
  1663.     elseif event == "rednet_message" then
  1664.         if string.find( p2, ";alkdjien") then
  1665.             p2 = string.sub( p2, string.len(";alkdjien"), string.len( p2 ))
  1666.             p2 = string.sub( p2, 3, string.len( p2 )) -- 3 to remove the \n from the message
  1667.             local file = fs.open("Mail/message"..#(fs.list("Mail"))+1, "w")
  1668.             file.writeLine(key)
  1669.             file.writeLine(p2)
  1670.             file.close()
  1671.            
  1672.             nMailCount = nMailCount+1
  1673.             newMessage(key, p2) -- Key being the senderID and p2 being the message received
  1674.         end
  1675.     elseif event == "reboot" then selection = 1; sMenuState = "logout"; printLogout()
  1676.     end
  1677. end
  1678. ------------------
  1679.  
  1680. os.pullEvent = oldpullEvent
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement