View difference between Paste ID: Aht0r1V9 and HVMwL5nR
SHOW: | | - or go back to the newest paste.
1
import rtmp_protocol
2
import httplib
3
from xml.dom.minidom import parseString
4
import thread
5
import time
6
import random
7
import socket
8
 
9
# Credits for code base to MegaLOLer
10
# Edits by Nola
11
 
12
# Add Cauth token - API - http://tinychat.com/api/captcha/check.php?room=tinychat^[roomname]&guest_id=[user_id]
13
# Fix Bug - If Using Admin account - all messages come in as PMs
14
# Fix Youtube/Sound Cloud API Calls
15
# Unban command - API - http://tinychat.com/ajax/user/clearbans
16
# Ability to tell whether users are moderators or not - Prase JOINS
17
# Add Auto Bans Based on Usernames
18
# Add Trivia/Poker Bot based on IRC Bots
19
# Other things
20
 
21
DEBUG = True
22
 
23
def httpRequest(server, resource, body="", headers={}, method="GET"):
24
		connection = httplib.HTTPConnection(server)
25
		connection.request(method, resource, body, headers)
26
		response = connection.getresponse()
27
		headers = response.getheaders()
28
		data = response.read()
29
		connection.close()
30
		return (headers, data)
31
	   
32
class TinychatMessage():
33
		def __init__(self, msg, nick, user=None, recipient=None, color=None, pm=False):
34
				self.msg = msg
35
				self.nick = nick
36
				self.user = user
37
				self.recipient = recipient
38
				self.color = color
39
				self.pm = pm
40
	   
41
		def printFormatted(self):
42
				if self.pm:
43
						pm = "(PM) "
44
				else:
45
						pm = ""
46
				print(pm + self.recipient + ": " + self.nick + ": " + self.msg)
47
 
48
class TinychatUser():
49
		def __init__(self, nick, id=None, color=None, lastMsg=None):
50
				self.nick = nick
51
				self.id = id
52
				self.color = color
53
				self.lastMsg = lastMsg
54
 
55
TINYCHAT_COLORS = ["#a78901"]
56
 
57
class TinychatRoom():
58
		# Manages a single room connection     
59
		def __init__(self, room, nick=None, passwd=None):
60
				self.room = room
61
				self.tcUrl = self._getTcUrl()
62
				parts = self.tcUrl.split("/")
63
				server = parts[2].split(":")
64
				self.server = server[0]
65
				self.port = int(server[1])
66
				self.app = parts[3]
67
				self.url = "http://tinychat.com/" + room
68
				self.connected = False
69
				self.queue = []
70
				self.color = TINYCHAT_COLORS[random.randint(0, len(TINYCHAT_COLORS) - 1)]
71
				self.nick = nick
72
				self.passwd = passwd
73
				if self.nick == "": self.nick = None
74
				if self.passwd == "": self.passwd = None
75
				self.topic = None
76
				self.users = {}
77
				self.echo = __name__ == "__main__"
78
				self.stack = False
79
				self.userID = None
80
 
81
		def connect(self):
82
				if not self.connected:
83
						self.connection = rtmp_protocol.RtmpClient(self.server, self.port, self.tcUrl, self.url, '', self.app)
84
						if self.nick:
85
								n = self.nick.lower()
86
						else:
87
								n = ""
88
						self.connection.connect([self.room, self._getAutoOp(), u'show', u'tinychat', n])
89
						self.connected = True
90
						self._listen()
91
	   
92
		def disconnect(self):
93
				if self.connected:
94
						self.connected = False
95
						try:
96
								self.connection.socket.shutdown(socket.SHUT_RDWR)
97
						except:
98
								pass
99
						self.onDisconnect()
100
	   
101
		def poll(self):
102
				q = self.queue
103
				self.queue = []
104
				return q
105
			   
106
		# Commands
107
		def cauth(self):
108
				self._sendCauth(self._getTcCauth())
109
	   
110
		def say(self, msg):
111
				if len(msg) > 152: return
112
				self._sendCommand("privmsg", [u"" + self._encodeMessage(msg), u"" + self.color + ",en"])
113
			   
114
		def pm(self, msg, recipient):
115
				if len(msg) > 152: return
116
				self._sendCommand("privmsg", [u"" + self._encodeMessage("/msg " + recipient + " " + msg), u"" + self.color + ",en", u"n" + self._getUser(recipient).id + "-" + recipient])
117
			   
118
		def setNick(self, nick=None):
119
				if not nick: nick = self.nick
120
				self.nick = nick
121
				self._sendCommand("nick", [u"" + nick])
122
	   
123
		def cycleColor(self):
124
				try:
125
						i = TINYCHAT_COLORS.index(self.color)
126
				except:
127
						i = TINYCHAT_COLORS[random.randint(0, len(TINYCHAT_COLORS) - 1)]
128
				i = (i + 1) % len(TINYCHAT_COLORS)
129
				self.color = TINYCHAT_COLORS[i]
130
	   
131
		def ban(self, nick):
132
				self._sendCommand("kick", [u"" + nick, self._getUser(nick).id])
133
	   
134
		def playYoutube(self, video):
135
				self.say("/mbs youTube " + str(video) + " 0")
136
	   
137
		def stopYoutube(self):
138
				self.say("/mbc youTube")
139
	   
140
		def playSoundcloud(self, track):
141
				self.say("/mbs soundCloud " + str(track) + " 0")
142
	   
143
		def stopSoundcloud(self):
144
				self.say("/mbc soundCloud")
145
	   
146
		# Events
147
		def onMessage(self, user, message):
148
				if self.echo: message.printFormatted()
149
			   
150
		def onPM(self, user, message):
151
				if self.echo: message.printFormatted()
152
	   
153
		def onQuit(self, user):
154
				if self.echo: print(self.room + ": " + user.nick + " left the room.")
155
	   
156
		def onBan(self, user):
157
				if self.echo: print(self.room + ": " + user.nick + " was banned.")
158
	   
159
		def onJoin(self, user):
160
				if self.echo: print(self.room + ": " + user.nick + " entered the room.")
161
	   
162
		def onRegister(self, user):
163
				if self.echo: print("You have connected to " + self.room + ".")
164
	   
165
		def onNickChange(self, new, old, user):
166
				if self.echo: print(self.room + ": " + old + " changed nickname to " + new + ".")
167
	   
168
		def onTopic(self, topic):
169
				if self.echo: print(self.room + ": Topic set to \"" + topic + "\".")
170
	   
171
		def onUserList(self, users):
172
				pass
173
	   
174
		def onDisconnect(self):
175
				if self.echo: print("You have disconnected from " + self.room + ".")
176
	   
177
		# Helper methods
178
		def _listen(self):
179
				while self.connected:
180
						try:
181
								msg = self.connection.reader.next()
182
								if DEBUG: print("SERVER: " + str(msg))
183
								if msg['msg'] == rtmp_protocol.DataTypes.COMMAND:
184
										pars = msg['command']
185
										cmd = pars[0].encode("ascii", "ignore").lower()
186
										if len(pars) > 3:
187
												pars = pars[3:]
188
										else:
189
												pars = []
190
										for i in range(len(pars)):
191
												if type(pars[i]) == str: pars[i] = pars[i].encode("ascii", "ignore")
192
										if cmd == "privmsg":
193
												recipient = pars[0]
194
												message = pars[1]
195
												color = pars[2].lower().split(",")[0]
196
												nick = pars[3]
197
												if recipient[0] == "#":
198
														recipient = "^".join(recipient.split("^")[1:])
199
												else:
200
														recipient = "-".join(recipient.split("-")[1:])
201
												user = self._getUser(nick)
202
												message = TinychatMessage(self._decodeMessage(message), nick, user, recipient, color)
203
												user.lastMsg = message
204
												user.color = color
205
												if self.stack: self.queue.append(message)
206
												if recipient.lower() == self.nick.lower():
207
														message.pm = True
208
														if message.msg.startswith("/msg ") and len(message.msg.split(" ")) >= 2: message.msg = " ".join(message.msg.split(" ")[2:])
209
														self.onPM(user, message)
210
												else:
211
														self.onMessage(user, message)
212
										elif cmd == "registered":
213
												if self.nick: self.setNick()
214
												user = self._getUser(pars[0])
215
												user.id = pars[1]
216
												self.onRegister(user)
217
										elif cmd == "topic":
218
												self.topic = pars[0]
219
												self.onTopic(self.topic)
220
										elif cmd == "nick":
221
												user = self._getUser(pars[0])
222
												old = user.nick
223
												user.nick = pars[1]
224
												if old.lower() in self.users.keys():
225
														del self.users[old.lower()]
226
														self.users[user.nick.lower()] = user
227
												if user.nick == self.nick:
228
													self.userID = user.id
229
													self.cauth();
230
												self.onNickChange(user.nick, old, user)
231
										elif cmd == "quit":
232
												user = self.users[pars[0].lower()]
233
												del self.users[pars[0].lower()]
234
												self.onQuit(user)
235
										elif cmd == "kick":
236
												self.onBan(user = self.users[pars[1].lower()])
237
										elif cmd == "join":
238
												user = self._getUser(pars[1])
239
												user.id = pars[0]
240
												self.onJoin(user)
241
										elif cmd == "joins":
242
												for i in range((len(pars) - 1) / 2):
243
														user = self._getUser(pars[i*2 + 2])
244
														user.id = pars[i*2 + 1]
245
												#self.cauth();
246
										elif cmd == "joinsdone":
247
												self.onUserList(self.users)
248
						except:
249
								self.disconnect()
250
									   
251
		def _getUser(self, nick):
252
				if not nick.lower() in self.users.keys(): self.users[nick.lower()] = TinychatUser(nick)
253
				return self.users[nick.lower()]
254
   
255
		def _decodeMessage(self, msg):
256
				chars = msg.split(",")
257
				msg = ""
258
				for i in chars:
259
						msg += chr(int(i))
260
				return msg
261
		   
262
		def _encodeMessage(self, msg):
263
				msg2 = []
264
				for i in msg:
265
						msg2.append(str(ord(i)))
266
				return ",".join(msg2)
267
	   
268
		def _sendCommand(self, cmd, pars=[]):
269
				msg = {"msg": rtmp_protocol.DataTypes.COMMAND, "command": [u"" + cmd, 0, None,] + pars}
270
				if DEBUG: print("CLIENT: " + str(msg))
271
				self.connection.writer.write(msg)
272
				self.connection.writer.flush()
273
	   
274
		def _sendCauth(self, cauth):
275
				self._sendCommand("cauth", [cauth])
276
   
277
		def _getTcUrl(self):   
278
				return parseString(httpRequest("apl.tinychat.com", "/api/find.room/" + self.room + "?site=tinychat&url=tinychat.com")[1]).getElementsByTagName("response")[0].getAttribute("rtmp")
279
	 
280
		def _getTcCauth(self):
281
				return self._uglyStripCauthKey(httpRequest("tinychat.com", "/api/captcha/check.php?room=tinychat^" + self.room + "&guest_id=" + self.userID)[1])
282
283
		def _uglyStripCauthKey(self, json):
284
				cauth = json.split('"key":"')[1].split('"')[0]
285
				print("CAUTH KEY: " + cauth)
286
				return cauth
287
288
		def _getAutoOp(self):
289
				if self.nick and self.passwd:
290
						headers = httpRequest("tinychat.com", "/login", "form_sent=1&referer=&next=&username=" + self.nick + "&password=" + self.passwd + "&passwordfake=Password&remember=1", {"Content-Type": "application/x-www-form-urlencoded"}, "POST")[0]
291
						cookies = []
292
						for header in headers:
293
								if header[0].lower() == "set-cookie":
294
										parts = header[1].split(", ")
295
										for i in range(len(parts)):
296
												part = parts[i]
297
												part2 = part.split(";")[0]
298
												if "=" in part2:
299
														if "," in part2:
300
																part2 = part2.split(", ")[1]
301
														cookies.append(part2)
302
										break
303
						if len(cookies) > 0:
304
								html = httpRequest("tinychat.com", "/" + self.room, "", {"Content-Type": "application/x-www-form-urlencoded", "Cookie": "; ".join(cookies)})[1]
305
								if ", autoop: \"" in html:
306
										return html.split(", autoop: \"")[1].split("\"")[0]
307
				return u"none"
308
   
309
if __name__ == "__main__":
310
		room = TinychatRoom(raw_input("Enter room name: "), raw_input("Enter username (optional): "), raw_input("Enter password (optional): "))
311
		thread.start_new_thread(room.connect, ())
312
		while not room.connected: time.sleep(1)
313
		while room.connected:
314
				msg = raw_input()
315
				if len(msg) > 0:
316
						if msg[0] == "/":
317
								msg = msg[1:]
318
								if len(msg) > 0:
319
										parts = msg.split(" ")
320
										if len(parts) == 1:
321
												cmd = parts[0]
322
												pars = []
323
												par = ""
324
										else:
325
												cmd = parts[0]
326
												pars = parts[1:]
327
												par = " ".join(parts[1:])
328
										if cmd.lower() == "say":
329
												room.say(par)
330
										elif cmd.lower() == "pm":
331
												if len(pars) > 1:
332
														room.pm(" ".join(pars[1:]), pars[0])
333
												else:
334
														print("Please supply the recipient's nick as well as the message to send")
335
										elif cmd.lower() == "nick":
336
												room.setNick(par)
337
										elif cmd.lower() == "color":
338
												room.cycleColor()
339
										elif cmd.lower() == "ban":
340
												room.ban(par)
341
										elif cmd.lower() == "quit":
342
												room.disconnect()
343
										elif cmd.lower() == "playyoutube":
344
												room.playYoutube(par)
345
										elif cmd.lower() == "stopyoutube":
346
												room.stopYoutube()
347
										elif cmd.lower() == "playsoundcloud":
348
												room.playSoundcloud(par)
349
										elif cmd.lower() == "stopsoundcloud":
350
												room.stopSoundcloud()
351
										elif cmd.lower() == "cauth":
352
												room.cauth()
353
						else:
354
								room.say(msg)