Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Gmail-Client PaymentOption
- Google on BlackWolfCC
- 23 November 2012
- Mail client script to correspond allow users
- to send mail to a server and thus to other
- clients with file attachments. Unreceived
- mail due to inactivity will be stored in the
- server and will be resent every ten seconds if
- the proper confirmation message is not sent to
- the server.
- Current Version: 24 November 2012: Incomplete menu system. Spaghetti
- coded some of the menus and their
- corresponding drawing functions.
- Networking system modified to send
- messages as their table bodies as
- opposed to strings.
- Basic Model:
- - Client -> Server -> Receiver -> Server(Confirmation)
- -> Client(Confirmation) or Stored to resend until
- confirmation received.
- Message Model:
- {sender = (number), receiver = (number),
- message = (table), subject = (string),
- attachment = {code = (string)}}
- - Attachments will only be sent if the attachment table
- exists within the message table provided.
- - The whole message will be in a table, and therefore
- will be serialized and unserialized upon sending and
- receiving.
- ]]--
- -- Variables --
- local serverID = 0 -- The computer from which we will send and receive mail from.
- local receivedMailDirectory = "Gmail-Client/Received_Mail" -- The location in
- -- which received mail
- -- is stored.
- local screenWidth, screenHeight = term.getSize() -- The x and y dimensions of the
- -- screen we are currently on.
- local confirmationFormat = "ConfirmedReception" -- The message that must be
- -- sent to the server to
- -- confirm a successful message
- -- send.
- -- Variables --
- -- Rednet Functions --
- -- Opens or close any modem found on this computer. An error is thrown if
- -- no modem on the computer was found.
- -- Params : open - A boolean value that determines whehter or not the modem is
- -- opened or closed.
- -- Returns: nil
- function openOrCloseModem(open)
- for sideIndex, side in pairs(rs.getSides()) do
- if peripheral.isPresent(side) and peripheral.getType(side) == "modem" then
- if open then
- rednet.open(side)
- else
- rednet.close(side)
- end
- return
- end
- end
- error("No modem found. Aborting.")
- end
- -- Sends a mail message to the server in a serialized table format.
- -- Params : receiverID - The receiver for this message.
- -- subjectString - The subject for the message.
- -- messageString - The contents of the message.
- -- attachmentString - The contents of a file to send as an attachment.
- -- Returns: nil
- function sendMailMessage(receiverID, subjectString, messageLines, attachmentString)
- local attachment = nil
- if attachmentString then
- attachment = {code = attachmentString}
- end
- local unserializedMessage = {sender = os.getComputerID(), receiver = receiverID, message = messageLines, subject = subjectString,
- attachment}
- --if unserializedMessage.sender == os.getComputerID() then os.shutdown() end
- local serializedMessage = textutils.serialize(unserializedMessage)
- rednet.send(serverID, serializedMessage)
- end
- -- Rednet Functions --
- -- File Functions --
- -- Saves the given message in its SERIALIZED format into the saved messages
- -- directory with the format: <sender>_<subject>_#ofTimesRepeated
- -- with #ofTimesRepeated being the number of times that the same message
- -- appears in the saved messages directory. However, when the list of messages
- -- is displayed, the messages will not be listed differently, but they will
- -- be separate entities.
- -- Params : serializedMessage - The string version of the message that has
- -- been serialized.
- -- Returns: nil
- function saveSerializedMessage(serializedMessage)
- -- Respond to the server with a confirmation message.
- rednet.send(serverID, confirmationFormat)
- -- Get the number of times the message has been repeated in the saved
- -- messages directory.
- local unserializedMessage = textutils.unserialize(serializedMessage)
- local newSavedMessageName = unserializedMessage.sender .. '_' .. unserializedMessage.subject
- newSavedMessageName = newSavedMessageName .. '_' .. getNumberOfTimesFileAppearsInDirectory(receivedMailDirectory, newSavedMessageName)
- -- Get a file handle for the new saved message, then write the serialized
- -- message to aforementioned file and close the handle.
- local fileHandle = fs.open(receivedMailDirectory .. '/' .. newSavedMessageName, 'w')
- fileHandle.write(serializedMessage)
- fileHandle.close()
- end
- -- Loads the message with the given path into an unserialized form and returns it.
- -- Params : messageName - The name of the message in the saved messages directory;
- -- NOT THE PATH!
- -- Returns: nil
- function loadMessageFromSavedMessagesDirectory(messageName)
- local fileHandle = fs.open(receivedMailDirectory .. '/' .. messageName)
- local unserializedMessage = textutils.unserialize(fileHandle.readAll())
- fileHandle.close()
- return unserializedMessage
- end
- -- Checks the amount of times the same file name appears in a directory.
- -- Params : directory, fileName - The directory and file name to check.
- -- Returns: timesAppeared - The number of times the same file name appears.
- function getNumberOfTimesFileAppearsInDirectory(directory, fileName)
- local timesAppeared = 0
- for index, item in pairs(fs.list(directory)) do
- if item:find(fileName) then
- timesAppeared = timesAppeared + 1
- end
- end
- return timesAppeared
- end
- -- File Functions --
- -- Input Functions --
- -- Gets input on the line given and will display the input typed until
- -- the character length given. Upon reaching the character limit, the function
- -- will proceed to scroll the input to the right. No cursor movement back
- -- and forth within the input line is supportted.
- -- This function also handles rednet messages that are received during input.
- -- Params : xPos, yPos - The x and y coordinates to begin grabbing input.
- -- charachterLimit - The number of characters that can be entered
- -- before the function will begin scrolling.
- -- currentLine - The line to start with in the case that you want
- -- to edit a string.
- -- Returns: line - The string of input entered.
- function getInputAtPosAndScrollRight(xPos, yPos, characterLimit, currentLine)
- term.setCursorBlink(true)
- local scroll = 0
- local line = tostring(currentLine) or ""
- local function redraw()
- term.setCursorPos(xPos, yPos)
- term.write(string.rep(' ', line:len() + 1))
- term.setCursorPos(xPos, yPos)
- if line:len() - 1 > characterLimit then
- scroll = line:len() - characterLimit
- term.write(line:sub(scroll, line:len()))
- return
- end
- term.write(line)
- end
- -- Main input loop.
- while true do
- redraw()
- local event, key, p2, p3 = os.pullEvent()
- -- If the event was a character typed, then add the character
- -- typed to the input string.
- if event == "char" then
- line = line .. key
- elseif event == "key" then
- -- If the enter key was pressed, then
- -- return the string retrieved from the user.
- if key == keys.enter then
- term.setCursorBlink(false)
- return line
- -- If the backspace key was pressed, then back up the
- -- input line by 1 charachter via substring.
- elseif key == keys.backspace then
- line = line:sub(1, line:len() - 1)
- end
- -- If the event was a message and it was from the server, then
- -- handle it as a serialized mail message.
- elseif event == "rednet_message" and key == serverID then
- saveSerializedMessage(p2)
- end
- end
- end
- -- Gets input over multiple lines. Uses a table to store the input at each line.
- -- The input is scrollable so more than the selected amount of lines can be
- -- written. However, only a certain amount of characters is limited per line;
- -- if this limit is reached the cursor will not reset, but the user will just
- -- not be permitted input any more text without jumping to the next line.
- -- This function also handles rednet messages that are received during input.
- -- Params : xPos, yPos - The x and y coordinates to begin getting input at.
- -- maxLines - The maximum number of lines to be typed before the
- -- screen will begin scrolling.
- -- lines - The lines to edit if you do not want to have an empty input.
- -- Returns: lines - The table of lines that are retrieved via input.
- function getInputAtPosInLines(xPos, yPos, maxLines, lines)
- term.setCursorBlink(true)
- local maxLines = maxLines or screenHeight
- local lines = lines or {""} -- The table that will contain all of the lines retrieved.
- local currentLine = 1 -- The current line that we are on in the liens table.
- local maxLineLength = screenWidth - (xPos + 1) -- The maximum amount of characters
- -- that can be on one line.
- local scroll = 0 -- The offset of the lines to be displayed.
- -- Redraws all of the text from the xPos and yPos using a loop to
- -- draw each of the lines on a separate line.
- local function redrawLines()
- -- Clear the space allotted.
- for line = yPos, maxLines + yPos do
- term.setCursorPos(xPos, line)
- term.write(string.rep(' ', maxLineLength))
- end
- -- If the amount of lines is greater than can be displayed, then
- -- scroll the screen.
- if #lines - maxLines > 0 then
- scroll = #lines - maxLines
- end
- -- If the current line is not greater than the screen, the we
- -- don't need to scroll it.
- if currentLine <= maxLines then
- scroll = 0
- end
- for index = 1 + scroll, #lines do
- term.setCursorPos(xPos, index - scroll + yPos - 1)
- term.write(lines[index])
- end
- end
- -- Main loop
- while true do
- -- Redraw the current input and position the cursor properly.
- redrawLines()
- term.setCursorPos(lines[currentLine]:len() + xPos, currentLine - scroll + yPos - 1)
- local event, key = os.pullEvent()
- -- If the event pulled was a character, then simply add the character
- -- typed to the end of the current line.
- if event == "char" then
- -- Make sure the current line doesn't already have the
- -- maximum amount of characters in it.
- if lines[currentLine]:len() < maxLineLength then
- lines[currentLine] = lines[currentLine] .. key
- end
- elseif event == "key" then
- -- Enter.
- if key == keys["return"] then
- -- If the enter key was pressed, then insert a blank line
- -- into the current line if there are lines below the
- -- current one.
- if currentLine < #lines then
- table.insert(lines, currentLine + 1, "")
- currentLine = currentLine + 1
- -- However, if the enter key was pressed and there are
- -- no lines below this one, then jump to the next line
- -- and make a new line in the lines table.
- else
- table.insert(lines, "")
- currentLine = currentLine + 1
- end
- -- If the backspace key was pressed, then get a substring
- -- of the current line with the ending character chopped off,
- -- then make that substring the actual line.
- elseif key == keys["backspace"] then
- -- If the current line has no more characters in it, then delete the
- -- current line and back up the line once.
- if lines[currentLine]:len() == 0 and currentLine > 1 then
- table.remove(lines, currentLine)
- currentLine = currentLine - 1
- else
- lines[currentLine] = lines[currentLine]:sub(1, lines[currentLine]:len() - 1)
- end
- -- Up key.
- elseif key == keys["up"] then
- -- If we're not on the first line, then bump up the
- -- current line by one line.
- if currentLine > 1 then
- currentLine = currentLine - 1
- end
- -- Down key.
- elseif key == keys["down"] then
- -- If we're not on the last line, then bump down the
- -- current line by one line.
- if currentLine < #lines then
- currentLine = currentLine + 1
- end
- -- If the end key was pressed, then return the current lines.
- elseif key == keys["end"] then
- term.setCursorBlink(false)
- return lines
- end
- end
- end
- end
- -- Sets the current serverID for the script.
- -- Params : newServerID - The new ID for the server to be set as.
- -- Returns: nil
- function setServerID(newServerID)
- serverID = newServerID
- end
- -- Input Functions --
- -- UI Functions --
- -- Clears the screen with the given color. If no color is provided, then black
- -- will be used instead.
- -- Params : color - The color to clear the screen with.
- -- Returns: nil
- function clearScreen(color)
- term.setBackgroundColor(color or colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- end
- -- Gets a new serverID from the user to receive mail from.
- -- Params : nil
- -- Returns: nil
- function getNewServerID()
- local item = {label = "Change Server", xPos = 1, yPos = 7, associatedFunction = getNewServerID, centered = true, color = colors.blue}
- local xPos = screenWidth/2 - item.label:len()/2
- term.setCursorPos(xPos, item.yPos)
- term.write(string.rep(' ', item.label:len()))
- term.setTextColor(colors.orange)
- local newServerID = getInputAtPosAndScrollRight(xPos, item.yPos, item.label:len())
- newServerID = tonumber(newServerID)
- -- Make sure the new serverID entered was a valid number.
- if type(newServerID) == "number" then
- setServerID(newServerID)
- end
- end
- -- Prints the current serverID that this computer is connected to. If no
- -- position is provided, then this information will be printed in the bottom
- -- right hand corner of the screen.
- -- Params : xPos, yPos - The x and y coordinates for this information to be drawn.
- -- Returns: nil
- function printCurrentServerID(xPos, yPos)
- local serverInfo = tostring(serverID)
- if serverInfo:len() > 4 then
- serverInfo = "Server: " .. serverInfo:sub(1, 1) .. "..."
- else
- serverInfo = "Server: " .. serverInfo
- end
- if not xPos and not yPos then
- xPos = screenWidth - serverInfo:len() + 1
- yPos = screenHeight
- end
- term.setCursorPos(xPos, yPos)
- term.setTextColor(colors.red)
- term.write(serverInfo)
- end
- -- Prints the amount of mail in the saved mail directory. This acts as a similar
- -- method of displaying the amount of unread mail. However, whether or not
- -- the mail was read is not taken into account when displaying this information.
- -- If no position is provided, then htis information will be displayed in the
- -- lower left hand corner of the screen.
- -- Params : xPos, yPos - The x and y coordinates for this information to be drawn.
- -- Returns: nil
- function printNumberOfMessagesInMailDirectory(xPos, yPos)
- if not xPos and not yPos then
- xPos = 1
- yPos = screenHeight
- end
- term.setCursorPos(xPos, yPos)
- term.setTextColor(colors.red)
- term.write("Mail: " .. #fs.list(receivedMailDirectory))
- end
- -- Prints the google logo to the position located. If no position was
- -- provided, then it will default to the top center of the screen.
- -- Params : xPos, yPos - The x and y coordinates for the logo to be drawn.
- -- Returns: nil
- function printLogo(xPos, yPos)
- if not xPos and not yPos then
- xPos = screenWidth/2 - ("Google"):len()/2
- yPos = 1
- end
- term.setCursorPos(xPos, yPos)
- local logoColors = {colors.blue, colors.red, colors.yellow, colors.blue,
- colors.green, colors.red} -- The colors for the logo
- -- that we're printing.
- local logo = "Google" -- The logo to be printed.
- for index = 1, logo:len() do
- term.setTextColor(logoColors[index])
- term.write(logo:sub(index, index))
- end
- end
- -- Prints the Gmail-Client title to the top of the screen at the given coordinates,
- -- or the center of the screen on line two by default.
- -- Params : xPos, yPos - The x and y coordinates of the title to be drawn.
- -- Returns: nil
- function printTitle(xPos, yPos)
- if not xPos and not yPos then
- xPos = screenWidth/2 - ("Gmail-Client"):len()/2
- yPos = 2
- end
- term.setCursorPos(xPos, yPos)
- local titleColors = {colors.blue, colors.red, colors.yellow, colors.blue,
- colors.green, colors.red, colors.blue, colors.red,
- colors.yellow, colors.blue, colors.green, colors.red}
- -- The colors for the title to be printed.
- local title = "Gmail-Client"
- for index = 1, title:len() do
- term.setTextColor(titleColors[index])
- term.write(title:sub(index, index))
- end
- end
- -- Prints the current time in the Minecraft world. By default, however, this
- -- information will be written at the bottom right of the screen.
- -- Params : xPos, yPos - The x and y coordinates for this information to be
- -- drawn at.
- -- Returns: nil
- function printCurrentTimeInMinecraft(xPos, yPos)
- local time = textutils.formatTime(os.time(), true)
- if not xPos and not yPos then
- xPos = screenWidth/2 - ("Current Time: " .. time):len()/2
- yPos = screenHeight
- end
- term.setCursorPos(xPos, yPos)
- term.write("Current Time: " .. time)
- end
- -- Draws the menu table given. Each entry in a menu table should have the
- -- following format:
- -- menu[n] = {label = (string), xPos = (number), yPos = (number), associatedFunction = (function), centered = (boolean), color = (number)}.
- -- Colors MUST be assigned to each entry or else the function will throw an error.
- -- Params : menu - The menu table to be drawn.
- -- Returns: nil
- function drawMenu(menu)
- for index, item in ipairs(menu) do
- if item.centered then
- term.setCursorPos(screenWidth/2 - item.label:len()/2, item.yPos)
- else
- term.setCursorPos(item.xPos, item.yPos)
- end
- term.setTextColor(item.color)
- term.write(item.label)
- end
- end
- -- Handles and prints the main screen for the client. This includes drawing
- -- the main screen and handling clicking of the interface.
- -- Params : nil
- -- Returns: nil
- function drawAndHandleMainScreen()
- local mainMenuTable = { -- The main menu screen for the client script.
- [1] = {label = "Compose Mail", xPos = 1, yPos = 5, associatedFunction = drawAndHandleComposeMailScreen, centered = true, color = colors.green},
- [2] = {label = "Read Mail", xPos = 1, yPos = 6, associatedFunction = drawAndHandleReadScreen, centered = true, color = colors.red},
- [3] = {label = "Change Server", xPos = 1, yPos = 7, associatedFunction = getNewServerID, centered = true, color = colors.blue},
- [4] = {label = "Exit", xPos = 1, yPos = 8, associatedFunction = exitProgram, centered = true, color = colors.yellow}
- }
- -- Draw the menu and all of the extra information to go along with it.
- while true do
- clearScreen(colors.white)
- printLogo()
- printTitle()
- printCurrentTimeInMinecraft()
- printNumberOfMessagesInMailDirectory()
- printCurrentServerID()
- drawMenu(mainMenuTable)
- local updateTimer = os.startTimer(1) -- The amount of time before
- -- the next screen update.
- local event, incomingID, incomingSerializedMessage, p3 = os.pullEvent()
- -- If the event triggered was a mouse click, then handle the click
- -- accordingly by executing the function associated with the item clicked.
- if event == "mouse_click" then
- for index, item in ipairs(mainMenuTable) do
- local item_xPos = (item.centered == true) and (screenWidth/2 - item.label:len()/2) or item.xPos
- if checkIfClickWasOnTextAtPos(incomingSerializedMessage, p3, item_xPos, item.yPos, item.label) then
- if item.associatedFunction and item.associatedFunction() == false then
- -- Exit the program because the
- -- only function that will return
- -- a value in the main screen
- -- will be false by the exit
- -- option.
- return false
- end
- end
- end
- -- If the event was a rednet message, then send a confirmation
- -- message to the server, then store the message in
- -- the saved messages directory, then alert the user that a
- -- message was received.
- elseif event == "rednet_message" and incomingID == serverID then
- saveSerializedMessage(incomingSerializedMessage)
- end
- end
- end
- -- Prints the receiver field for the compose mail screen where the user can
- -- enter a receiver to send a mail message to.
- -- Params : nil
- -- Returns: nil
- function printReceiverFieldForComposeMailScreen(receiverID, fieldWidth)
- if receiverID and tostring(receiverID):len() > fieldWidth then
- receiverID = tostring(receiverID):sub(1, fieldWidth - 3) .. "..."
- end
- term.setCursorPos(2, 3)
- term.setTextColor(colors.red)
- term.write("Send To : " .. ((receiverID) and receiverID or ""))
- term.setCursorPos(2, 4)
- term.setBackgroundColor(colors.lightGray)
- term.write(string.rep(' ', screenWidth - 3))
- term.setBackgroundColor(colors.white)
- end
- -- Prints the subject field for the compose mail screen where the user can
- -- enter a subject for their mail message.
- -- Params : nil
- -- Returns: nil
- function printSubjectFieldForComposeMailScreen(subject, fieldWidth)
- if subject and subject:len() > fieldWidth then
- subject = subject:sub(1, fieldWidth - 3) .. "..."
- end
- term.setCursorPos(2, 5)
- term.setTextColor(colors.red)
- term.write("Subject : " .. ((subject) and subject or ""))
- term.setCursorPos(2, 6)
- term.setBackgroundColor(colors.lightGray)
- term.write(string.rep(' ', screenWidth - 3))
- term.setBackgroundColor(colors.white)
- end
- -- Prints the attachment field for the compose mail screen where the user can
- -- enter a path to a file that they would like to attach to their mail message.
- -- Params : nil
- -- Returns: nil
- function printAttachmentFieldForComposeMailScreen(attachmentPath, fieldWidth)
- if attachmentPath and attachmentPath:len() > fieldWidth then
- attachmentPath = attachmentPath:sub(1, fieldWidth - 3) .. "..."
- end
- term.setCursorPos(2, 7)
- term.setTextColor(colors.red)
- term.write("Attachment: " .. ((attachmentPath) and attachmentPath or ""))
- term.setCursorPos(2, 8)
- term.setBackgroundColor(colors.lightGray)
- term.write(string.rep(' ', screenWidth - 3))
- term.setBackgroundColor(colors.white)
- end
- -- Prints the body field for the compose mail screen where the user can enter
- -- a body for their mail message.
- -- Params : nil
- -- Returns: nil
- function printBodyFieldForComposeMailScreen(body)
- term.setCursorPos(2, 9)
- term.setTextColor(colors.red)
- term.write("Body (Below):")
- term.setCursorPos(1, 10)
- term.setBackgroundColor(colors.lightGray)
- term.write(string.rep(' ', screenWidth))
- for line = 11, screenHeight - 1 do
- term.setCursorPos(1, line)
- term.write(' ')
- term.setCursorPos(screenWidth, line)
- term.write(' ')
- end
- term.setCursorPos(1, screenHeight)
- term.write(" Exit | END to Stop Writing | ENTER to Send" .. string.rep(' ', screenWidth - (" Exit | END to Stop Writing | ENTER to Send"):len()))
- term.setTextColor(colors.red)
- term.setBackgroundColor(colors.white)
- local maxLinesToBeDrawn = 1 -- The maximum number of lines from the body
- -- table that should be drawn.
- -- If the body is too large to fit the box, then only draw enough of
- -- the body to fit the box.
- if #body + 10 > screenHeight - 1 then
- maxLinesToBeDrawn = 8
- elseif #body > 0 then
- maxLinesToBeDrawn = #body
- end
- for index = 1, maxLinesToBeDrawn do
- term.setCursorPos(2, 11 + (index - 1))
- term.write(body[index])
- end
- end
- -- Handles and prints the compose mail screen for the client. This includes
- -- drawing the compose mail screen and handling clicking and typing in the
- -- interface.
- -- Params : nil
- -- Returns: nil
- function drawAndHandleComposeMailScreen()
- local body = {""}
- local receiverID = 0
- local subject = ""
- local attachmentPath = ""
- local fieldWidth = screenWidth - (" Send To : "):len() - 1
- while true do
- clearScreen(colors.white)
- printLogo()
- printTitle()
- printReceiverFieldForComposeMailScreen(receiverID, fieldWidth)
- printSubjectFieldForComposeMailScreen(subject, fieldWidth)
- printAttachmentFieldForComposeMailScreen(attachmentPath, fieldWidth)
- printBodyFieldForComposeMailScreen(body)
- local event, button, xClickPos, yClickPos = os.pullEvent()
- -- Handle incoming mail messages in the case we receive one
- -- whilst on this screen.
- if event == "rednet_message" and button == serverID then
- saveSerializedMessage(xClickPos)
- -- Handle mouse clicks by directing the user to type in the
- -- proper field.
- elseif event == "mouse_click" then
- -- Make sure the user did not click on the EXIT button at
- -- the bottom of the screen.
- if checkIfClickWasOnTextAtPos(xClickPos, yClickPos, 2, screenHeight, "EXIT") then
- return
- -- If the user clicked on the SEND TO field, then allow the
- -- user to type in the SEND TO line.
- elseif checkIfClickWasOnTextAtPos(xClickPos, yClickPos, (" Send To : "):len(), 3, string.rep(' ', fieldWidth)) then
- local tempReceiverID = getInputAtPosAndScrollRight((" Send To : "):len() + 1, 3, fieldWidth - 3, receiverID)
- tempReceiverID = tonumber(tempReceiverID)
- if type(tempReceiverID) == "number" then
- receiverID = tempReceiverID
- end
- -- If the user clicked on the SUBJECT field, then allow
- -- the user to type in the SUBJECT line. Since all
- -- of the fields are of the same width, we can reuse the
- -- previous line and simply changing the y coordinate.
- elseif checkIfClickWasOnTextAtPos(xClickPos, yClickPos, (" Send To : "):len(), 5, string.rep(' ', fieldWidth)) then
- subject = getInputAtPosAndScrollRight((" Send To : "):len() + 1, 5, fieldWidth - 3, subject)
- -- If the user clicked on the ATTACHMENT field, then allow
- -- the user to type in the ATTACHMENT line. All of these
- -- fields can reuse the same click logic with a slight change
- -- to the yCoordinate of the line clicked.
- elseif checkIfClickWasOnTextAtPos(xClickPos, yClickPos, (" Send To : "):len(), 7, string.rep(' ', fieldWidth)) then
- attachmentPath = getInputAtPosAndScrollRight((" Send To : "):len() + 1, 7, fieldWidth - 3, attachmentPath)
- if not fs.exists(attachmentPath) or fs.isDir(attachmentPath) then
- attachmentPath = "Invalid attachment path."
- end
- -- If the user clicked on any line in the body, then go ahead
- -- and allow the user to edit the body of the message.
- else
- for line = 11, screenHeight - 1 do
- if xClickPos >= 2 and xClickPos <= screenWidth - 1 and yClickPos == line then
- body = getInputAtPosInLines(2, 11, screenHeight - 12, body)
- end
- end
- end
- -- Handle key events.
- elseif event == "key" then
- -- If the key was enter, then package up the message and send it.
- local attachmentString = nil
- if attachmentPath ~= "Invalid attachment path." and attachmentPath ~= "" then
- local fileHandle = fs.open(attachmentPath, 'r')
- local attachmentString = fileHandle.readAll()
- fileHandle.close()
- end
- -- Send the message.
- sendMailMessage(receiverID, subject, body, attachmentString)
- end
- end
- end
- -- Exits the program and returns the terminal to a normal and useable state.
- -- Params : nil
- -- Returns: false
- function exitProgram()
- return false
- end
- -- UI Functions --
- -- Click Functions --
- -- Checks if the click at the given position is on top of the text at another
- -- given position provided.
- -- Params : xClickPos, yClickPos - The x and y coordinates of the click.
- -- xTextPos, yTextPos - The x and y coordinates of the text.
- -- text - The text to be checked for clicks on.
- -- Returns: true or false - Whether or not the click was on the text provided.
- function checkIfClickWasOnTextAtPos(xClickPos, yClickPos, xTextPos, yTextPos, text)
- if xClickPos >= xTextPos and xClickPos <= xTextPos + text:len() then
- if yClickPos == yTextPos then
- return true
- end
- end
- return false
- end
- -- Click Functions --
- -- Main Loop -------------------------------------------------------------------
- -- Setup all of the proper directories for the script to function properly.
- if not fs.isDir(receivedMailDirectory) then
- fs.makeDir(receivedMailDirectory)
- end
- openOrCloseModem(true)
- while true do
- -- If the main screen function returns false, then we need to exit the
- -- script and return to the shell.
- if not drawAndHandleMainScreen() then
- openOrCloseModem(false)
- clearScreen(colors.black)
- term.setTextColor(colors.yellow)
- print(os.version())
- return
- end
- end
- --------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment