local function getLastIndex() local f = http.get("http://immibis.awardspace.biz/cc/iim/get.php") local last = tonumber(f.readLine()) f.close() return lastendlocal function urlencode(msg) local ok = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~" local enc = "" local fmt = "%%%02X" for k = 1, msg:len() do local ch = msg:sub(k, k) if ok:find(ch) then enc = enc .. ch else enc = enc .. fmt:format(string.byte(ch)) end end return encendlocal function sendMessage(msg) http.request("http://immibis.awardspace.biz/cc/iim/send.php?msg="..urlencode(msg))endlocal buffer = {}local typing = ""local typing_pos = 0local typing_scroll = 0local history_pos = 0local history = {}local lastChatIndex = getLastIndex()local function addLine(line) if #buffer >= 17 then table.remove(buffer, 1) end table.insert(buffer, line)endlocal function displayChat(msg) while msg:len() > 50 do addLine(msg:sub(1,50)) msg = msg:sub(51) end addLine(msg)endlocal function updateCursor() term.setCursorPos(typing_pos - typing_scroll + 3, 18)endlocal function updateInputLine() term.setCursorPos(1, 18) term.clearLine() term.write("> " .. typing:sub(typing_scroll + 1)) updateCursor()endlocal function updateScreen() for k = 1, 17 do term.setCursorPos(1, k) term.clearLine() term.write(buffer[k] or "") end updateCursor()endlocal pollURLlocal function startPoll() pollURL = "http://immibis.awardspace.biz/cc/iim/get.php?last=" .. lastChatIndex http.request(pollURL)endlocal function handlePollResponse(f) local any = false while true do local line = f.readLine() if line == nil then break end if line == "EMPTY" then break end if line == "END" then break end local index = line:find(" ") if index ~= nil then local id = tonumber(line:sub(1, index-1)) local msg = line:sub(index+1) lastChatIndex = id displayChat(msg) any = true end end f.close() if any then updateScreen() endendprint("Enter your nickname: ")local nick = read()local function updateHScroll() if typing_pos < typing_scroll + 4 and typing_pos > 4 then typing_scroll = math.max(0, typing_pos - 4) return true elseif typing_pos > typing_scroll + 43 then typing_scroll = typing_pos - 43 return true else return false endendlocal function onInputLine(msg) sendMessage("<"..nick.."> "..msg)endlastChatIndex = 0startPoll()term.setCursorBlink(true)updateScreen()updateInputLine()while true do local evt, p1, p2 = os.pullEvent() if evt == "http_failure" and p1 == pollURL then displayChat("Network error") elseif evt == "http_success" and p1 == pollURL then handlePollResponse(p2) startPoll() elseif evt == "http_success" then p2.close() elseif evt == "char" then typing = typing:sub(1, typing_pos)..p1..typing:sub(typing_pos + 1) typing_pos = typing_pos + 1 updateHScroll() updateInputLine() elseif evt == "key" then if p1 == 28 then -- Enter onInputLine(typing) table.insert(history, typing) typing = "" typing_pos = 0 typing_scroll = 0 history_pos = #history updateInputLine() elseif p1 == 203 then -- Left if typing_pos > 0 then typing_pos = typing_pos - 1 if updateHScroll() then updateInputLine() else updateCursor() end end elseif p1 == 205 then -- Right if typing_pos < typing:len() then typing_pos = typing_pos + 1 if updateHScroll() then updateInputLine() else updateCursor() end end elseif p1 == 14 then -- Backspace if typing_pos > 0 then typing = typing:sub(1, typing_pos-1) .. typing:sub(typing_pos+1) typing_pos = typing_pos - 1 updateHScroll() updateInputLine() end elseif p1 == 200 then -- Up if history_pos > 1 then history_pos = history_pos - 1 typing = history[history_pos] typing_pos = typing:len() updateHScroll() updateInputLine() end elseif p1 == 208 then -- Down if history_pos < #history then history_pos = history_pos + 1 typing = history[history_pos] typing_pos = typing:len() updateHScroll() updateInputLine() end end endend