View difference between Paste ID: qHgr8CNq and sUu6ujPr
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