Advertisement
PaymentOption

NetBootClient

Aug 20th, 2012
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.58 KB | None | 0 0
  1. -- Better network boot, developed by PaymentOption --
  2. VERSION = 1.0
  3. -------------
  4.  
  5. -- Variables --
  6. local tOS_List = {} -- Holds all of the available names of OS' to boot to.
  7. -- ^^ FORMAT: tOS_List[n] = { Name, Version }
  8. local NetworkID = 0 -- The network ID that we will retrieve OS' from and boot to an OS from.
  9. local bConnected = false -- Whether or not we are connected to a network.
  10.  
  11. local bRunning = true -- Whether or not the program should be running.
  12.  
  13. local ScreenWidth, ScreenHeight = term.getSize() -- Holds the width and height of the screen.
  14. local Selection = 1 -- The currently selected index in the OS' available.
  15. ---------------
  16.  
  17. -- Borrowed functions --
  18. -- Following function taken from: http://lua-users.org/wiki/SplitJoin
  19. -- Compatibility: Lua-5.1
  20. function split(str, pat)
  21.    local t = {}  -- NOTE: use {n = 0} in Lua-5.0
  22.    local fpat = "(.-)" .. pat
  23.    local last_end = 1
  24.    local s, e, cap = str:find(fpat, 1)
  25.    while s do
  26.       if s ~= 1 or cap ~= "" then
  27.      table.insert(t,cap)
  28.       end
  29.       last_end = e+1
  30.       s, e, cap = str:find(fpat, last_end)
  31.    end
  32.    if last_end <= #str then
  33.       cap = str:sub(last_end)
  34.       table.insert(t, cap)
  35.    end
  36.    return t
  37. end
  38. ------------------------
  39.  
  40. -- Drawing functions --
  41. function cPrint( height, string ) -- Prints to the dead center of the screen.
  42.     term.setCursorPos( ScreenWidth/2 - string.len( string )/2, height )
  43.     term.write( string )
  44. end
  45.  
  46. function rPrint( height, string ) -- Prints to the very right of the screen.
  47.     term.setCursorPos( ScreenWidth - string.len( string ), height )
  48.     term.write( string )
  49. end
  50.  
  51. function Clear() -- Clears the screen.
  52.     term.clear()
  53.     term.setCursorPos( 1, 1 )
  54. end
  55.  
  56. function DrawBorder()
  57.     term.setCursorPos( 1, 1 )
  58.     term.write( string.rep( "*", 50 ) )
  59.    
  60.     for i=2, 17 do
  61.         term.setCursorPos( 1, i )
  62.         term.write( "*" )
  63.         term.setCursorPos( 50, i )
  64.         term.write( "*" )
  65.     end
  66.    
  67.     term.setCursorPos( 1, 18 )
  68.     term.write( string.rep( "*", 50 ) )
  69. end
  70.  
  71. function DrawLogo() -- Draws the PaymentOption signature logo.
  72.     print( "     ____                                   __ " )
  73.     print( "    / __ \\____ ___  ______ ___  ___  ____  / /_" )
  74.     print( "   / /_/ / __ '/ / / / __ '__ \\/ _ \\/ __ \\/ __/" )
  75.     print( "  / ____/ /_/ / /_/ / / / / / /  __/ / / / /_ " )
  76.     print( " /_/    \\__,_/\\__, /_/ /_/ /_/\\___/_/ /_/\\__/ " )
  77.     print( "             /____/                            " )
  78. end
  79.  
  80. function limitRead( nLength, cReplaceChar )
  81.       term.setCursorBlink( true )
  82.  
  83.       nLength = nLength or -1 -- -1 is unlimited
  84.       sReturnString = ""
  85.  
  86.       xPos, yPos = term.getCursorPos()
  87.  
  88.       while true do
  89.                event, char = os.pullEvent()
  90.  
  91.                if nLength ~= -1 and string.len( sReturnString ) >= nLength then term.setCursorBlink( false ); return sReturnString end -- Length check
  92.                     if event == "char" then sReturnString = sReturnString .. char
  93.                     elseif event == "key" then
  94.                         if char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
  95.                         elseif char == 14 then -- Backspace
  96.                                 term.setCursorPos( xPos, yPos )
  97.                                 term.write( string.rep( " ", string.len( sReturnString ) ) )
  98.                                 sReturnString = string.sub( sReturnString, 1, string.len( sReturnString )-1 )
  99.                                 term.setCursorPos( xPos, yPos )
  100.  
  101.                                 if not cReplaceChar then term.write( sReturnString )
  102.                                 else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  103.                         end
  104.                     end
  105.                     term.setCursorPos( xPos, yPos )
  106.                     term.write( string.rep( " ", string.len( sReturnString ) ) )
  107.                     term.setCursorPos( xPos, yPos )
  108.                     if not cReplaceChar then term.write( sReturnString )
  109.                     else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
  110.             end
  111.     end
  112. -----------------------
  113.  
  114. -- Screen drawing functions --
  115. function DrawTitleScreen() -- Draws the opening screen to be displayed when the program is run.
  116.     Clear()
  117.     cPrint( 3, "Developed by" )
  118.     term.setCursorPos( 1, 4 )
  119.     DrawLogo()
  120.     DrawBorder()
  121. end
  122.  
  123. function DrawGetServerScreen() -- Draws the screen that prompts us to get a network ID to retrieve OS' from.
  124.     Clear()
  125.     cPrint( 2, "Enter a valid network ID" )
  126.     DrawBorder()
  127.    
  128.     term.setCursorPos( ScreenWidth/2 - string.len( "Network ID: " ) + 4, 4 ) -- Set the cursor in the middle of the position offset enough to accept a 4 digit ID.
  129.     term.write( "Networkd ID: " )
  130.     NetworkID = tonumber( limitRead( 4 ) ) -- Get a network ID from the user and cast it to a number since read returns a string.
  131.    
  132.     if GetOS_List() then -- If we get the OS list successfully, then the connection was a success.
  133.         bConnected = true -- We are connected.
  134.     else -- If we do not get the OS list successfully, then the connection was a failure.
  135.         bConnected = false -- We are not connected.
  136.     end
  137. end
  138.  
  139. function DrawBootOptionScreen()
  140.     Clear()
  141.     DrawBorder()
  142.     cPrint( 2, "Available Operating Systems" )
  143.     rPrint( 17, "Network Boot" )
  144.     term.setCursorPos( 2, 17 )
  145.     write( "Version: " .. VERSION )
  146.    
  147.     for i=1, #tOS_List do -- Draw out the list of available OS'.
  148.         term.setCursorPos( 3, i + 3 ) -- Set the cursor to x = 3, y = i offset by 3 so it starts on line 4.
  149.        
  150.         if Selection == i then -- If the current OS is selected.
  151.             term.write( "-> " .. tOS_List[i].Name ) -- Draw the OS' name with an arrow indicating that it is selected.
  152.         else -- If the current OS is not selected.
  153.             term.write( "   " .. tOS_List[i].Name ) -- Draw the OS' name without an arrow indicating that it is selected.
  154.         end
  155.        
  156.         term.setCursorPos( 30, i + 3 ) -- Set the cursor at x = 30, y = i offset by 3 so it starts on line 4.
  157.         term.write( "Ver: " .. tOS_List[i].Version ) -- Draw the OS' version regardless of it being selected.
  158.     end
  159. end
  160. ------------------------------
  161.  
  162. -- Key handling functions --
  163. function HandleKeyPress( Key )
  164.     if Key == 200 and Selection > 1 then -- If the key was to move the selection up on the screen.
  165.         Selection = Selection - 1 -- Move the selection up.
  166.     elseif Key == 208 and Selection < #tOS_List then -- If the key was to move the selection down on the screen.
  167.         Selection = Selection + 1 -- Move the selection down.
  168.     elseif Key == 28 then -- If the key was enter then get and execute the requested OS.
  169.         local OS = RequestOS( Selection ) -- Attempt to get the OS in a function.
  170.        
  171.         if OS then -- If the OS was retrieved successfully.
  172.             shell.run( "Temp_OS" ) -- Execute the OS.
  173.             shell.exit()
  174.         else -- If the OS was not retrieved successfully.
  175.             -- Report the failure.
  176.             cPrint( 17, "Networking failure." )
  177.             sleep( 1.3 )
  178.         end
  179.     end
  180. end
  181. ----------------------------
  182.  
  183. -- Networking functions --
  184. function OpenExistantModem() -- Opens any modem found, returns true. Returns false if no modem was found.
  185.     local tSides = rs.getSides()
  186.    
  187.     for i=1, #tSides do
  188.         if peripheral.isPresent( tSides[i] ) and peripheral.getType( tSides[i] ) == "modem" then
  189.             rednet.open( tSides[i] )
  190.             return true
  191.         end
  192.     end
  193.    
  194.     return false
  195. end
  196.  
  197. function Ping( ID ) -- Makes sure that we can contact the computer ID passed and that they are listening for requests.
  198.     rednet.send( ID, "PingingYou" ) -- Send a request to the server.
  199.     local sender, message = rednet.receive( 0.2 ) -- Wait for .2 seconds for a response.
  200.    
  201.     if sender == ID then -- If the message received was from the server we pinged.
  202.         if message == "PingingYouBack" then -- If the message received was a ping acknowledgement.
  203.             return true -- Report a successfull ping.
  204.         else -- If the message received was not a ping acknowledgement.
  205.             return false -- Report an unsuccessfull ping.
  206.         end
  207.     else -- If the message received was not from the server we pinged.
  208.         return false -- Report an unsuccessfull ping.
  209.     end
  210. end
  211.  
  212. function GetOS_List() -- Gets the available list of OS' from the network computer.
  213.     if Ping( NetworkID ) then -- If we can contact the network computer.
  214.         rednet.send( NetworkID, "AllPlease" ) -- Request the OS'.
  215.         local sender, message = rednet.receive( 0.2 ) -- Wait for a response from the network for .2 seconds.
  216.        
  217.         if sender == NetworkID then -- If the message received was from the network computer.
  218.             local DownloadedList = split( message, "@#DS!" ) -- Split the message into a table by pattern !SP!.
  219.            
  220.             for i=1, #DownloadedList, 2 do -- Iterate through every other index of the downloaded list table.
  221.                 tOS_List[#tOS_List+1] = { Name = DownloadedList[i], Version = tonumber( DownloadedList[i+1] ) }
  222.                 -- ^^ Fill the OS_List table with the appropriate values.
  223.             end
  224.            
  225.             return true -- Report a successfull download.
  226.         else -- If the message was not from the network.
  227.             return false -- Report a failure.
  228.         end
  229.     else -- If we cannot contact the network compute.r
  230.         return false -- Report a failure.
  231.     end
  232. end
  233.  
  234. function RequestOS( OS_Index ) -- Requests the OS passed from the network and loads it into a usable function. Returns the function or false.
  235.     if Ping( NetworkID ) then -- If we can contact the network.
  236.         rednet.send( NetworkID, "OS_Number_" .. OS_Index ) -- Request the OS by Index in the OS table.
  237.         local sender, message = rednet.receive( 0.2 ) -- Wait for a response from the network computer for .2 seconds.
  238.        
  239.         if sender == NetworkID then -- If the message received was from the network computer.
  240.             if message then -- If the message is not equal to nil.
  241.                 if fs.exists( "Temp_OS" ) then
  242.                     fs.delete( "Temp_OS" )
  243.                 end
  244.                
  245.                 local File = fs.open( "Temp_OS", "w" )
  246.                 File.write( message )
  247.                 File.close()
  248.                
  249.                 return true
  250.             else -- If the message is equal to nil.
  251.                 return false -- Report a failure.
  252.             end
  253.         else -- If the message received was not from the network computer.
  254.             return false -- Report a failure.
  255.         end
  256.     else -- If we cannot contact the network.
  257.         return false -- Report a failure.
  258.     end
  259. end
  260. --------------------------
  261.  
  262. -- Main loop function --
  263. function MainLoop()
  264.     if bConnected then -- If the connection was a success.
  265.         DrawBootOptionScreen() -- Draw the available OS' to boot from.
  266.        
  267.         local event, key = os.pullEvent( "key" ) -- Wait for a key press.
  268.         HandleKeyPress( key ) -- Handle the key press that occured.
  269.     else -- If the connection was a failure.
  270.         bRunning = false -- Exit the program.
  271.     end
  272. end
  273. ------------------------
  274.  
  275. -- The program --
  276. if not OpenExistantModem() then
  277.     error( "No modem found." )
  278. end
  279.  
  280. DrawTitleScreen() -- Draw the logo and credits.
  281. sleep( 1.3 )
  282.  
  283. DrawGetServerScreen() -- Get the network ID to connect to.
  284. cPrint( 14, "Connecting..." ) -- Inform the user that we are connecting.
  285. sleep( 0.2 )
  286.  
  287. while bRunning do
  288.     MainLoop()
  289. end
  290.  
  291. if not bRunning then
  292.     Clear()
  293.     print( os.version() )
  294.     print( "Connection failure: " .. shell.getRunningProgram() )
  295. end
  296. -----------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement