gravitowl

GraviMail Client

Mar 9th, 2021 (edited)
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.86 KB | None | 0 0
  1. -- GLOBALS
  2. local serverID = -1
  3. local side = "top"
  4. local myID = os.getComputerID()
  5. local template = "$SERVER$MAIL$EMAIL!ED!"
  6. local w, h = term.getSize()
  7.  
  8. local states = {
  9. ["home"] = {
  10. id = 1,
  11. options = 6
  12. },
  13. ["composeMail"] = {
  14. id = 2,
  15. options = 4
  16. },
  17. ["changeName"] = {
  18. id = 3,
  19. options = 3
  20. },
  21. ["hasMailBeenSent"] = {
  22. id = 4,
  23. options = 0
  24. },
  25. ["mails"] = {
  26. id = 5,
  27. options = 3
  28. },
  29. ["archive"] = {
  30. id = 6,
  31. options = 4
  32. }
  33. }
  34.  
  35. local state = 1
  36. local select = 1
  37.  
  38. local username = "New User"
  39. local newMail = {
  40. recipient = "",
  41. body = ""
  42. }
  43. local tempUN = ""
  44. local newMessages = 0
  45.  
  46. local accepted_chars = {
  47. 'zero','one','two','three','four','five','six','seven','eight','nine','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','space','comma'
  48. }
  49.  
  50. local mails = {}
  51. local archivedMails = {}
  52. if fs.exists("gravimail/client/archivedMails") then
  53. local file = fs.open("gravimail/client/archivedMails", "r")
  54. file = file.readAll()
  55. archivedMails = textutils.unserialise(file)
  56. end
  57. local currentMail = 1
  58.  
  59. -- Functions & Stuff
  60. function writeToFile(data, filename)
  61. local file = fs.open(filename, "w")
  62. file.write(textutils.serialise(data))
  63. file.close()
  64. end
  65.  
  66. function readFromFile(filename)
  67. if not fs.exists(filename) then
  68. return
  69. end
  70. local file = fs.open(filename, "r")
  71. local data = file.readAll()
  72. file.close()
  73. return data
  74. end
  75.  
  76. function split(str, pat)
  77. local t = { }
  78. local fpat = "(.-)"..pat
  79. local last_end = 1
  80. local s, e, cap = str:find(fpat, 1)
  81. while s do
  82. if s ~= 1 or cap ~= "" then
  83. table.insert(t,cap)
  84. end
  85. last_end = e+1
  86. s, e, cap = str:find(fpat, last_end)
  87. end
  88. if last_end <= #str then
  89. cap = str:sub(last_end)
  90. table.insert(t, cap)
  91. end
  92. return t
  93.  
  94. end
  95.  
  96. function includes(table, string)
  97. if #table < 1 then return false, -1 end
  98.  
  99. for i = 1, #table, 1 do
  100. if table[i] == string then return true, i end
  101. end
  102.  
  103. return false, -1
  104. end
  105.  
  106. function printCentered(text, y)
  107. term.setCursorPos(w/2 - #text/2, y)
  108. term.write(text)
  109. end
  110.  
  111. function sendMail(mail, username)
  112. local time = os.date("*t")
  113. local msg = template..mail.recipient.."!ED!"..username.."!ED!"..time.day.."!ED!"..time.month.."!ED!"..time.year.."!ED!"..time.hour.."!ED!"..time.min.."!ED!"..mail.body.."!ED!"
  114. rednet.open(side)
  115. rednet.send(serverID, msg)
  116. rednet.close()
  117. end
  118.  
  119. function refreshMails()
  120. currentMail = 1
  121. local msg = "$SERVER$MAIL$REQUEST!ED!"..myID.."!ED!EMAILS!ED!"
  122. rednet.open(side)
  123. rednet.send(serverID, msg)
  124. term.clear()
  125. printCentered("Requesting mails...", h/2)
  126. local id, message = rednet.receive(1)
  127. if message and string.find(message, "$RESPONSE") then
  128. message = string.gsub(message, "$RESPONSE", "")
  129. local newMails = split(message, "!NM!")
  130. for i, mail in pairs(newMails) do
  131. mailData = split(mail, "!ED!")
  132. table.insert(mails, mailData)
  133. term.clear()
  134. end
  135.  
  136. end
  137. newMessages = #mails
  138. rednet.close()
  139. end
  140.  
  141. function decodeKey(key)
  142. key = keys.getName(key)
  143. succes, index = includes(accepted_chars,key)
  144. if succes then
  145. if index <= 10 then
  146. return tostring(index - 1)
  147. elseif key == "space" then
  148. return " "
  149. elseif key == "comma" then
  150. return ","
  151. else
  152. return key
  153. end
  154. end
  155. return ""
  156. end
  157.  
  158. ---- UI
  159.  
  160. function printHeader(headerText)
  161. term.setCursorPos(1,1)
  162. print(string.rep("-", w))
  163. term.setCursorPos(w/2 - #headerText/2, 2)
  164. print(headerText)
  165. term.setCursorPos(1, 3)
  166. print(string.rep("-", w))
  167. end
  168.  
  169. function printHome()
  170. if select == 1 then
  171. printCentered("[ COMPOSE ]", 5)
  172. printCentered("CHANGE NAME", 6)
  173. printCentered(" MAILS ", 7)
  174. printCentered(" ARCHIVE ", 8)
  175. printCentered(" REFRESH ", 9)
  176. printCentered("LEAVE", 10)
  177. elseif select == 2 then
  178. printCentered("COMPOSE", 5)
  179. printCentered("[ CHANGE NAME ]", 6)
  180. printCentered("MAILS", 7)
  181. printCentered("ARCHIVE", 8)
  182. printCentered("REFRESH", 9)
  183. printCentered("LEAVE", 10)
  184. elseif select == 3 then
  185. printCentered("COMPOSE", 5)
  186. printCentered("CHANGE NAME", 6)
  187. printCentered("[ MAILS ]", 7)
  188. printCentered("ARCHIVE", 8)
  189. printCentered("REFRESH", 9)
  190. printCentered("LEAVE", 10)
  191. elseif select == 4 then
  192. printCentered("COMPOSE", 5)
  193. printCentered("CHANGE NAME", 6)
  194. printCentered("MAILS", 7)
  195. printCentered("[ ARCHIVE ]", 8)
  196. printCentered("REFRESH", 9)
  197. printCentered("LEAVE", 10)
  198. elseif select == 5 then
  199. printCentered("COMPOSE", 5)
  200. printCentered("CHANGE NAME", 6)
  201. printCentered("MAILS", 7)
  202. printCentered("ARCHIVE", 8)
  203. printCentered("[ REFRESH ]", 9)
  204. printCentered("LEAVE", 10)
  205. elseif select == 6 then
  206. printCentered("COMPOSE", 5)
  207. printCentered("CHANGE NAME", 6)
  208. printCentered("MAILS", 7)
  209. printCentered("ARCHIVE", 8)
  210. printCentered("REFRESH", 9)
  211. printCentered("[ LEAVE ]", 10)
  212. end
  213.  
  214. term.setCursorPos(1, h-1)
  215. term.write("Hi, "..username.."! Your ID: "..myID)
  216. term.setCursorPos(1, h)
  217. term.write("You have "..newMessages.." new messages!")
  218. end
  219.  
  220. function printCompose()
  221. term.setCursorPos(1, 5)
  222. term.write("TO: ")
  223. term.write(newMail.recipient)
  224. term.setCursorPos(1, 6)
  225. print("BODY: ")
  226. term.setCursorPos(1, 7)
  227. print(newMail.body)
  228.  
  229. if select == 1 then
  230. term.setCursorPos(10, h)
  231. term.write(" SEND ")
  232. term.setCursorPos(w - 10 - #" CANCEL ", h)
  233. term.write(" CANCEL ")
  234.  
  235. term.setCursorPos(#"TO: " + #newMail.recipient + 1, 5)
  236. term.setCursorBlink(true)
  237. elseif select == 2 then
  238. term.setCursorPos(10, h)
  239. term.write(" SEND ")
  240. term.setCursorPos(w - 10 - #" CANCEL ", h)
  241. term.write(" CANCEL ")
  242.  
  243. term.setCursorPos(#newMail.body + 1, 7)
  244. term.setCursorBlink(true)
  245. elseif select == 3 then
  246. term.setCursorPos(10, h)
  247. term.write("[ SEND ]")
  248. term.setCursorPos(w - 10 - #" CANCEL ", h)
  249. term.write(" CANCEL ")
  250. term.setCursorBlink(false)
  251. elseif select == 4 then
  252. term.setCursorPos(10, h)
  253. term.write(" SEND ")
  254. term.setCursorPos(w - 10 - #"[ CANCEL ]", h)
  255. term.write("[ CANCEL ]")
  256. term.setCursorBlink(false)
  257. end
  258. end
  259.  
  260. function printChangeName()
  261. term.setCursorPos(1, 5)
  262. term.write("NEW NAME:")
  263. term.setCursorPos(1, 8)
  264. term.write("(press enter to start typing)")
  265.  
  266. if select == 1 then
  267. term.setCursorPos(10, h)
  268. term.write(" CONFIRM ")
  269. term.setCursorPos(w - 10 - #" CANCEL ", h)
  270. term.write(" CANCEL ")
  271.  
  272. term.setCursorBlink(true)
  273. elseif select == 2 then
  274. term.setCursorPos(10, h)
  275. term.write("[ CONFIRM ]")
  276. term.setCursorPos(w - 10 - #" CANCEL ", h)
  277. term.write(" CANCEL ")
  278. term.setCursorBlink(false)
  279.  
  280. elseif select == 3 then
  281. term.setCursorPos(10, h)
  282. term.write(" CONFIRM ")
  283. term.setCursorPos(w - 10 - #"[ CANCEL ]", h)
  284. term.write("[ CANCEL ]")
  285. term.setCursorBlink(false)
  286.  
  287. end
  288.  
  289. term.setCursorPos(1, 6)
  290. print(tempUN)
  291. term.setCursorPos(#tempUN + 1, 6)
  292. end
  293.  
  294. function printHasMailBeenSent()
  295. printCentered("Mail has been sent!", h/2)
  296. end
  297.  
  298. function printMails()
  299. if #mails > 0 then
  300. local mail = mails[currentMail]
  301. term.setCursorPos(1,1)
  302. print("From: "..mail[2])
  303. term.setCursorPos(1, 2)
  304. print("Sent at: "..mail[3]..", "..mail[4])
  305. term.setCursorPos(1, 3)
  306. print(string.rep("-", 15))
  307. term.setCursorPos(1, 4)
  308. print(mail[5])
  309. else
  310. printCentered("No emails found.", h/2)
  311. end
  312.  
  313. if select == 1 then
  314. term.setCursorPos(w - #"[ CANCEL ]", 1)
  315. print("[ CANCEL ]")
  316. term.setCursorPos(3, h)
  317. term.write(" ARCHIVE ")
  318. term.setCursorPos(w - 3 - #" DELETE ", h)
  319. term.write(" DELETE ")
  320. elseif select == 2 then
  321. term.setCursorPos(w - #" CANCEL ", 1)
  322. print(" CANCEL ")
  323. term.setCursorPos(3, h)
  324. term.write(" ARCHIVE ")
  325. term.setCursorPos(w - 3 - #"[ DELETE ]", h)
  326. term.write("[ DELETE ]")
  327. elseif select == 3 then
  328. term.setCursorPos(w - #" CANCEL ", 1)
  329. print(" CANCEL ")
  330. term.setCursorPos(3, h)
  331. term.write("[ ARCHIVE ]")
  332. term.setCursorPos(w - 3 - #" DELETE ", h)
  333. term.write(" DELETE ")
  334. end
  335. end
  336.  
  337. function printArchive()
  338. if #archivedMails > 0 then
  339. local mail = archivedMails[currentMail]
  340. term.setCursorPos(1,1)
  341. print("From: "..mail[2])
  342. term.setCursorPos(1, 2)
  343. print("Sent at: "..mail[3]..", "..mail[4])
  344. term.setCursorPos(1, 3)
  345. print(string.rep("-", 15))
  346. term.setCursorPos(1, 4)
  347. print(mail[5])
  348. else
  349. printCentered("No emails found.", h/2)
  350. end
  351.  
  352. if select == 1 then
  353. term.setCursorPos(w - #"[ CANCEL ]", 1)
  354. print("[ CANCEL ]")
  355.  
  356. term.setCursorPos(w - 3 - #" NEXT ", h)
  357. term.write(" NEXT ")
  358.  
  359. printCentered("DELETE", h)
  360.  
  361. term.setCursorPos(3, h)
  362. term.write(" BACK ")
  363. elseif select == 2 then
  364. term.setCursorPos(w - #" CANCEL ", 1)
  365. print(" CANCEL ")
  366.  
  367. term.setCursorPos(w - 3 - #"[ NEXT ]", h)
  368. term.write("[ NEXT ]")
  369.  
  370. printCentered("DELETE", h)
  371.  
  372. term.setCursorPos(3, h)
  373. term.write(" BACK ")
  374. elseif select == 3 then
  375. term.setCursorPos(w - #" CANCEL ", 1)
  376. print(" CANCEL ")
  377.  
  378. term.setCursorPos(w - 3 - #" NEXT ", h)
  379. term.write(" NEXT ")
  380.  
  381. printCentered("[ DELETE ]", h)
  382.  
  383. term.setCursorPos(3, h)
  384. term.write(" BACK ")
  385. elseif select == 4 then
  386. term.setCursorPos(w - #" CANCEL ", 1)
  387. print(" CANCEL ")
  388.  
  389. term.setCursorPos(w - 3 - #" NEXT ", h)
  390. term.write(" NEXT ")
  391.  
  392. printCentered("DELETE", h)
  393.  
  394. term.setCursorPos(3, h)
  395. term.write("[ BACK ]")
  396. end
  397. end
  398.  
  399. function runUi()
  400. term.clear()
  401. while true do
  402. if state == states["home"].id then
  403. term.clear()
  404. printHeader("GRAVIMAIL CLIENT")
  405. printHome()
  406.  
  407. local e, key = os.pullEvent("key")
  408.  
  409. if key == keys.up and select > 1 then select = select - 1
  410. elseif key== keys.down and select < states["home"].options then select = select + 1
  411. elseif key== keys.enter then
  412. if select == 1 then
  413. state = 2
  414. select = 1
  415. elseif select == 2 then
  416. state = 3
  417. select = 1
  418. refreshMails()
  419. elseif select == 3 then
  420. state = 5
  421. select = 1
  422. elseif select == 4 then
  423. state = 6
  424. select = 1
  425. currentMail = 1
  426. elseif select == 5 then
  427. refreshMails()
  428. elseif select == 6 then
  429. term.clear()
  430. printCentered("Bye!", h/2)
  431. os.sleep(0.5)
  432. term.clear()
  433. term.setCursorPos(1, 1)
  434. return
  435. end
  436. end
  437.  
  438. elseif state == states["composeMail"].id then
  439. term.clear()
  440. printHeader("COMPOSE NEW MAIL")
  441. printCompose()
  442.  
  443. local e, key = os.pullEvent("key")
  444.  
  445. if key == keys.up and select > 1 then select = select - 1
  446. elseif key == keys.down and select < states["composeMail"].options then select = select + 1
  447. elseif key == keys.enter then
  448. if select == 3 then
  449. if newMail.recipient:gsub('%W','') ~= "" and newMail.body:gsub('%W','') ~= "" then
  450. sendMail(newMail,username)
  451. newMail.recipient = ""
  452. newMail.body = ""
  453. select = 1
  454. state = 4
  455. end
  456.  
  457. elseif select == 4 then
  458. state = 1
  459. select = 1
  460. end
  461. elseif select == 1 then
  462. local decodedKey = decodeKey(key)
  463. if tonumber(decodedKey) then
  464. newMail.recipient = newMail.recipient..decodeKey(key)
  465. end
  466.  
  467. if key == keys.backspace then
  468. newMail.recipient = string.sub(newMail.recipient, 1, #newMail.recipient - 1)
  469. end
  470. elseif select == 2 then
  471. newMail.body = newMail.body..decodeKey(key)
  472.  
  473. if key == keys.backspace then
  474. newMail.body = string.sub(newMail.body, 1, #newMail.body - 1)
  475. end
  476. end
  477.  
  478. elseif state == states["changeName"].id then
  479. term.clear()
  480. printHeader("CHANGE NAME")
  481. printChangeName()
  482.  
  483. local e, key = os.pullEvent("key")
  484.  
  485. if key == keys.up and select > 1 then select = select - 1
  486. elseif key == keys.down and select < states["changeName"].options then select = select + 1
  487. elseif key == keys.enter then
  488. if select == 1 then
  489. select = select + 1
  490.  
  491. elseif select == 2 then
  492. if tempUN:gsub('%W','') ~= "" then
  493. username = tempUN
  494. tempUN = ""
  495. state = 1
  496. select = 1
  497. end
  498.  
  499. elseif select == 3 then
  500. tempUN = ""
  501. state = 1
  502. select = 1
  503. end
  504. elseif select == 1 then
  505. tempUN = tempUN..decodeKey(key)
  506.  
  507. if key == keys.backspace then
  508. tempUN = string.sub(tempUN, 1, #tempUN - 1)
  509. end
  510. end
  511.  
  512. elseif state == states["hasMailBeenSent"].id then
  513. term.clear()
  514. printHasMailBeenSent()
  515. os.sleep(0.5)
  516. state = 1
  517.  
  518. elseif state == states["mails"].id then
  519. term.clear()
  520. printMails()
  521.  
  522. local e, key = os.pullEvent("key")
  523.  
  524. if key == keys.up and select > 1 then select = select - 1
  525. elseif key== keys.down and select < states["mails"].options then select = select + 1
  526. elseif key== keys.enter then
  527. if select == 1 then
  528. state = 1
  529. select = 1
  530.  
  531. elseif select == 2 then
  532. table.remove(mails, currentMail)
  533. newMessages = #mails
  534. if currentMail < #mails then
  535. currentMail = currentMail + 1
  536. elseif currentMail > 1 then
  537. currentMail = currentMail - 1
  538. end
  539. elseif select == 3 then
  540. table.insert(archivedMails, mails[currentMail])
  541. writeToFile(archivedMails, "gravimail/client/archivedMails")
  542. table.remove(mails, currentMail)
  543. newMessages = #mails
  544. if currentMail < #mails then
  545. currentMail = currentMail + 1
  546. elseif currentMail > 1 then
  547. currentMail = currentMail - 1
  548. end
  549. end
  550. end
  551. elseif state == states["archive"].id then
  552. term.clear()
  553. printArchive()
  554.  
  555. local e, key = os.pullEvent("key")
  556.  
  557. if key == keys.up and select > 1 then select = select - 1
  558. elseif key== keys.down and select < states["archive"].options then select = select + 1
  559. elseif key== keys.enter then
  560. if select == 1 then
  561. state = 1
  562. select = 1
  563.  
  564. elseif select == 2 then
  565. if currentMail < #archivedMails then
  566. currentMail = currentMail + 1
  567. end
  568. elseif select == 3 then
  569. table.remove(archivedMails, currentMail)
  570. writeToFile(archivedMails, "gravimail/client/archivedMails")
  571. if currentMail < #archivedMails then
  572. currentMail = currentMail + 1
  573. elseif currentMail > 1 then
  574. currentMail = currentMail - 1
  575. end
  576. elseif select == 4 then
  577. if currentMail > 1 then
  578. currentMail = currentMail - 1
  579. end
  580. end
  581. end
  582. end
  583. os.sleep(0.1)
  584. end
  585. end
  586.  
  587. --Rednet Logic
  588.  
  589. if not fs.exists("gravinet/client/pref") then
  590. error("No preferences setup. Make sure to run the connect script before running GraviNet apps!")
  591. return
  592. end
  593.  
  594. local prefs = fs.open("gravinet/client/pref", "r")
  595. prefs = prefs.readAll()
  596. prefs = textutils.unserialise(prefs)
  597. serverID = prefs.routerId
  598. side = prefs.side
  599.  
  600. runUi()
Add Comment
Please, Sign In to add comment