SHOW:
|
|
- or go back to the newest paste.
| 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 | - | sendMessage(msg) |
| 131 | + | |
| 132 | end | |
| 133 | ||
| 134 | local function onInputLine(msg) | |
| 135 | if msg == "/quit" then | |
| 136 | sendLogout() | |
| 137 | running = false | |
| 138 | else | |
| 139 | - | while true do |
| 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 |