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 |