Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Better network boot, developed by PaymentOption --
- VERSION = 1.0
- -------------
- -- Variables --
- local tOS_List = {} -- Holds all of the available names of OS' to boot to.
- -- ^^ FORMAT: tOS_List[n] = { Name, Version }
- local NetworkID = 0 -- The network ID that we will retrieve OS' from and boot to an OS from.
- local bConnected = false -- Whether or not we are connected to a network.
- local bRunning = true -- Whether or not the program should be running.
- local ScreenWidth, ScreenHeight = term.getSize() -- Holds the width and height of the screen.
- local Selection = 1 -- The currently selected index in the OS' available.
- ---------------
- -- Borrowed functions --
- -- Following function taken from: http://lua-users.org/wiki/SplitJoin
- -- Compatibility: Lua-5.1
- function split(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pat
- 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
- ------------------------
- -- Drawing functions --
- function cPrint( height, string ) -- Prints to the dead center of the screen.
- term.setCursorPos( ScreenWidth/2 - string.len( string )/2, height )
- term.write( string )
- end
- function rPrint( height, string ) -- Prints to the very right of the screen.
- term.setCursorPos( ScreenWidth - string.len( string ), height )
- term.write( string )
- end
- function Clear() -- Clears the screen.
- term.clear()
- term.setCursorPos( 1, 1 )
- end
- function DrawBorder()
- term.setCursorPos( 1, 1 )
- term.write( string.rep( "*", 50 ) )
- for i=2, 17 do
- term.setCursorPos( 1, i )
- term.write( "*" )
- term.setCursorPos( 50, i )
- term.write( "*" )
- end
- term.setCursorPos( 1, 18 )
- term.write( string.rep( "*", 50 ) )
- end
- function DrawLogo() -- Draws the PaymentOption signature logo.
- print( " ____ __ " )
- print( " / __ \\____ ___ ______ ___ ___ ____ / /_" )
- print( " / /_/ / __ '/ / / / __ '__ \\/ _ \\/ __ \\/ __/" )
- print( " / ____/ /_/ / /_/ / / / / / / __/ / / / /_ " )
- print( " /_/ \\__,_/\\__, /_/ /_/ /_/\\___/_/ /_/\\__/ " )
- print( " /____/ " )
- end
- function limitRead( nLength, cReplaceChar )
- term.setCursorBlink( true )
- nLength = nLength or -1 -- -1 is unlimited
- sReturnString = ""
- xPos, yPos = term.getCursorPos()
- while true do
- event, char = os.pullEvent()
- if nLength ~= -1 and string.len( sReturnString ) >= nLength then term.setCursorBlink( false ); return sReturnString end -- Length check
- if event == "char" then sReturnString = sReturnString .. char
- elseif event == "key" then
- if char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
- elseif char == 14 then -- Backspace
- term.setCursorPos( xPos, yPos )
- term.write( string.rep( " ", string.len( sReturnString ) ) )
- sReturnString = string.sub( sReturnString, 1, string.len( sReturnString )-1 )
- term.setCursorPos( xPos, yPos )
- if not cReplaceChar then term.write( sReturnString )
- else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
- end
- end
- term.setCursorPos( xPos, yPos )
- term.write( string.rep( " ", string.len( sReturnString ) ) )
- term.setCursorPos( xPos, yPos )
- if not cReplaceChar then term.write( sReturnString )
- else term.write( string.rep( cReplaceChar, string.len( sReturnString ) ) ) end
- end
- end
- -----------------------
- -- Screen drawing functions --
- function DrawTitleScreen() -- Draws the opening screen to be displayed when the program is run.
- Clear()
- cPrint( 3, "Developed by" )
- term.setCursorPos( 1, 4 )
- DrawLogo()
- DrawBorder()
- end
- function DrawGetServerScreen() -- Draws the screen that prompts us to get a network ID to retrieve OS' from.
- Clear()
- cPrint( 2, "Enter a valid network ID" )
- DrawBorder()
- 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.
- term.write( "Networkd ID: " )
- NetworkID = tonumber( limitRead( 4 ) ) -- Get a network ID from the user and cast it to a number since read returns a string.
- if GetOS_List() then -- If we get the OS list successfully, then the connection was a success.
- bConnected = true -- We are connected.
- else -- If we do not get the OS list successfully, then the connection was a failure.
- bConnected = false -- We are not connected.
- end
- end
- function DrawBootOptionScreen()
- Clear()
- DrawBorder()
- cPrint( 2, "Available Operating Systems" )
- rPrint( 17, "Network Boot" )
- term.setCursorPos( 2, 17 )
- write( "Version: " .. VERSION )
- for i=1, #tOS_List do -- Draw out the list of available OS'.
- term.setCursorPos( 3, i + 3 ) -- Set the cursor to x = 3, y = i offset by 3 so it starts on line 4.
- if Selection == i then -- If the current OS is selected.
- term.write( "-> " .. tOS_List[i].Name ) -- Draw the OS' name with an arrow indicating that it is selected.
- else -- If the current OS is not selected.
- term.write( " " .. tOS_List[i].Name ) -- Draw the OS' name without an arrow indicating that it is selected.
- end
- term.setCursorPos( 30, i + 3 ) -- Set the cursor at x = 30, y = i offset by 3 so it starts on line 4.
- term.write( "Ver: " .. tOS_List[i].Version ) -- Draw the OS' version regardless of it being selected.
- end
- end
- ------------------------------
- -- Key handling functions --
- function HandleKeyPress( Key )
- if Key == 200 and Selection > 1 then -- If the key was to move the selection up on the screen.
- Selection = Selection - 1 -- Move the selection up.
- elseif Key == 208 and Selection < #tOS_List then -- If the key was to move the selection down on the screen.
- Selection = Selection + 1 -- Move the selection down.
- elseif Key == 28 then -- If the key was enter then get and execute the requested OS.
- local OS = RequestOS( Selection ) -- Attempt to get the OS in a function.
- if OS then -- If the OS was retrieved successfully.
- shell.run( "Temp_OS" ) -- Execute the OS.
- shell.exit()
- else -- If the OS was not retrieved successfully.
- -- Report the failure.
- cPrint( 17, "Networking failure." )
- sleep( 1.3 )
- end
- end
- end
- ----------------------------
- -- Networking functions --
- function OpenExistantModem() -- Opens any modem found, returns true. Returns false if no modem was found.
- local tSides = rs.getSides()
- for i=1, #tSides do
- if peripheral.isPresent( tSides[i] ) and peripheral.getType( tSides[i] ) == "modem" then
- rednet.open( tSides[i] )
- return true
- end
- end
- return false
- end
- function Ping( ID ) -- Makes sure that we can contact the computer ID passed and that they are listening for requests.
- rednet.send( ID, "PingingYou" ) -- Send a request to the server.
- local sender, message = rednet.receive( 0.2 ) -- Wait for .2 seconds for a response.
- if sender == ID then -- If the message received was from the server we pinged.
- if message == "PingingYouBack" then -- If the message received was a ping acknowledgement.
- return true -- Report a successfull ping.
- else -- If the message received was not a ping acknowledgement.
- return false -- Report an unsuccessfull ping.
- end
- else -- If the message received was not from the server we pinged.
- return false -- Report an unsuccessfull ping.
- end
- end
- function GetOS_List() -- Gets the available list of OS' from the network computer.
- if Ping( NetworkID ) then -- If we can contact the network computer.
- rednet.send( NetworkID, "AllPlease" ) -- Request the OS'.
- local sender, message = rednet.receive( 0.2 ) -- Wait for a response from the network for .2 seconds.
- if sender == NetworkID then -- If the message received was from the network computer.
- local DownloadedList = split( message, "@#DS!" ) -- Split the message into a table by pattern !SP!.
- for i=1, #DownloadedList, 2 do -- Iterate through every other index of the downloaded list table.
- tOS_List[#tOS_List+1] = { Name = DownloadedList[i], Version = tonumber( DownloadedList[i+1] ) }
- -- ^^ Fill the OS_List table with the appropriate values.
- end
- return true -- Report a successfull download.
- else -- If the message was not from the network.
- return false -- Report a failure.
- end
- else -- If we cannot contact the network compute.r
- return false -- Report a failure.
- end
- end
- function RequestOS( OS_Index ) -- Requests the OS passed from the network and loads it into a usable function. Returns the function or false.
- if Ping( NetworkID ) then -- If we can contact the network.
- rednet.send( NetworkID, "OS_Number_" .. OS_Index ) -- Request the OS by Index in the OS table.
- local sender, message = rednet.receive( 0.2 ) -- Wait for a response from the network computer for .2 seconds.
- if sender == NetworkID then -- If the message received was from the network computer.
- if message then -- If the message is not equal to nil.
- if fs.exists( "Temp_OS" ) then
- fs.delete( "Temp_OS" )
- end
- local File = fs.open( "Temp_OS", "w" )
- File.write( message )
- File.close()
- return true
- else -- If the message is equal to nil.
- return false -- Report a failure.
- end
- else -- If the message received was not from the network computer.
- return false -- Report a failure.
- end
- else -- If we cannot contact the network.
- return false -- Report a failure.
- end
- end
- --------------------------
- -- Main loop function --
- function MainLoop()
- if bConnected then -- If the connection was a success.
- DrawBootOptionScreen() -- Draw the available OS' to boot from.
- local event, key = os.pullEvent( "key" ) -- Wait for a key press.
- HandleKeyPress( key ) -- Handle the key press that occured.
- else -- If the connection was a failure.
- bRunning = false -- Exit the program.
- end
- end
- ------------------------
- -- The program --
- if not OpenExistantModem() then
- error( "No modem found." )
- end
- DrawTitleScreen() -- Draw the logo and credits.
- sleep( 1.3 )
- DrawGetServerScreen() -- Get the network ID to connect to.
- cPrint( 14, "Connecting..." ) -- Inform the user that we are connecting.
- sleep( 0.2 )
- while bRunning do
- MainLoop()
- end
- if not bRunning then
- Clear()
- print( os.version() )
- print( "Connection failure: " .. shell.getRunningProgram() )
- end
- -----------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement