immibis

IIM r4

Jan 21st, 2012
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local session, nick
  2. local running = true
  3. local term_w, term_h = term.getSize()
  4.  
  5. local function urlencode(msg)
  6.     local ok = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
  7.     local enc = ""
  8.     local fmt = "%%%02X"
  9.     for k = 1, msg:len() do
  10.         local ch = msg:sub(k, k)
  11.         if ok:find(ch, 1, true) then
  12.             enc = enc .. ch
  13.         else
  14.             enc = enc .. fmt:format(string.byte(ch))
  15.         end
  16.     end
  17.     return enc
  18. end
  19.  
  20. local function getLastIndex()
  21.     local f = http.get("http://immibis.awardspace.biz/cc/iim/get.php")
  22.     local last = tonumber(f.readLine())
  23.     f.close()
  24.     return last
  25. end
  26.  
  27. local function sendLogout()
  28.     http.request("http://immibis.awardspace.biz/cc/iim/leave.php?s="..urlencode(session))
  29. end
  30.  
  31. local function startSession()
  32.     local f = http.get("http://immibis.awardspace.biz/cc/iim/start.php?nick="..urlencode(nick))
  33.     local response = f.readLine()
  34.     f.close()
  35.     if response:sub(1,2) == "OK" then
  36.         session = response:sub(3)
  37.     else
  38.         print(response)
  39.     end
  40. end
  41.  
  42. local function sendMessage(msg)
  43.     http.request("http://immibis.awardspace.biz/cc/iim/send.php?s="..urlencode(session).."&msg="..urlencode(msg))
  44. end
  45.  
  46. local buffer = {}
  47. local typing = ""
  48. local typing_pos = 0
  49. local typing_scroll = 0
  50. local history_pos = 0
  51. local history = {}
  52. local lastChatIndex = getLastIndex()
  53.  
  54. local function addLine(line)
  55.     if #buffer >= term_h - 1 then
  56.         table.remove(buffer, 1)
  57.     end
  58.     table.insert(buffer, line)
  59. end
  60.  
  61. local function displayChat(msg)
  62.     while msg:len() > term_w do
  63.         addLine(msg:sub(1,term_w))
  64.         msg = msg:sub(term_w + 1)
  65.     end
  66.     addLine(msg)
  67. end
  68.  
  69. local function updateCursor()
  70.     term.setCursorPos(typing_pos - typing_scroll + 3, term_h)
  71. end
  72.  
  73. local function updateInputLine()
  74.     term.setCursorPos(1, term_h)
  75.     term.clearLine()
  76.     term.write("> " .. typing:sub(typing_scroll + 1))
  77.     updateCursor()
  78. end
  79.  
  80. local function updateScreen()
  81.     for k = 1, term_h - 1 do
  82.         term.setCursorPos(1, k)
  83.         term.clearLine()
  84.         term.write(buffer[k] or "")
  85.     end
  86.     updateCursor()
  87. end
  88.  
  89. local pollURL
  90.  
  91. local function startPoll()
  92.     pollURL = "http://immibis.awardspace.biz/cc/iim/get.php?last=" .. lastChatIndex .. "&ping=" .. session
  93.     http.request(pollURL)
  94. end
  95.  
  96. local function handlePollResponse(f)
  97.     local any = false
  98.     while true do
  99.         local line = f.readLine()
  100.         if line == nil then break end
  101.         if line == "EMPTY" then break end
  102.         if line == "END" then break end
  103.         local index = line:find(" ")
  104.         if index ~= nil then
  105.             local id = tonumber(line:sub(1, index-1))
  106.             local msg = line:sub(index+1)
  107.             lastChatIndex = id
  108.             displayChat(msg)
  109.             any = true
  110.         end
  111.     end
  112.     f.close()
  113.     if any then updateScreen() end
  114. end
  115.  
  116. repeat
  117.     print("Enter your nickname: ")
  118.     nick = read()
  119.     startSession()
  120. until session ~= nil
  121.  
  122. local function updateHScroll()
  123.     if typing_pos < typing_scroll + 4 and typing_pos > 4 then
  124.         typing_scroll = math.max(0, typing_pos - 4)
  125.         return true
  126.     elseif typing_pos > typing_scroll + term_w - 7 then
  127.         typing_scroll = typing_pos - term_w + 7
  128.         return true
  129.     else
  130.         return false
  131.     end
  132. end
  133.  
  134. local function onInputLine(msg)
  135.     if msg == "/quit" then
  136.         sendLogout()
  137.         running = false
  138.     else
  139.         sendMessage(msg)
  140.     end
  141. end
  142.  
  143. lastChatIndex = 0
  144. startPoll()
  145. term.setCursorBlink(true)
  146. updateScreen()
  147. updateInputLine()
  148. while running do
  149.     local evt, p1, p2 = os.pullEvent()
  150.     if evt == "http_failure" and p1 == pollURL then
  151.         displayChat("Network error")
  152.     elseif evt == "http_success" and p1 == pollURL then
  153.         handlePollResponse(p2)
  154.         startPoll()
  155.     elseif evt == "http_success" then
  156.         p2.close()
  157.     elseif evt == "char" then
  158.         typing = typing:sub(1, typing_pos)..p1..typing:sub(typing_pos + 1)
  159.         typing_pos = typing_pos + 1
  160.         updateHScroll()
  161.         updateInputLine()
  162.     elseif evt == "key" then
  163.         if p1 == 28 then
  164.             -- Enter
  165.             onInputLine(typing)
  166.             table.insert(history, typing)
  167.             typing = ""
  168.             typing_pos = 0
  169.             typing_scroll = 0
  170.             history_pos = #history
  171.             updateInputLine()
  172.         elseif p1 == 203 then
  173.             -- Left
  174.             if typing_pos > 0 then
  175.                 typing_pos = typing_pos - 1
  176.                 if updateHScroll() then
  177.                     updateInputLine()
  178.                 else
  179.                     updateCursor()
  180.                 end
  181.             end
  182.         elseif p1 == 205 then
  183.             -- Right
  184.             if typing_pos < typing:len() then
  185.                 typing_pos = typing_pos + 1
  186.                 if updateHScroll() then
  187.                     updateInputLine()
  188.                 else
  189.                     updateCursor()
  190.                 end
  191.             end
  192.         elseif p1 == 14 then
  193.             -- Backspace
  194.             if typing_pos > 0 then
  195.                 typing = typing:sub(1, typing_pos-1) .. typing:sub(typing_pos+1)
  196.                 typing_pos = typing_pos - 1
  197.                 updateHScroll()
  198.                 updateInputLine()
  199.             end
  200.         elseif p1 == 200 then
  201.             -- Up
  202.             if history_pos > 1 then
  203.                 history_pos = history_pos - 1
  204.                 typing = history[history_pos]
  205.                 typing_pos = typing:len()
  206.                 updateHScroll()
  207.                 updateInputLine()
  208.             end
  209.         elseif p1 == 208 then
  210.             -- Down
  211.             if history_pos < #history then
  212.                 history_pos = history_pos + 1
  213.                 typing = history[history_pos]
  214.                 typing_pos = typing:len()
  215.                 updateHScroll()
  216.                 updateInputLine()
  217.             end
  218.         end
  219.     end
  220. end
Advertisement
Add Comment
Please, Sign In to add comment