Advertisement
Guest User

talk

a guest
Sep 21st, 2014
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.64 KB | None | 0 0
  1. local width,height=term.getSize()
  2.  
  3. local function debug(...)
  4.   term.redirect(term.native)
  5.   print(...)
  6.   os.pullEvent("char")
  7.   term.restore()
  8. end
  9.  
  10. local function printUsage()
  11.   print([[Usage:
  12. talk <dein name>
  13. ]])
  14.   error()
  15. end
  16.  
  17. local tArgs={...}
  18. if #tArgs<1 or #tArgs>2 then
  19.   printUsage()
  20. end
  21.  
  22. --look for a modem
  23. local modem
  24.  
  25. do
  26.   local modemSides={}
  27.   for _,v in pairs(rs.getSides()) do
  28.     if peripheral.getType(v)=="modem" then
  29.       modemSides[#modemSides+1]=v
  30.     end
  31.   end
  32.  
  33.   if #modemSides==0 then
  34.     print("Du benåB6tigst ein WLAN Modem")
  35.     return
  36.   end
  37.   if #modemSides>1 then
  38.     term.scroll(#modemSides+3)
  39.     local selected=1
  40.    
  41.     local function printMenu()
  42.       term.setCursorPos(1,height-#modemSides-2)
  43.       for i=1,#modemSides do
  44.         if selected==i then
  45.           term.setTextColor(colors.black)
  46.           term.setBackgroundColor(colors.white)
  47.         end
  48.         print(i..": "..modemSides[i].." - "..(peripheral.call(modemSides[i],"isWireless") and "wireless" or "wired"))
  49.         if selected==i then
  50.           term.setTextColor(colors.white)
  51.           term.setBackgroundColor(colors.black)
  52.         end
  53.       end
  54.     end
  55.      
  56.     print("select a modem to use:")
  57.     printMenu()
  58.     if term.isColor() then
  59.       write("use arrows and enter, press # to select, or click with mouse to select")
  60.     else
  61.       write("use arrows and enter or press # to select")
  62.     end
  63.     while true do
  64.       local e={os.pullEvent()}
  65.       if e[1]=="key" then
  66.         local key=e[2]
  67.         if key==keys.up then
  68.           selected=selected==1 and #modemSides or selected-1
  69.           printMenu()
  70.         elseif key==keys.down then
  71.           selected=(selected%#modemSides)+1
  72.           printMenu()
  73.         elseif key==keys.enter then
  74.           break
  75.         end
  76.       elseif e[1]=="char" then
  77.         local char=e[2]
  78.         local num=tonumber(char)
  79.         if num and num>0 and num<=#modemSides then
  80.           selected=num
  81.           break
  82.         end
  83.       end
  84.     end
  85.    
  86.     term.scroll(2)
  87.     modem=peripheral.wrap(modemSides[selected])    
  88.   else
  89.     modem=peripheral.wrap(modemSides[1])
  90.   end
  91. end
  92.  
  93.          
  94. local function parseNick(str)
  95.   local nick=str:match("%s*([%w_]+)%s*")
  96.   return nick and nick:sub(1,12) or nil
  97. end
  98.  
  99. local nick=parseNick(tArgs[1])
  100. if nick==nil then
  101.   print("Invalid nick! can contain only letters, numbers, and _ and must be no more than 12 characters long.")
  102.   return
  103. end
  104.  
  105. local users={
  106.   [nick]=true
  107. }
  108.  
  109. local channel, frequency="chat",1337
  110.  
  111. local function parseChannel(str)
  112.   local chan,freq=str:match("%s*(%w+):(%d+)%s*")
  113.   if not chan then
  114.     freq=frequency
  115.     chan=str:match("(%w+)"):lower():sub(1,16)
  116.     if not chan then
  117.       chan=channel
  118.     end
  119.   else
  120.     chan=chan:lower():sub(1,16)
  121.     freq=tonumber(freq)%65536
  122.   end
  123.   return chan,freq
  124. end
  125.  
  126.  
  127. if tArgs[2] then
  128.   channel,frequency=parseChannel(tArgs[2])
  129. end
  130.  
  131. modem.open(frequency)
  132.  
  133. local inputCurPos={1,2}
  134. local inputTextColor=colors.white
  135. local inputBGColor=colors.black
  136. local inputCursorBlink=false
  137. local inputBuffer=(""):rep(width)
  138.  
  139. local statusLine
  140.  
  141. local function rebuildStatus()
  142.   statusLine=" ccchat v1.0     channel: "..channel..":"..frequency
  143.   statusLine=statusLine..(" "):rep(width-#statusLine)
  144.   term.native.setCursorPos(1,height-1)
  145.   term.native.setTextColor(colors.black)
  146.   term.native.setBackgroundColor(colors.white)
  147.   term.native.write(statusLine)
  148.   term.native.setTextColor(colors.white)
  149.   term.native.setBackgroundColor(colors.black)  
  150. end
  151.  
  152. local function redrawInput()
  153.   term.redirect(term.native)
  154.   term.setCursorPos(1,height-1)
  155.   term.setTextColor(colors.black)
  156.   term.setBackgroundColor(colors.white)
  157.   term.write(statusLine)
  158.   term.setCursorPos(1,height)
  159.   term.setBackgroundColor(colors.black)
  160.   term.setTextColor(colors.white)
  161.   term.write(inputBuffer)
  162.   term.setCursorPos(unpack(inputCurPos))
  163.   term.restore()
  164. end
  165.  
  166.  
  167. --input+status redirect
  168. local inputRedirect = {
  169.   getSize=function() return width,2 end,
  170.   setCursorPos=function(x,y) inputCurPos={x,y} term.native.setCursorPos(x,height) end,
  171.   getCursorPos=function() return unpack(inputCurPos) end,
  172.   setTextColor=function(color) inputTextColor=color term.native.setTextColor(color) end,
  173.   setTextColour=function(color) inputTextColor=color term.native.setTextColor(color) end,
  174.   setBackgroundColor=function(color) inputBGColor=color term.native.setBackgroundColor(color) end,
  175.   setBackgroundColour=function(color) inputBGColor=color term.native.setBackgroundColor(color) end,
  176.   setCursorBlink=function(state) inputCursorBlink=state term.native.setCursorBlink(state) end,
  177.   isColor=function() return term.native.isColor() end,
  178.   isColour=function() return term.native.isColour() end,
  179.   scroll=function() term.clearLine() end,
  180.   write=function(val)
  181.       inputBuffer=inputBuffer:sub(1,inputCurPos[1]-1)..val..inputBuffer:sub(inputCurPos[1]+#val)
  182.       inputCurPos[1]=inputCurPos[1]+#val
  183.       term.native.write(val)
  184.     end,
  185.   clear=function()
  186.       inputBuffer=(""):rep(width)
  187.     end,
  188.   clearLine=function()
  189.       inputBuffer=(""):rep(width)
  190.     end,
  191. }
  192.  
  193.  
  194. local isNewLogLine=true
  195. --main log redirect
  196. local logRedirect = {
  197.   getSize=function() return width,height-1 end,
  198.   setCursorBlink=function() end,
  199.   scroll=function(amt)      
  200.       term.native.scroll(amt)      
  201.       isNewLogLine=true
  202.     end,
  203.   write=function(text)
  204.       if isNewLogLine then
  205.         term.native.clearLine()
  206.         isNewLogLine=false
  207.       end      
  208.       term.native.write(text)
  209.     end,
  210. }
  211.  
  212. for k,v in pairs(term.native) do
  213.   if logRedirect[k]==nil then
  214.     logRedirect[k]=v
  215.   end
  216. end
  217.  
  218.  
  219. local function printLine(line)
  220.   local x,y=term.getCursorPos()
  221.   term.redirect(logRedirect)
  222.   term.setCursorPos(1,height-1)
  223.   print(line)
  224.   term.restore()
  225.   redrawInput()
  226.   term.setCursorPos(x,y)
  227.   --queue a dummy event to trigger coRead update?
  228.   --os.queueEvent("key")  
  229. end
  230.  
  231. local function printHelp()
  232.   printLine([[eXz-Chat 1.0 BETA #13
  233.   /quit [msg]   Beendet den Chat mit einer Nachricht
  234.   /join <name>  
  235.                 and joins <name>. <name> can end
  236.                 with :<freq> to change both,
  237.                 ex: /join foo:1338
  238.   /freq <freq>  switches chat frequencies
  239.   /help         displays this help
  240.   /nick <nick>  
  241.   /users        lists users in channel
  242.  
  243.   anything typed without a / will be said in the
  244.   channel and heard by all in range on the same
  245.   channel and frequency.]])
  246.  
  247. end
  248.  
  249.  
  250. local function sendMsg(msg)
  251.   local out="CHAT "..channel.." "..nick.." "..msg
  252.   modem.transmit(frequency,frequency,out)
  253. end
  254.  
  255. local function showUsers()
  256.   local first=true
  257.   local str="** Benutzer in diesem Channel "..channel..":"
  258.   for k,v in pairs(users) do
  259.     if first then
  260.       first=false
  261.     else
  262.       str=str..","
  263.     end
  264.     str=str.." "..k
  265.   end
  266.   printLine(str)
  267. end
  268.  
  269. local autoUsersTimer
  270.  
  271. local function coRead()
  272.   history={}
  273.   while true do
  274.     term.setCursorPos(1,height)
  275.     local input=read(nil,history)
  276.     history[#history+1]=input
  277.     if #history==256 then
  278.       table.remove(history,1)
  279.     end
  280.    
  281.     if input:sub(1,1)=="/" then
  282.       local cmd,args=input:match("/(%S+) ?(.*)")
  283.       if cmd=="quit" then
  284.         printLine("Exiting chat")
  285.         sendMsg("quit "..args:match("^%s*(.*)%s*$"))
  286.         return
  287.       elseif cmd=="me" then
  288.         printLine("* "..nick.." "..args)
  289.         sendMsg("me "..args)
  290.       elseif cmd=="join" then
  291.         local chan,freq=parseChannel(args)
  292.         if chan then
  293.           if chan==channel then
  294.             printLine("** Yer already in that channel!")
  295.           elseif args~="" then
  296.             printLine("** switching to channel "..chan..(freq==frequency and "" or (":"..freq)))
  297.             sendMsg("quit leftChannel")
  298.             channel=chan
  299.             if frequency~=freq then
  300.               modem.open(freq)
  301.               modem.close(frequency)
  302.               frequency=freq
  303.             end
  304.             sendMsg("join")
  305.             rebuildStatus()
  306.             users={[nick]=true}
  307.             autoUsersTimer=os.startTimer(.25)
  308.           else
  309.             printLine("** invalid channel!")
  310.           end
  311.         else
  312.           printLine("** invalid syntax")
  313.         end
  314.       elseif cmd=="freq" then
  315.         args=tonumber(args)
  316.         if args==nil then
  317.           printLine("** frequency must be a number.")
  318.         elseif frequency~=args then
  319.           printLine("** switching to frequency "..args)
  320.           sendMsg("quit leftChannel")
  321.           modem.open(args)
  322.           modem.close(frequency)
  323.           frequency=args
  324.           sendMsg("join")
  325.           rebuildStatus()
  326.           users={[nick]=true}
  327.           autoUsersTimer=os.startTimer(.25)
  328.         end
  329.       elseif cmd=="help" then
  330.         printHelp()
  331.       elseif cmd=="nick" then
  332.         local newNick=parseNick(args)
  333.         if newNick then          
  334.           printLine("** nick changed to "..newNick)
  335.           sendMsg("nick "..nick.." "..newNick)
  336.           nick=newNick
  337.         end
  338.       elseif cmd=="users" then
  339.         showUsers()
  340.       else
  341.         printLine("** Unknown command")
  342.       end
  343.     else
  344.       printLine("<"..nick.."> "..input)
  345.       sendMsg("say "..input)
  346.     end
  347.   end
  348. end
  349.  
  350.  
  351. local function coMain()
  352.   while true do  
  353.     e={os.pullEvent()}
  354.     if e[1]=="modem_message" then
  355.       local msgChannel, msgNick, msgCmd, msgArgs=e[5]:match("CHAT (%S+) (%S+) (%S+) ?(.*)")
  356.       if msgChannel==channel then
  357.         --it's a chat message on the right channel
  358.         if msgCmd=="say" then
  359.           printLine("<"..msgNick.."> "..msgArgs)
  360.         elseif msgCmd=="me" then
  361.           printLine("* "..msgNick.." "..msgArgs)
  362.         elseif msgCmd=="join" then
  363.           printLine("** "..msgNick.." has joined the chat")
  364.           sendMsg("ident")
  365.         elseif msgCmd=="ident" then
  366.           users[msgNick]=true
  367.         elseif msgCmd=="quit" then
  368.           printLine("** "..msgNick.." has left the channel ("..(msgArgs=="" and "quit" or msgArgs)..")")          
  369.         elseif msgCmd=="nick" then
  370.           local old, new=msgArgs:match("(%S+) (%S+)")
  371.           users[old]=nil
  372.           users[new]=true
  373.           printLine("** "..old.." now known as "..new)          
  374.         end
  375.       end
  376.     elseif e[1]=="timer" and e[2]==autoUsersTimer then
  377.       showUsers()      
  378.     end    
  379.   end
  380. end
  381.  
  382. sendMsg("join")
  383.  
  384. autoUsersTimer=os.startTimer(.25)
  385.  
  386. term.clear()
  387. rebuildStatus()
  388.  
  389. term.redirect(inputRedirect)
  390. printLine([[CCChat v1.0
  391. /help for a list of commands
  392. /quit quits
  393. just type to talk.]])
  394.  
  395. parallel.waitForAny(coRead,coMain)
  396.  
  397. modem.close(frequency)
  398.  
  399. term.restore()
  400. term.scroll(1)
  401. print("\ngoodbye!\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement