Advertisement
gpgautier

RedNet Chat

Nov 1st, 2012
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.98 KB | None | 0 0
  1. -- [ --------------------------------------------------------------------- ] --
  2. -- [ RedNetChat                                                           ] --
  3. -- [ A public chat client for ComputerCraft                                ] --
  4. -- [ Created by GPG Incorporated.                                          ] --
  5. -- [ --------------------------------------------------------------------- ] --
  6.  
  7. -- [ --------------------------------------------------------------------- ] --
  8.  
  9. local VERSION = "0.3 beta"
  10. local MODEM = nil
  11. local MONITOR = nil
  12. local NICKNAME = nil
  13. local ACTIVE = false
  14. local BUFFER = {}
  15. local POINTER = 0
  16. local ONLINE = {}
  17. local ISONLINE = false
  18.  
  19. -- [ --------------------------------------------------------------------- ] --
  20.  
  21. -- Application entry
  22. function main()
  23.   term.clear()
  24.   term.setCursorPos(1, 1)
  25.   print("Starting RedNetChat " .. VERSION)
  26.  
  27.   --sleep(0.5)
  28.  
  29.   if not setPeripherals() then
  30.     return false
  31.   end
  32.  
  33.   print("")
  34.   print("")
  35.   print("Peripherals are setup.")
  36.   print("")
  37.   term.write("Starting application")
  38.  
  39.   --simulateLoading(8)
  40.  
  41.   if MONITOR ~= nil then
  42.     MONITOR.clear()
  43.     MONITOR.setTextScale(1.5)
  44.     MONITOR.setCursorPos(1, 2)
  45.     MONITOR.write("        RedNet Chat")
  46.     MONITOR.setCursorPos(1, 4)
  47.     MONITOR.write("   Chatception in Tekkit")
  48.   end
  49.  
  50.   welcome()
  51. end
  52.  
  53. -- Simulate a loading effect
  54. function simulateLoading(amount)
  55.   local i
  56.  
  57.   sleep(0.2)
  58.   term.write(" ")
  59.   for i = 0, amount do
  60.     term.write(".")
  61.     sleep(0.2)
  62.   end
  63.   term.write " Done"
  64. end
  65.  
  66. -- Set the attached peripherals. Opens rednet modem and warps monitor
  67. function setPeripherals()
  68.   local i, side
  69.  
  70.   for i, side in pairs(redstone.getSides()) do
  71.     if peripheral.isPresent(side) then
  72.       if peripheral.getType(side) == "modem" then
  73.         MODEM = side
  74.         print("")
  75.         term.write("Opening modem on " .. side)
  76.         rednet.open(MODEM)
  77.         --simulateLoading(6)
  78.       elseif peripheral.getType(side) == "monitor" then
  79.         print("")
  80.         term.write("Wrapping monitor on " .. side)
  81.         MONITOR = peripheral.wrap(side)
  82.         --simulateLoading(4)
  83.       end
  84.     end
  85.   end
  86.  
  87.   -- Exit with a fatal error when modem not found
  88.   if MODEM == nil then
  89.     print("[FATAL ERROR] No modem was detected. Plase attach a modem on any side.")
  90.     return false
  91.   end
  92.  
  93.   return true
  94. end
  95.  
  96. -- Start the welcome screen
  97. function welcome()
  98.   local x, y
  99.  
  100.   term.clear()
  101.   writeHeader()
  102.   print("")
  103.   print("")
  104.   print("Enter a nickname and press [enter].")
  105.   print("")
  106.   term.write("Nickname: ")
  107.  
  108.   x, y = term.getCursorPos()
  109.  
  110.   while NICKNAME == nil or NICKNAME == "" do
  111.     term.setCursorPos(x, y)
  112.     NICKNAME = read()
  113.     execute("/online")
  114.     appendBuffer("[RedNet Chat]: Type /help for a list of commands")
  115.   end
  116.  
  117.   start()
  118. end
  119.  
  120. -- Writes the screen header
  121. function writeHeader()
  122.   term.setCursorPos(1, 1)
  123.   term.write("RedNet Chat " .. VERSION .. "           by GPG Incorporated")
  124.   term.setCursorPos(1, 2)
  125.   term.write("--------------------------------------------------")
  126. end
  127.  
  128. -- Writes the list of online users
  129. function writeOnlineList()
  130.   local i, v, count, x, y
  131.  
  132.   count = 0
  133.  
  134.   x, y = term.getCursorPos()
  135.  
  136.   term.setCursorPos(1, 17)
  137.   term.write("--------------------------------------------------")
  138.   term.setCursorPos(1, 18)
  139.   term.clearLine()
  140.   term.write("Online: ")
  141.  
  142.   for i, v in ipairs(ONLINE) do
  143.     if i == 1 then
  144.       term.write(ONLINE[i])
  145.     else
  146.       term.write(", " .. ONLINE[i])
  147.     end
  148.  
  149.     count = count + 1
  150.   end
  151.  
  152.   if count == 0 then
  153.     term.write("There is nobody online at this moment")
  154.   end
  155.  
  156.   term.setCursorPos(x, y)
  157. end
  158.  
  159. -- Start the chat
  160. function start()
  161.   term.clear()
  162.   writeHeader()
  163.   writeOnlineList()
  164.  
  165.   ACTIVE = true
  166.  
  167.   showBuffer()
  168.  
  169.   parallel.waitForAll(input, watchEvents, receive)
  170. end
  171.  
  172. -- Stop the application
  173. function stop()
  174.   ACTIVE = false
  175. end
  176.  
  177. -- Reset the application
  178. function reset()
  179.   execute("/offline")
  180.   rednet.close(MODEM)
  181.   sleep(2)
  182.   os.reboot()
  183. end
  184.  
  185. -- Watch all input to provide possible shortcuts (for example usernames)
  186. function watchEvents()
  187.   local type, param, param2, param3, i, v
  188.  
  189.   while ACTIVE do
  190.     type, param, param2, param3 = os.pullEvent()
  191.   end
  192. end
  193.  
  194. -- Handle input from the prompt
  195. function input()
  196.   local message
  197.  
  198.   term.setCursorPos(1, 4)
  199.   term.write("--------------------------------------------------")
  200.  
  201.   while ACTIVE do
  202.     term.setCursorPos(1, 3)
  203.     term.clearLine()
  204.     term.write("Send > ")
  205.  
  206.     message = read()
  207.  
  208.     if message ~= nil and message ~= "" then
  209.       execute(message, "local")
  210.     end
  211.   end
  212. end
  213.  
  214. -- Send a message
  215. function send(message)
  216.   local request = {protocol = "rnc", nickname = NICKNAME, message = message}
  217.   rednet.broadcast(textutils.serialize(request))
  218. end
  219.  
  220. -- Recieve a message
  221. function receive()
  222.   local sender, message, distance, request
  223.  
  224.   while ACTIVE do
  225.     sender, message, distance = rednet.receive(1)
  226.  
  227.     if message ~= nil and message ~= "" then
  228.       request = textutils.unserialize(message)
  229.       if request.protocol == "rnc" then
  230.         if request.nickname ~= nil and request.nickname ~= "" then
  231.           execute(request, "remote")
  232.         end
  233.       end
  234.     end
  235.   end
  236. end
  237.  
  238. -- Execute a command or add a chat message
  239. function execute(message, source)
  240.   local command
  241.  
  242.   if message.nickname ~= nil then
  243.     executeRemote(message)
  244.     return
  245.   end
  246.  
  247.   if message:sub(0, 1) == "/" then
  248.       command = message:sub(2)
  249.  
  250.       if command == "quit"
  251.           or command == "reset"
  252.           or command == "restart"
  253.           or command == "reboot"
  254.           or command == "stop"
  255.         then
  256.           appendBuffer("[RedNet Chat]: Restarting application")
  257.           reset()
  258.       elseif command == "online" then
  259.         if not ISONLINE then
  260.           send("/online")
  261.           putOnline()
  262.           appendBuffer("[RedNet Chat]: You are now online")
  263.           ISONLINE = true
  264.         else
  265.           appendBuffer("[RedNet Chat]: You are already online")
  266.         end
  267.       elseif command == "offline" then
  268.         if ISONLINE then
  269.           send("/offline")
  270.           takeOffline()
  271.           appendBuffer("[RedNet Chat]: You are now offline")
  272.           ISONLINE = false
  273.         else
  274.           appendBuffer("[RedNet Chat]: You are already offline")
  275.         end
  276.       elseif command:sub(0, 5) == "nick " then
  277.         takeOffline()
  278.         NICKNAME = command:sub(6)
  279.         putOnline()
  280.         appendBuffer("[RedNet Chat]: Your nickname has been changed")
  281.       elseif command:sub(0, 5) == "slap " then
  282.         appendBuffer(command:sub(6) .. " was slapped by " .. NICKNAME)
  283.       elseif command == "help" then
  284.         appendBuffer("[RedNet Chat] Commands:")
  285.         appendBuffer("/quit : Exit the chat")
  286.       end
  287.      
  288.       return
  289.   end
  290.  
  291.   appendBuffer(NICKNAME .. ": " .. message)
  292.   send(message)
  293. end
  294.  
  295. --
  296. function putOnline(nickname)
  297.   local i, v, exists
  298.  
  299.   if nickname == nil then
  300.     nickname = NICKNAME
  301.   end
  302.  
  303.   for i, v in ipairs(ONLINE) do
  304.     if ONLINE[i] == nickname then
  305.       exists = true
  306.     end
  307.   end
  308.  
  309.   if not exists then
  310.     table.insert(ONLINE, nickname)
  311.   end
  312.  
  313.   writeOnlineList()
  314. end
  315.  
  316. --
  317. function takeOffline(nickname)
  318.   local i, v
  319.  
  320.   if nickname == nil then
  321.     nickname = NICKNAME
  322.   end
  323.  
  324.   for i, v in ipairs(ONLINE) do
  325.     if ONLINE[i] == nickname then
  326.       table.remove(ONLINE, i)
  327.     end
  328.   end
  329.  
  330.   writeOnlineList()
  331. end
  332.  
  333. --
  334. function executeRemote(request)
  335.   local command
  336.  
  337.   if request.message:sub(0, 1) == "/" then
  338.     command = request.message:sub(2)
  339.  
  340.     if command == "online" then
  341.       putOnline(request.nickname)
  342.       appendBuffer("[RedNet Chat]: " .. request.nickname .. " is now online")
  343.       send("/metoo")
  344.     elseif command == "offline" then
  345.       takeOffline(request.nickname)
  346.       appendBuffer("[RedNet Chat]: " .. request.nickname .. " is now offline")
  347.     elseif command == "metoo" then
  348.       putOnline(request.nickname)
  349.     end
  350.     return
  351.   end
  352.  
  353.   appendBuffer(request.nickname .. ": " .. request.message)
  354. end
  355.  
  356. --
  357. function appendBuffer(message)
  358.   local length
  359.  
  360.   length = message:len()
  361.  
  362.   if length > 50 then
  363.     table.insert(BUFFER, message:sub(1, 50))
  364.     POINTER = POINTER + 1
  365.     appendBuffer(message:sub(51))
  366.   else
  367.     table.insert(BUFFER, message)
  368.     POINTER = POINTER + 1
  369.   end
  370.  
  371.   showBuffer()
  372. end
  373.  
  374. --
  375. function showBuffer()
  376.   local i, line, bufferPointer, x, y
  377.  
  378.   if POINTER == 0 then
  379.     return
  380.   end
  381.  
  382.   x, y = term.getCursorPos()
  383.  
  384.   line = 5
  385.  
  386.   bufferPointer = -(11 - POINTER)
  387.  
  388.   for i = bufferPointer, bufferPointer + 11 do
  389.     term.setCursorPos(1, line)
  390.     term.clearLine()
  391.    
  392.     if BUFFER[i] ~= nil then
  393.       term.write(tostring(BUFFER[i]))
  394.     end
  395.    
  396.     line = line + 1
  397.   end
  398.  
  399.   term.setCursorPos(x, y)
  400. end
  401.  
  402. -- [ --------------------------------------------------------------------- ] --
  403.  
  404. -- Fire up the application
  405. --welcome()
  406. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement