Advertisement
BeminLP

Computercraft Mailingsystem - DEV/BETA [UPDATE 4]

Jun 4th, 2016
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.70 KB | None | 0 0
  1. --It is currently possible to transfer messages over about 128 blocks between 2 computers by setting up a mail-server in the middle
  2. --Each Node (Server and Client need any type of network modem
  3.  
  4. --The code may not be the prettiest of codes and also not one of the most efficient ones but it currently works really smoothly
  5.  
  6. --THIS PROGRAM IS STILL UNDER DEVELOPMENT AND MAY GET SOME UPDATES UNTIL THE FINAL VERSION
  7.  
  8.  
  9.  
  10. -- local variables --------- local variables --------- local variables --------- local variables --
  11. local modem = nil
  12. local tArgs = { ... }
  13.  
  14. local cl_modemside, cl_type
  15. local key = nil
  16.  
  17. local username, password
  18.  
  19. local prt_transmit = 1912
  20. local prt_receive = 1997
  21.  
  22.  
  23.  
  24. -- functions ---- functions ---- functions ---- functions ---- functions ---- functions ---- functions --
  25. function getModemSides()
  26.  
  27.     local mc = 0
  28.     local modemlist = {}
  29.     local sides = rs.getSides()
  30.    
  31.     for i=1,6 do
  32.         if peripheral.getType(sides[i]) == "modem" then
  33.             mc = mc + 1
  34.             modemlist[mc] = sides[i]
  35.         end
  36.     end
  37.     return(modemlist)
  38.    
  39. end
  40.  
  41. function clear()
  42.     shell.run("clear");
  43. end
  44.  
  45. function getModemToRun(cm)
  46.    
  47.     if table.getn(cm) == 0 then
  48.         clear()
  49.         print("There is no modem connected to this device!")
  50.         error()
  51.     elseif table.getn(cm) > 1 then
  52.         repeat
  53.             clear()
  54.             print("===================================================")
  55.             print("=                      SETUP                      =")
  56.             print("===================================================")
  57.             print()
  58.             print("You have multipe modems connected")
  59.             print("Connected modems:")
  60.             for i=1,table.getn(cm) do
  61.                 print(i .. ": " .. cm[i])  
  62.             end
  63.             local answer=tonumber(read())
  64.         until answer ~= nil and answer > 0 and answer <= table.getn(cm)
  65.         return answer
  66.     end
  67.     return 1
  68. end
  69.  
  70. function genKey(length)
  71.     length = tonumber(length)
  72.     if length == nil or length < 1 then
  73.         length = 1
  74.     end
  75.     local value = ""
  76.     local hex_values = {"0","1","2","3","4","5","6","7","8","9","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"}
  77.     for i=1,length do
  78.         value = value .. hex_values[math.floor(math.random()*36)+1]
  79.     end
  80.     return value
  81. end
  82.  
  83. function writeConfig()
  84.    
  85.     local h = fs.open("config/mail.cfg", "w")
  86.    
  87.     h.writeLine(cl_modemside)
  88.     h.writeLine(cl_type)
  89.    
  90.     h.close()
  91.    
  92. end
  93.  
  94. function transmit(data)
  95.     modem.transmit(prt_transmit, prt_receive, textutils.serialize(data))
  96. end
  97.  
  98. function receive()
  99.     modem.open(prt_transmit)
  100.     local timeout = os.startTimer(2)
  101.     while true do
  102.         event = {os.pullEvent()}
  103.         if event[1] == "modem_message" then
  104.             modem.close(prt_transmit)
  105.             return textutils.unserialize(event[5])         
  106.         elseif event[1] == "timer" and event[2] == timeout then
  107.             return {""}
  108.         end
  109.     end
  110. end
  111.  
  112. function login()
  113.     print("Username: ")
  114.     user=read()
  115.     print("Password: ")
  116.     pass=read("*")
  117.     return user, pass
  118. end
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125. -- code --------- code --------- code --------- code --------- code --------- code --------- code --------- code --
  126.  
  127. if tostring(tArgs[1]) == "?" then
  128.     print("This program is a mailing-software. Running this program the first time will start the installation-wizzard.")
  129.    
  130.     print()
  131.     print(" -r    will reinstall the program")
  132.     error()
  133. elseif tostring(tArgs[1]) == "-r" then
  134.    
  135.     if fs.exists("config/mail.cfg") then
  136.         shell.run("rm config/mail.cfg")
  137.         shell.run("rm mailserver")
  138.         shell.run("rm startup")
  139.     end
  140. end
  141.  
  142. if fs.exists("config/mail.cfg") then
  143.        
  144.     local h = fs.open("config/mail.cfg", "r")
  145.    
  146.     cl_modemside = h.readLine();
  147.     cl_type = h.readLine();
  148.    
  149.     h.close()
  150.    
  151.     if peripheral.getType(cl_modemside) ~= "modem" then
  152.         cl_modemside = getModemSides()[getModemToRun(getModemSides())]
  153.         writeConfig()
  154.     end
  155. else
  156.    
  157.     cl_modemside = getModemSides()[getModemToRun(getModemSides())]
  158.     repeat
  159.         clear()
  160.         -------=========================-=========================
  161.         print("===================================================")
  162.         print("=                      SETUP                      =")
  163.         print("===================================================")
  164.         print()
  165.         print("What role does tis machine have?")
  166.         print("It is a:")
  167.         print("1 => Client")
  168.         print("2 => Server")
  169.         print("3 => Repeater")
  170.        
  171.         answer=tonumber(read())
  172.     until answer ~= nil and ( answer == 1 or answer == 2 or answer == 3 )
  173.    
  174.     if answer == 1 then
  175.         cl_type = "client"
  176.     elseif answer == 2 then
  177.         cl_type = "server"
  178.         shell.run("mkdir mailserver")
  179.        
  180.         local h = fs.open("startup", "w")
  181.         h.writeLine('shell.run("'.. shell.getRunningProgram() .. '")')
  182.         h.close()
  183.     elseif answer == 3 then
  184.         cl_type = "repeater"
  185.         local h = fs.open("startup", "w")
  186.         h.writeLine('shell.run("'.. shell.getRunningProgram() .. '")')
  187.         h.close()
  188.     end
  189.    
  190.     writeConfig()
  191. end
  192. modem = peripheral.wrap(cl_modemside)
  193.  
  194. if cl_type == "server" then
  195.     clear()
  196.     -------=========================-=========================
  197.     print("===================================================")
  198.     print("=                  Computercraft                  =")
  199.     print("=                   Mail-Server                   =")
  200.     print("=                   Version 1.0                   =")
  201.     print("=                   by BeminAbe                   =")
  202.     print("===================================================")
  203.     print("")
  204.     print("There are multiple ways of adding People.")
  205.     print("You can add yourself as a user from a client or")
  206.     print("you start this server with -u <username> <password>")
  207.     print("")
  208.     print("Wireless Modems have a range which is 64 blocks")
  209.     print("It can go up to 384 blocks at max. buildheight")
  210.     print("You can use the repeater function built into this")
  211.     print("system to extend the transmission range.")
  212.     while true do
  213.         data = receive()
  214.        
  215.         if data[2] == "login" then
  216.             user = data[3]
  217.             pass = data[4]
  218.             transmit({data[1].."-", "auth",fs.exists("mailserver/"..user.."/"..pass)})
  219.         elseif data[2] == "register" then
  220.             user = data[3]
  221.             pass = data[4]
  222.             transmit({data[1].."-", "auth",not(fs.exists("mailserver/"..user))})
  223.             if fs.exists("mailserver/"..user) == false then
  224.                 print("mailserver/"..user.."/"..pass)
  225.                 shell.run("mkdir mailserver/"..user.."/"..pass)
  226.             end
  227.         elseif data[2] == "finduser" then
  228.             user = data[3]
  229.             transmit({data[1].."-", "usercheck",fs.exists("mailserver/"..user)})
  230.         elseif data[2] == "sendmail" then
  231.             from = data[3]
  232.             to = data[4]
  233.             title = data[5]
  234.             message = data[6]
  235.            
  236.             transmit({data[1].."-", "sentmail",true})
  237.            
  238.             title = title:gsub(" ", "_")
  239.            
  240.             local h = fs.open("mailserver/" .. to .. "/inbox/new/"..title, "w")
  241.            
  242.             h.writeLine("Title: " .. title)
  243.             h.writeLine("From: " .. from)
  244.             h.writeLine("To: you(" .. to .. ")")
  245.             h.writeLine("\n"..message)
  246.            
  247.             h.close()
  248.            
  249.             local h = fs.open("mailserver/" .. from .. "/inbox/sent/"..title, "w")
  250.            
  251.             h.writeLine("Title: " .. title)
  252.             h.writeLine("From: " .. from)
  253.             h.writeLine("To: you(" .. to .. ")")
  254.             h.writeLine("\n"..message)
  255.            
  256.             h.close()
  257.            
  258.         elseif data[2] == "dir" then
  259.             user = data[3]
  260.             subdir = textutils.unserialize(data[4])
  261.            
  262.             sd =""
  263.             for k, v in pairs(subdir)  do
  264.                 if v ~= nil then
  265.                     sd = sd .. v .. "/"
  266.                 end
  267.             end
  268.            
  269.             if fs.isDir("mailserver/"..user.."/inbox/"..sd) then
  270.                 transmit({data[1].."-", "ls_dir", textutils.serialize(fs.list("mailserver/"..user.."/inbox/"..sd))})
  271.             else
  272.                 local h = fs.open("mailserver/"..user.."/inbox/"..sd, "r")
  273.                 message = h.readAll()
  274.                 h.close()
  275.                 if message == "" then
  276.                     message = "\n\n                  [Unknown Message]";
  277.                 end
  278.                 transmit({data[1].."-", "message", message})
  279.             end
  280.         elseif data[2] == "rm" then
  281.             user = data[3]
  282.             subdir = textutils.unserialize(data[4])
  283.            
  284.             sd =""
  285.             for k, v in pairs(subdir)  do
  286.                 if v ~= nil then
  287.                     sd = sd .. v .. "/"
  288.                 end
  289.             end
  290.            
  291.             shell.run("rm mailserver/"..user.."/inbox/"..sd)
  292.         elseif data[2] == "archive" then
  293.             user = data[3]
  294.             subdir = textutils.unserialize(data[4])
  295.            
  296.             sd =""
  297.             for k, v in pairs(subdir)  do
  298.                 if v ~= nil then
  299.                     sd = sd .. v .. "/"
  300.                 end
  301.             end
  302.            
  303.             shell.run("mv mailserver/"..user.."/inbox/"..sd .. " mailserver/" .. user .. "/inbox/archive/" .. subdir[table.getn(subdir)])
  304.            
  305.         else
  306.            
  307.         end
  308.     end
  309. elseif cl_type == "client" then
  310.     while true do
  311.         repeat
  312.             clear()
  313.             -------=========================-=========================
  314.             print("===================================================")
  315.             print("=                Login or Register                =")
  316.             print("===================================================")
  317.             print("")
  318.             print("1: Login")
  319.             print("2: Register")
  320.             action=tonumber(read())
  321.            
  322.             tries = 0
  323.             username = nil
  324.             repeat
  325.                 if action == 1 then
  326.                     clear()
  327.                     -------=========================-=========================
  328.                     print("===================================================")
  329.                     print("=                      Login                      =")
  330.                     print("===================================================")
  331.                     print()        
  332.                     if username ~= nil then
  333.                         print("Username or Password invalid!")
  334.                     end
  335.                     username,password = login()
  336.                     key = genKey(16)
  337.                     transmit({key, "login", username, password})
  338.                 elseif action == 2 then
  339.                     clear()
  340.                     -------=========================-=========================
  341.                     print("===================================================")
  342.                     print("=                  Registration                   =")
  343.                     print("===================================================")
  344.                     print()    
  345.                     if username ~= nil then
  346.                         print("Username already taken!")       
  347.                     end        
  348.                     username,password = login()
  349.                     key = genKey(16)
  350.                     transmit({key, "register", username, password})    
  351.                 end
  352.                 repeat
  353.                     data = receive()
  354.                 until string.sub(data[1],0,16) == key and data[2] == "auth"
  355.                 tries = tries + 1
  356.                 if tries >= 3 then
  357.                     action = ""
  358.                 end
  359.                
  360.             until data[3] == true or not(action == 1 or action == 2)
  361.            
  362.         until action == 1 or action == 2
  363.        
  364.         repeat
  365.             clear()
  366.             print("===================================================")
  367.             print("=             What do you want to do?             =")
  368.             print("===================================================")
  369.             print("")
  370.             print("1: Write a message to someone")
  371.             print("2: Check if I have a new message")
  372.             print("0: Exit")
  373.             action=tonumber(read())
  374.        
  375.        
  376.             if action == 1 then
  377.                 data = {}
  378.                 repeat
  379.                     clear()
  380.                     print("===================================================")
  381.                     print("=                      Mails                      =")
  382.                     print("===================================================")
  383.                     print()
  384.                     print("Please keep in mind titles are used in the inbox")
  385.                     print("That means you can overwrite mails")
  386.                     print("Also don't write too long mails. They cant be read")
  387.                     print()
  388.                     if data[3] == false then
  389.                         print("Target not found.")
  390.                     end
  391.                     print("Sending to: ")
  392.                     user=read()
  393.                     key = genKey(16)
  394.                     transmit({key, "finduser", user})
  395.                    
  396.                     repeat
  397.                         data = receive()
  398.                     until string.sub(data[1],0,16) == key and data[2] == "usercheck"
  399.  
  400.                 until data[2] == "usercheck" and data[3] == true
  401.                
  402.                 print("Title: ")
  403.                 title=read()
  404.                 print("Message: ")
  405.                 message=read()
  406.                 repeat
  407.                     key = genKey(16)
  408.                     transmit({key,"sendmail", username, user, title, message})
  409.                
  410.                     repeat
  411.                         data = receive()
  412.                     until string.sub(data[1],0,16) == key and data[2] == "sentmail"
  413.                 until data[2] == "sentmail" and data[3] == true
  414.             elseif action == 2 then
  415.                
  416.                
  417.                 local subdir = {}
  418.                 local page = 1
  419.                 repeat
  420.                     key = genKey(16)
  421.                     transmit({key, "dir", username, textutils.serialize(subdir)})
  422.                    
  423.                     repeat
  424.                         data = receive()
  425.                     until string.sub(data[1],0,16) == key and ( data[2] == "ls_dir" or data[2] == "message" )
  426.                    
  427.                     txt = ""
  428.                     dircontent =  textutils.unserialize(data[3])
  429.                     if data[2] == "ls_dir" then
  430.                        
  431.                          for k, v in pairs(textutils.unserialize(data[3])) do
  432.                             if v ~= nil then
  433.                                 txt = txt .. k .. ": " .. v .. "\n"
  434.                             end
  435.                         end
  436.            
  437.                        
  438.                        
  439.                         clear()
  440.                         print("===================================================")
  441.                         print("=                      Mails                      =")
  442.                         print("===================================================")
  443.                         print("0: <back 1 folder>")
  444.                         print(txt)
  445.                         lines = select(2, txt:gsub('\n', '\n'))
  446.                         for i=1, 10 - lines do
  447.                             print()
  448.                         end
  449.                         print("===================================================")
  450.                         print("<- back 10 (B)         EXIT e     (F) 10 forward ->")
  451.                         print("===================================================")
  452.                    
  453.                         action=string.lower(read())
  454.                          if action == "b" then
  455.                             if page > 1 then
  456.                                 page = page - 1
  457.                             end
  458.                         elseif action == "f" then
  459.                             if lines == 10 then
  460.                                 page = page + 1
  461.                             end
  462.                         elseif action ~= "0" and tonumber(action) ~= nil then
  463.                             page = 1
  464.                             subdir[table.getn(subdir) +1] = dircontent[tonumber(action)]
  465.                         elseif action == "0" and tonumber(action) ~= nil then
  466.                             page = 1
  467.                             subdir[table.getn(subdir)] = nil
  468.                            
  469.                         end
  470.                        
  471.                     elseif data[2] == "message" then
  472.                        
  473.                         repeat
  474.                             clear()
  475.                             print("===================================================")
  476.                             print("=                     Message                     =")
  477.                             print("===================================================")
  478.                             print(data[3])
  479.                             lines = select(2, data[3]:gsub('\n', '\n'))
  480.                             for i=1, 11 - lines do
  481.                                 print()
  482.                             end
  483.                             print("===================================================")
  484.                             print("= delete (D)           EXIT e          (A) archive=")
  485.                             print("===================================================")
  486.                            
  487.                             action=string.lower(read())
  488.                             if action == "d" then
  489.                                 key = genKey(16)
  490.                                 transmit({key, "rm", username, textutils.serialize(subdir)})   
  491.                                 action = "e"                           
  492.                             elseif action == "a" then
  493.                                 key = genKey(16)
  494.                                 transmit({key, "archive", username, textutils.serialize(subdir)})  
  495.                                 action = "e"
  496.                             end
  497.                            
  498.                         until action == "e"
  499.                         action = ""
  500.                         page = 1
  501.                         subdir[table.getn(subdir)] = nil
  502.                        
  503.                     end
  504.                
  505.                 until action == "e"
  506.                 action = 2
  507.                
  508.             end
  509.            
  510.         until action == 0
  511.    
  512.     end
  513.        
  514. elseif cl_type=="repeater" then
  515.     modem.open(prt_transmit)
  516.     modem.open(prt_receive)
  517.     keys = {{"key",5},{"keyyyyy",1}}
  518.     while true do
  519.    
  520.         local timeout = os.startTimer(1)
  521.         while true do
  522.             event = {os.pullEvent()}
  523.             if event[1] == "modem_message" then
  524.                
  525.                 -- local h = fs.open("config/repeater.log", "a")
  526.                 -- for k, v in pairs(event)  do
  527.                     -- if v ~= nil then
  528.                         -- h.writeLine(k .. ": " .. v)
  529.                     -- end
  530.                 -- end
  531.                
  532.                 -- h.writeLine("---------------------------------------------")
  533.                
  534.                 -- h.close()
  535.                
  536.                 donotsend = false
  537.                 for k, v in pairs( keys ) do
  538.                     val1 = textutils.unserialize(event[5])
  539.                    
  540.                     if v[1] == val1[1] then
  541.                         v[2] = 0
  542.                         donotsend = true
  543.                     end            
  544.                 end
  545.                
  546.                 print("transmiting: " .. tostring(donotsend))
  547.                
  548.                 if not(donotsend) then
  549.                     modem.transmit(event[3], event[4], event[5])
  550.                     val1 = textutils.unserialize(event[5])
  551.                     keys[table.getn(keys) +1] = {val1[1], 0}
  552.                 end
  553.                
  554.             elseif event[1] == "timer" and event[2] == timeout then
  555.                 old_keys = keys
  556.                 keys = {}
  557.                 for k, v in pairs( old_keys ) do
  558.                     print(k, " ", v[1], " ", v[2])
  559.                     v[2] = v[2] + 1
  560.                     if v[2] < 4 then
  561.                         keys[table.getn(keys)+1] = old_keys[k]
  562.                     end
  563.                 end
  564.                 print("---------------")
  565.                 break
  566.             end
  567.         end
  568.    
  569.     end
  570. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement