Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- File client for OMNI INC. by PaymentOption --
- -- Credits:
- -- Main Programmer: PaymentOption
- -- Lead Designer: PaymentOption
- -- Co Designer: cmez123
- -- Funded by: cmez123, iananimatorpro
- --[[
- NOTES:
- A ping from the server consists of the message "pingingYouFromServer" to which the client should respond with "respondingToPingFromYou".
- CODE:
- function ping( id )
- rednet.send( id, "pingingYouFromServer" )
- local sender, message = rendet.receive( 0.15 )
- if sender == id and message == "respondingToPingFromYou" then return true
- else return false end
- end
- --]]
- -- VARS --
- sCurrentLocationInServer = "/" -- The current path or "location" that the user is located in at any given time.
- tFilesInLocation = {}
- temp = {}
- nSelect = 1
- nSubSelect = 1 -- For sub menues, like the commands menu.
- scroll = 0 -- For the scrolling of menues.
- bInFileMenu = false
- bConnected = false -- True if you're currently viewing files on a server.
- nServerID = nil
- bRunning = true
- VERSION = 1.12
- screenWidth, screenHeight = term.getSize()
- ----------
- -- Helper Functions --
- -- Code taken directly 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
- -- End code snippet --
- 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" and char == 28 then term.setCursorBlink( false ); return sReturnString -- Enter
- elseif event == "key" and 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
- 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
- function cPrint( height, string )
- term.setCursorPos( screenWidth/2 - string.len( string )/2, height ); term.write( string )
- end
- function rPrint( height, string )
- term.setCursorPos( screenWidth - string.len( string ), height ); term.write( string )
- end
- function clear() term.clear(); term.setCursorPos( 1, 1 ) end
- function printBorder()
- for i=1, screenHeight do
- term.setCursorPos( 1, i )
- if i == 1 or i == screenHeight then term.write( string.rep( "*", screenWidth ) )
- else term.write( "*" .. string.rep( " ", screenWidth - 2 ) .. "*" ) end
- end
- end
- function printLogo()
- term.setCursorPos( 3, 3 )
- write( [[ ________ .__
- * \_____ \ _____ ____ |__|
- * / | \ / \ / \| |
- * / | \ Y Y \ | \ |
- * \_______ /__|_| /___| /__|
- * \/ \/ \/
- * .___
- * | | ____ ____
- * | |/ \_/ ___\
- * | | | \ \___
- * |___|___| /\___ > /\
- * \/ \/ \/
- ]] )
- rPrint( 17, "Version: " .. VERSION )
- rPrint( 16, "~ PaymentOption" )
- end
- function checkDirs()
- if not fs.isDir( "Files" ) then fs.makeDir( "Files" ) end
- end
- ----------------------
- -- Update functions --
- local function update(nNewVer)
- local sCode = "xWTMwPnx"
- file = fs.open(".serverVersion", "w")
- file.write(nNewVer)
- file.close()
- clear()
- printBorder()
- cPrint(6, "***************")
- cPrint(7, "* Updating... *")
- cPrint(8, "***************")
- while true do
- local response = http.get(
- "http://pastebin.com/raw.php?i="..textutils.urlEncode( sCode )
- )
- if response then
- local sResponse = response.readAll()
- response.close()
- file = fs.open("/FILE_Client", "w")
- file.write(sResponse)
- file.close()
- return
- else return end
- end
- end
- local function checkForUpdate()
- local sCode = "R4ujbMuL"
- clear()
- printBorder()
- cPrint(6, "***********************")
- cPrint(7, "* Checking Version... *")
- cPrint(8, "***********************")
- while true do
- local response = http.get(
- "http://pastebin.com/raw.php?i="..textutils.urlEncode( sCode )
- )
- if response then
- local sResponse = response.readAll()
- response.close()
- if VERSION < tonumber(sResponse) then return tonumber(sResponse), true
- else return false end
- else return false end
- end
- end
- -- END Updating Functions --
- -- Networking functions (non file related) --
- function openExistantModem()
- local tSides = { "front", "back", "top", "bottom", "right", "left" } -- Reset to nil to free memory, if LUA doesn't garbage collect :P.
- for i=1, #tSides do
- if peripheral.isPresent( tSides[i] ) and peripheral.getType( tSides[i] ) == "modem" then
- rednet.open( tSides[i] ); tSides = nil; return true
- end
- end
- tSides = nil; return false
- end
- function closeExistantModem()
- local tSides = { "front", "back", "top", "bottom", "right", "left" } -- Reset to nil to free memory, if LUA doesn't garbage collect :P.
- for i=1, #tSides do
- if peripheral.isPresent( tSides[i] ) and peripheral.getType( tSides[i] ) == "modem" then
- rednet.close( tSides[i] ); tSides = nil; return true
- end
- end
- tSides = nil; return false
- end
- function respondToPing( id )
- sender, ping = rednet.receive( 0.5 )
- if sender == id and ping == "pingingYouFromServer" then rednet.send( id, "respondingToPingFromYou" ); return true
- else return false end
- end
- function connectToServer( id )
- rednet.send( id, "list!SP!" .. sCurrentLocationInServer )
- if respondToPing( id ) then
- os.startTimer( 1 )
- while true do
- event, param1, param2 = os.pullEvent()
- if event == "rednet_message" and param1 == id then
- t = split( param2, "!SP!" )
- tFilesInLocation[#tFilesInLocation+1] = { name = t[1], objType = t[2] }
- t = {}
- elseif event == "timer" then break end
- end
- nServerID = id
- bConnected = true
- return true
- else return false end
- end
- ---------------------------------------------
- -- Networking functions (file related) --
- function addDirectory( sName )
- rednet.send( nServerID, "addDir!SP!" .. sName .. "!SP!" .. sCurrentLocationInServer )
- return true
- end
- function changeLocation( sNewPath )
- rednet.send( nServerID, "list!SP!" .. sNewPath )
- if respondToPing( nServerID ) then
- tFilesInLocation = {}
- nSelect = 1
- sCurrentLocationInServer = sNewPath
- os.startTimer( 1 )
- while true do
- event, param1, param2 = os.pullEvent()
- if event == "rednet_message" and param1 == nServerID then
- t = split( param2, "!SP!" )
- tFilesInLocation[#tFilesInLocation+1] = { name = t[1], objType = t[2] }
- t = {}
- elseif event == "timer" then break end
- end
- return true
- else return false end
- end
- function downloadFile( sFileName )
- if bConnected then
- if fs.exists( "Files/" .. sFileName ) then return false end
- rednet.send( nServerID, "download!SP!" .. sFileName .. "!SP!" .. sCurrentLocationInServer )
- if respondToPing( nServerID ) then
- os.startTimer( 1 )
- while true do
- event, param1, param2 = os.pullEvent()
- if event == "rednet_message" and param1 == nServerID then
- local file = fs.open( "Files/" .. sFileName, "w" )
- file.write( param2 )
- file.close()
- return true
- elseif event == "timer" then return false end
- end
- else return false end
- else return false end
- end
- function uploadFile( sFileName, sPath )
- if bConnected then
- if not fs.exists( sFileName ) then return false end
- rednet.send( nServerID, "upload!SP!" .. sFileName .. "!SP!" .. sCurrentLocationInServer )
- if respondToPing( nServerID ) then
- local file = fs.open( sPath .. "/" .. sFileName, "r" )
- local fileContents = file.readAll()
- file.close()
- rednet.send( nServerID, fileContents )
- return true
- else return false end
- else return false end
- end
- function deleteFile( fileName )
- rednet.send( nServerID, "delete!SP!" .. fileName .. "!SP!" .. sCurrentLocationInServer )
- return true
- end
- -----------------------------------------
- -- Menues and displays --
- function removeLogFileFromList( t )
- for i=1, #t do
- if sCurrentLocationInServer == "/" and t[i].name == ".fileServerLog" then table.remove( t, i ); return true end
- end
- return false
- end
- function neutralizeROM( t )
- for i=1, #t do
- if sCurrentLocationInServer == "rom" then t[i].objType = "ROM"
- else return false end
- end
- return true
- end
- function displayFiles()
- if bConnected then
- local y = 3
- rPrint( 17, "Path: " .. sCurrentLocationInServer )
- removeLogFileFromList( tFilesInLocation ) -- Remove the log file from the table, just so we don't download it ;)
- neutralizeROM( tFilesInLocation ) -- Make it so we can't do anything to the ROM files.
- for i=1 + scroll, #tFilesInLocation do
- term.setCursorPos( 3, y )
- if nSelect == i then term.write( "[" .. tFilesInLocation[i].name .. "]" )
- else term.write( " " .. tFilesInLocation[i].name .. " " ) end
- term.setCursorPos( 40, y )
- if tFilesInLocation[i].objType == "F" then term.write( "File" )
- elseif tFilesInLocation[i].objType == "D" then term.write( "Dir." )
- elseif tFilesInLocation[i].objType == "ROM" then term.write( "ROM" ) end
- if scroll <= 0 and #tFilesInLocation > 13 then term.setCursorPos( 2, 17 ); term.write( "More..." ) end
- y = y+1
- if y == 16 then break end
- end
- else return end
- end
- function displayConnectToServer()
- local temp_ServerID = nil
- cPrint( 6, "*************" )
- cPrint( 7, "* Server ID *" )
- cPrint( 8, "*************" )
- cPrint(10, "ID: ")
- while not bConnected do
- term.setCursorPos( screenWidth/2 - string.len( "ID: " )/2 + 4, 10 )
- if temp_ServerID then string.rep( " ", string.len( temp_ServerID ) ); term.setCursorPos( screenWidth/2 - string.len( "ID: " )/2 + 4, 10 ) end
- temp_ServerID = limitRead( 12 )
- if not tonumber( temp_ServerID ) then
- cPrint( 13, "******************" )
- cPrint( 14, "* Not a valid ID *" )
- cPrint( 15, "******************" )
- sleep( 2 )
- for i=13, 16 do
- if i == 15 then break end
- cPrint( i, string.rep( " ", string.len( "**********************" ) ) )
- end
- else
- if connectToServer( tonumber( temp_ServerID ) ) then bConnected = true
- else
- cPrint( 13, "**********************" )
- cPrint( 14, "* Connection Failure *" )
- cPrint( 15, "**********************" )
- sleep( 2 )
- end
- end
- end
- end
- function uploadMenu() -- Requires path attached to file name.
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "Filename: " )
- term.setCursorPos( 2 + string.len( "Filename: " ), 16 )
- local temp_FileToUpload = limitRead( 14 )
- local posInString = string.find( temp_FileToUpload, fs.getName( temp_FileToUpload ) ) -- Get the position that the file path ends.
- local sPath = string.sub( temp_FileToUpload, 1, posInString - 1 ) -- Seperate the file path from the file name.
- if fs.exists( sPath .. ( fs.getName( temp_FileToUpload ) ) ) then
- if uploadFile( temp_FileToUpload, sPath ) then
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "Successfully uploaded." ); sleep( 2 )
- changeLocation( sCurrentLocationInServer ) -- Refresh the files on screen.
- bInFileMenu = false; return
- else
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "Upload failure." ); sleep( 2 )
- bInFileMenu = false; return
- end
- else
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "File does not exist." ); sleep( 2 )
- bInfileMenu = false; return
- end
- end
- function newDirMenu()
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "Dir name: " )
- term.setCursorPos( 2 + string.len( "Dir name: " ), 16 )
- local temp_DirToCreate = limitRead( 14 )
- if addDirectory( temp_DirToCreate ) then
- term.setCursorPos( 2, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 2, 16 ); term.write( "Attempted to create directory." ); sleep( 2 )
- changeLocation( sCurrentLocationInServer )
- return
- end
- end
- function fileMenu() -- Should probably get around to this lol.
- while bInFileMenu do
- term.setCursorPos( 3, 16 ); term.write(string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 3, 16 )
- if nSubSelect == 1 then term.write( "[ Download ] Delete" )
- elseif nSubSelect == 2 then term.write( " Download [ Delete ]" ) end
- event, key = os.pullEvent( "key" )
- if key == 203 and nSubSelect > 1 then nSubSelect = nSubSelect - 1
- elseif key == 205 and nSubSelect < 2 then nSubSelect = nSubSelect + 1
- elseif key == 28 then
- if nSubSelect == 1 then
- if downloadFile( tFilesInLocation[nSelect].name ) then
- term.setCursorPos( 3, 16 ); term.write( string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 3, 16 ); term.write( "Successfull download." ); sleep( 1.3 )
- bInFileMenu = false
- return
- else
- term.setCursorPos( 3, 16 ); term.write( string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 3, 16 ); term.write( "Failed download." ); sleep( 1.3 )
- bInFileMenu = false
- return
- end
- elseif nSubSelect == 2 then
- if deleteFile( tFilesInLocation[nSelect].name ) then
- term.setCursorPos( 3, 16 ); term.write( string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 3, 16 ); term.write( "Successfully deleted." ); sleep( 1.3 )
- changeLocation( sCurrentLocationInServer ) -- Refresh the files on screen.
- bInFileMenu = false
- return
- else
- term.setCursorPos( 3, 17 ); term.write( string.rep( " ", screenWidth-5 ))
- term.setCursorPos( 3, 17 ); term.write( "Failed deletion." ); sleep( 1.3 )
- bInFileMenu = false
- return
- end
- end
- elseif key == 14 then bInFileMenu = false; return end
- end
- end
- function handleDisplayInput( key ) -- Using the new 'keys' API
- if key == 208 and nSelect < #tFilesInLocation then
- if nSelect >= 13 and scroll < #tFilesInLocation then scroll = scroll+1; nSelect = nSelect+1
- else nSelect = nSelect+1 end
- elseif key == 200 and nSelect > 1 then
- if nSelect >= 13 and scroll > 0 then scroll = scroll-1; nSelect = nSelect-1
- else nSelect = nSelect-1 end
- elseif key == 28 then
- if tFilesInLocation[nSelect].objType == "D" then changeLocation( tFilesInLocation[nSelect].name )
- elseif tFilesInLocation[nSelect].objType == "F" then bInFileMenu = true; fileMenu() end
- elseif key == 14 and sCurrentLocationInServer ~= "/" then
- changeLocation( "/" )
- elseif key == 22 then uploadMenu() -- 'U'
- elseif key == 18 then bRunning = false
- elseif key == 32 then newDirMenu()
- end
- end
- -------------------------
- newVersion, bNeedsUpdate = checkForUpdate()
- if bNeedsUpdate then update( newVersion ); shell.run( "FILE_Client" ) end
- checkDirs()
- openExistantModem()
- while bRunning do -- Main loop
- clear()
- printBorder()
- if not bConnected then displayConnectToServer(); clear(); printBorder() end
- displayFiles()
- term.setCursorPos( 2, 16 ); term.write( "D - New Dir" )
- term.setCursorPos( 2, 17 ); term.write( "U - Upload | E - Exit" )
- event, key = os.pullEvent( "key" )
- if not bInFileMenu then handleDisplayInput( key )
- else fileMenu() end
- end
- closeExistantModem()
- clear()
- print( os.version() )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement