Advertisement
Guest User

Untitled

a guest
Feb 5th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.79 KB | None | 0 0
  1. import http.client
  2. import threading
  3. import difflib
  4. import html
  5. import json
  6.  
  7. urls = [
  8.        '/authentication/guest',   #0
  9.        '/authentication/login',   #1
  10.        '/search/users',           #2
  11.        '/cometd/handshake',       #3
  12.        '/cometd/connect',         #4
  13.        '/cometd/',                #5
  14.        '/account/logout',         #6
  15.        '/'                        #7
  16.        ]
  17.  
  18. class Crawler(threading.Thread):
  19.  
  20.     def __init__(self, auth_cookie, room_numb):
  21.         threading.Thread.__init__(self)
  22.         self.auth_cookie = auth_cookie
  23.         self.room_numb = room_numb
  24.         self.isRunning = False
  25.         self.client_id = None
  26.         self.ids_count = 0
  27.         self.cookies = None
  28.         self.friends = list()
  29.         self.roam_room = False
  30.         self.conn = http.client.HTTPConnection('e-chat.co', port=80)
  31.         return
  32.  
  33.     def send_receive(self, method, index, body):
  34.         #print('[debug]: trying to send data')
  35.         #print(body)
  36.         headers, stream = self.build_request_headers(index, body)
  37.         headers, stream = self.request_response(method, urls[index], stream, headers)
  38.         if headers == None or stream == None:
  39.             return None
  40.         if index == 3 or index == 7:
  41.             self.update_cookies(headers)
  42.         #print('[debug]: received response data')
  43.         #print(stream.decode('utf-8'))
  44.         return stream.decode('utf-8')
  45.  
  46.     def update_cookies(self, headers):
  47.         #print('[debug]: headers for invoked update are as', headers)
  48.         for pair in headers:
  49.             if pair[0] == 'Set-Cookie':
  50.                 new_cookie = pair[1][:pair[1].find(';')]
  51.                 #self.cookies = self.cookies[:self.cookies.find(';')]
  52.                 #print('[debug]: cookies before update are as', self.cookies)
  53.                 self.cookies = self.cookies + '; ' + new_cookie
  54.                 #print('[debug]: cookies after update are as', self.cookies)
  55.         return
  56.  
  57.     def request_response(self, method, url, body, headers):
  58.         try_count = 8
  59.         while try_count > 0:
  60.             try:
  61.                 try_count -= 1
  62.                 #print('[debug]: trying to send data, attempt', 8 - try_count)
  63.                 self.conn.request(method, url, body, headers)
  64.                 respon = self.conn.getresponse()
  65.                 status = respon.status
  66.                 reason = respon.reason
  67.                 header = respon.getheaders()
  68.                 stream = respon.read()
  69.                 respon.close()
  70.                 #print('[debug]: succeeded in sending data, attempt', 8 - try_count)
  71.                 return header, stream
  72.             except:
  73.                 status = self.refresh_connection()
  74.                 continue
  75.         #print('[debug]: failed to send data, attempt', 8 - try_count)
  76.         return None, None
  77.  
  78.     def refresh_connection(self):
  79.         try:
  80.             self.conn.close()
  81.             self.conn = http.client.HTTPConnection('e-chat.co', port=80)
  82.             self.conn.connect()
  83.             return True
  84.         except:
  85.             return False
  86.  
  87.     def build_request_headers(self, index, body):
  88.         headers = {}
  89.         headers['Host'] = 'e-chat.co'
  90.         if index < 3: #guest, login, search
  91.             headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
  92.         elif index < 6: #handshake, connect, cometd
  93.             headers['Content-Type'] = 'application/json; charset=UTF-8'
  94.         if index != 2 and index != 6: #except search, logout
  95.             headers['Connection'] = 'keep-alive'
  96.         if body != None:
  97.             headers['Content-Length'] = str(len(body))
  98.             body = body.encode('utf-8')
  99.         if self.cookies != None:
  100.             headers['Cookie'] = self.cookies
  101.         return headers, body
  102.  
  103.     def manual_user_login(self):
  104.         self.open_session()
  105.         stream = self.send_receive('GET', 7, None)
  106.         return (self.cookies.find('JSESSIONID') != -1)
  107.  
  108.     def checked_user_login(self):
  109.         for test in range(4):
  110.             if self.user_login() == '100':
  111.                 return True
  112.         return False
  113.  
  114.     def open_session(self):
  115.         self.client_id = None
  116.         self.ids_count = 0
  117.         #self.cookies = 'echat-authentication-cookie=cacb05c0-1801-425e-8485-2b0352afc517' #blackish
  118.         #self.cookies = 'echat-authentication-cookie=b3acd112-2f43-475e-8de4-bb27794acab5' #manonic
  119.         #self.cookies = 'echat-authentication-cookie=27b78658-b65c-44d2-a602-23cb11d67619' #Iran_Is_Safe
  120.         self.cookies = self.auth_cookie
  121.         self.conn = http.client.HTTPConnection('e-chat.co', port=80)
  122.         self.conn.connect()
  123.         return
  124.  
  125.     def close_session(self):
  126.         self.client_id = None
  127.         self.ids_count = 0
  128.         self.cookies = None
  129.         self.conn.close()
  130.         return
  131.  
  132.     def user_login(self):
  133.         if self.pass_word == None:
  134.             body = 'username=' + self.user_name
  135.         else:
  136.             body = 'username=' + self.user_name + '&password=' + self.pass_word + '&rememberAuthDetails=false'
  137.         self.open_session()
  138.         return self.send_receive('POST', 1, body)
  139.  
  140.     def user_logout(self):
  141.         stream = self.send_receive('GET', 6, None)
  142.         self.close_session()
  143.         return stream
  144.  
  145.     def checked_room_handshake(self):
  146.         self.ids_count = 0
  147.         stream = self.room_handshake()
  148.         if stream == None:
  149.             return False
  150.         st = stream.find('\"clientId\"')
  151.         en = stream.find(',', st)
  152.         if st == -1 or en == -1:
  153.             return False
  154.         self.client_id = stream[st:en]
  155.         return True
  156.  
  157.     def room_handshake(self):
  158.         body = '[{\"ext\":{\"chatroomId\":' + self.room_numb + '},\"version\":\"1.0\",\"minimumVersion\":\"0.9\",\"channel\":\"/meta/handshake\",\"supportedConnectionTypes\":[\"long-polling\",\"callback-polling\"],\"advice\":{\"timeout\":60000,\"interval\":0},\"id\":\"1\"}]'
  159.         return self.send_receive('POST', 3, body)
  160.  
  161.     def meta_connect(self):
  162.         self.ids_count += 1
  163.         body = '[{\"channel\":\"/meta/connect\",\"connectionType\":\"long-polling\",\"advice\":{\"timeout\":0},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  164.         return self.send_receive('POST', 4, body)
  165.  
  166.     def room_connect(self):
  167.         self.ids_count += 1
  168.         body = '[{\"channel\":\"/meta/connect\",\"connectionType\":\"long-polling\",\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  169.         return self.send_receive('POST', 4, body)
  170.  
  171.     def get_context(self):
  172.         self.ids_count += 1
  173.         body = '[{\"channel\":\"/service/user/context/self/complete\",\"data\":{},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  174.         stream = self.send_receive('POST', 5, body)
  175.         self.handle_json(json.loads(stream)[0])
  176.         return stream
  177.  
  178.     def send_public_text(self, text):
  179.         self.ids_count += 1
  180.         body = '[{\"channel\":\"/service/chatroom/message\",\"data\":{\"messageBody\":\"' + text + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  181.         return self.send_receive('POST', 5, body)
  182.  
  183.     def send_private_text(self, conv_uuid, text):
  184.         self.ids_count += 1
  185.         body = '[{\"channel\":\"/service/conversation/message\",\"data\":{\"conversationUserUuid\":\"' + conv_uuid + '\",\"messageBody\":\"' + text + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  186.         return self.send_receive('POST', 5, body)
  187.  
  188.     def open_chat_box(self, conv_uuid):
  189.         self.ids_count += 1
  190.         body = '[{\"channel\":\"/service/conversation/opened\",\"data\":{\"conversationUserUuid\":\"' + conv_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  191.         return self.send_receive('POST', 5, body)
  192.  
  193.     def close_chat_box(self, conv_uuid):
  194.         self.ids_count += 1
  195.         body = '[{\"channel\":\"/service/conversation/closed\",\"data\":{\"conversationUserUuid\":\"' + conv_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  196.         return self.send_receive('POST', 5, body)
  197.  
  198.     def append_friend(self, friend_uuid, friend_name):
  199.         friend = dict()
  200.         friend['uuid'] = friend_uuid
  201.         friend['name'] = friend_name
  202.         friend['isOnline'] = False
  203.         self.friends.append(friend)
  204.         self.ids_count += 1
  205.         stream = self.open_chat_box(friend_uuid)
  206.         stream = self.send_private_text(friend_uuid, 'hello ' + friend_name)
  207.         stream = self.send_private_text(friend_uuid, 'from now on i am a forced friend of yours')
  208.         body = '[{\"channel\":\"/service/friends/add\",\"data\":{\"userUuid\":\"' + friend_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  209.         return self.send_receive('POST', 5, body)
  210.  
  211.     def remove_friend(self, friend_uuid):
  212.         for friend in self.friends:
  213.             if friend['uuid'] == friend_uuid:
  214.                 self.friends.remove(friend)
  215.         stream = self.send_private_text(friend_uuid, 'it\'s been such an honour to befriended by you')
  216.         stream = self.send_private_text(friend_uuid, 'alas our friendship is not going to last forever')
  217.         stream = self.close_chat_box(friend_uuid)
  218.         self.ids_count += 1
  219.         body = '[{\"channel\":\"/service/friends/remove\",\"data\":{\"userUuid\":\"' + friend_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  220.         return self.send_receive('POST', 5, body)
  221.  
  222.     def append_ban(self, target_uuid):
  223.         self.ids_count += 1
  224.         body = '[{\"channel\":\"/service/moderator/ban/add\",\"data\":{\"targetUserUuid\":\"' + target_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  225.         return self.send_receive('POST', 5, body)
  226.  
  227.     def remove_ban(self, target_uuid):
  228.         self.ids_count += 1
  229.         body = '[{\"channel\":\"/service/moderator/ban/remove\",\"data\":{\"targetUserUuid\":\"' + target_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  230.         return self.send_receive('POST', 5, body)
  231.  
  232.     def remove_public_text(self, target_uuid):
  233.         self.ids_count += 1
  234.         body = '[{\"channel\":\"/service/moderator/messages/remove\",\"data\":{\"targetUserUuid\":\"' + target_uuid + '\"},\"id\":\"' + str(self.ids_count) + '\",' + self.client_id + '}]'
  235.         return self.send_receive('POST', 5, body)
  236.  
  237.     def join_room(self):
  238.         print('[debug]: trying to join room')
  239.         if self.manual_user_login() == False:
  240.             print('[error]: failed to login')
  241.             return False
  242.         if self.checked_room_handshake() == False:
  243.             print('[error]: failed at handshake')
  244.             return False
  245.         if self.meta_connect() == None:
  246.             print('[error]: failed to connect')
  247.             return False
  248.         if self.get_context() == None:
  249.             print('[error]: failed to get context')
  250.             return False
  251.         print('[debug]: successfully joined room')
  252.         return True
  253.  
  254.     def run(self):
  255.         self.isRunning = self.join_room()
  256.         while self.isRunning == True:
  257.             stream = self.room_connect()
  258.             if stream == None:
  259.                 print('[error]: connection is lost')
  260.                 self.isRunning = self.join_room()
  261.                 continue
  262.             if self.load_json(stream) == False:
  263.                 print('[debug]: connection is lost')
  264.                 self.isRunning = self.join_room()
  265.             if self.ids_count >= 256:
  266.                 print('[debug]: maximum number of requests reached')
  267. #                time.sleep(random.randint(1, 600))
  268.                 self.isRunning = self.join_room()
  269.             if self.roam_room == True:
  270.                 print('[debug]: a roam request has been issued')
  271.                 self.roam_room = False
  272.                 self.isRunning = self.join_room()
  273.         print('[debug]: failed to join room')
  274.         return
  275.  
  276.     def load_json(self, stream):
  277.         try:
  278.             data = json.loads(stream)
  279.             for obj in data:
  280.                 if obj['channel'] == '/meta/connect':
  281.                     return obj['successful']
  282.                 else:
  283.                     self.handle_json(obj)
  284.         except:
  285.             print('[error]: invalid json string')
  286.         return False
  287.  
  288.     def handle_json(self, obj):
  289.         if obj == None:
  290.             self.isRunning = False
  291. #        elif obj['channel'] == '/chatroom/message/add/' + self.room_numb:
  292. #            try:
  293. #                self.received_public_message(obj['data'])
  294. #            except:
  295. #                print('[error]: json format has changed for', obj['channel'])
  296. #        elif obj['channel'] == '/chatroom/user/joined/' + self.room_numb:
  297. #            try:
  298. #                self.user_joined(obj['data'])
  299. #            except:
  300. #                print('[error]: json format has changed for', obj['channel'])
  301. #        elif obj['channel'] == '/chatroom/user/left/' + self.room_numb:
  302. #            try:
  303. #                self.remove_user(obj['data'])
  304. #            except:
  305. #                print('[error]: json format has changed for', obj['channel'])
  306.         elif obj['channel'] == '/service/conversation/message':
  307.             try:
  308.                 self.received_private_message(obj['data']['msg'], obj['data']['key'])
  309.             except:
  310.                 print('[error]: json format has changed for', obj['channel'])
  311.         elif obj['channel'] == '/service/user/context/self/complete':
  312.             try:
  313.                 self.prepare_friends_details(obj['data'])
  314.             except:
  315.                 print('[error]: json format has changed for', obj['channel'])
  316.         elif obj['channel'] == '/service/conversation/notification/added':
  317.             try:
  318.                 self.received_notification(obj['data'])
  319.             except:
  320.                 print('[error]: json format has changed for', obj['channel'])
  321.         return
  322.  
  323.     def received_notification(self, obj):
  324.         stream = self.open_chat_box(obj['userUuid'])
  325.         if stream.find('you are not reckoned to be my master, get lost you blithering imposter') < 0:
  326.             stream =self.send_private_text(obj['userUuid'], 'you are not reckoned to be my master, get lost you blithering imposter')
  327.         stream = self.close_chat_box(obj['userUuid'])
  328.         return
  329.  
  330.     def prepare_friends_details(self, obj):
  331.         self.friends.clear()
  332.         for friend in obj['friends']:
  333.             _friend = dict()
  334.             _friend['uuid'] = friend['userUuid']
  335.             _friend['name'] = friend['username']
  336.             _friend['isOnline'] = friend['isOnline']
  337.             self.open_chat_box(_friend['uuid'])
  338.             self.friends.append(_friend)
  339.         return
  340.  
  341.     def retrieve_user_uuid(self, msg, key):
  342.         if msg['o'] == 1:
  343.             user_uuid = key[:36]
  344.         elif msg['o'] == 2:
  345.             user_uuid = key[36:]
  346.         else:
  347.             print('[error]: unexpected order', msg['o'])
  348.             if key[:36] != '2abcce47-eda0-443d-a382-78bb4b45045e': #'9cd92a17-22c3-4c83-ab26-32bef7b01cc0'
  349.                 user_uuid = key[:36]
  350.             else:
  351.                 user_uuid = key[36:]
  352.         return user_uuid
  353.  
  354.     def retrieve_user_text(self, msg):
  355.         user_text = html.unescape(msg['m'])
  356.         user_text = user_text.lower()
  357.         user_text = user_text.replace('\\\"', '\"')
  358.         return user_text
  359.  
  360.     def received_private_message(self, msg, key):
  361.         user_text = self.retrieve_user_text(msg)
  362.         user_uuid = self.retrieve_user_uuid(msg, key)
  363.         if user_text[:4] == 'say ':
  364.             self.say_text(user_text[4:], user_uuid)
  365.         elif user_text[:5] == 'roam ':
  366.             self.roam_to_room(user_text[5:], user_uuid)
  367.         elif user_text[:9] == 'befriend ':
  368.             self.befriend_user(user_text[9:], user_uuid)
  369.         elif user_text[:9] == 'unfriend ':
  370.             self.unfriend_user(user_text[9:], user_uuid)
  371.         elif user_text == 'list':
  372.             self.list_friends(user_uuid)
  373.         elif user_text == 'help':
  374.             self.send_user_manual(user_uuid)
  375.         else:
  376.             self.send_private_text(user_uuid, 'can not understand your order, type help if you need it')
  377.         return
  378.  
  379.     def send_user_manual(self, user_uuid):
  380.         self.send_private_text(user_uuid, 'say [text]: posts the given text in public chat')
  381.         self.send_private_text(user_uuid, 'roam [room number]: roams to the requsted room')
  382.         self.send_private_text(user_uuid, 'befriend [username]: befriends the requested user')
  383.         self.send_private_text(user_uuid, 'unfriend [username]: unfriends the requested user')
  384.         return
  385.  
  386.     def roam_to_room(self, user_text, user_uuid):
  387.         if not user_text.isnumeric():
  388.             self.send_private_text(user_uuid, 'room number must only contain numerials')
  389.         elif self.roam_room == True:
  390.             self.send_private_text(user_uuid, 'sorry, i can not roam to the requested room right now')
  391.         else:
  392.             self.room_numb = user_text
  393.             self.roam_room = True
  394.             self.send_private_text(user_uuid, 'i will be there within a minute')
  395.         return
  396.  
  397.     def isFriend(self, friend_uuid):
  398.         for friend in self.friends:
  399.             if friend['uuid'] == friend_uuid:
  400.                 return True
  401.         return False
  402.  
  403.     def list_friends(self, user_uuid):
  404.         self.send_private_text(user_uuid, 'you')
  405.         for friend in self.friends:
  406.             self.send_private_text(user_uuid, 'and ' + friend['name'])
  407.         self.send_private_text(user_uuid, 'are my friends')
  408.         return
  409.  
  410.     def say_text(self, user_text, user_uuid):
  411.         self.send_public_text(user_text)
  412.         self.send_private_text(user_uuid, 'the given text has been posted in public chat')
  413.         return
  414.  
  415.     def befriend_user(self, user_text, user_uuid):
  416.         friend_uuid = None
  417.         if len(user_text) == 36 and user_text[8] == '-' and user_text[13] == '-' and user_text[18] == '-' and user_text[23] == '-':
  418.             friend_uuid = user_text
  419.         else:
  420.             friend_uuid = self.seek_friend_by_name(user_text)
  421.         if friend_uuid != None:
  422.             if self.isFriend(friend_uuid):
  423.                 self.send_private_text(user_uuid, 'this user is already in my friends list')
  424.                 return
  425.             self.append_friend(friend_uuid, user_text)
  426.             self.send_private_text(user_uuid, 'user was found')
  427.         else:
  428.             self.send_private_text(user_uuid, 'no such user was found')
  429.         return
  430.  
  431.     def unfriend_user(self, user_text, user_uuid):
  432.         friend_uuid = None
  433.         if len(user_text) == 36 and user_text[8] == '-' and user_text[13] == '-' and user_text[18] == '-' and user_text[23] == '-':
  434.             friend_uuid = user_text
  435.         else:
  436.             friend_uuid = self.find_friend_by_name(user_text)
  437.         if friend_uuid != None:
  438.             if not self.isFriend(friend_uuid):
  439.                 self.send_private_text(user_uuid, 'this user is not in my friends list')
  440.                 return
  441.             self.remove_friend(friend_uuid)
  442.             self.send_private_text(user_uuid, 'user was found')
  443.         else:
  444.             self.send_private_text(user_uuid, 'no such user was found')
  445.         return
  446.  
  447.     def find_friend_by_name(self, name):
  448.         for friend in self.friends:
  449.             if self.strings_match(friend['name'], name):
  450.                 return friend['uuid']
  451.         return self.seek_friend_by_name(name)
  452.  
  453.     def seek_friend_by_name(self, user_name):
  454.         stream = self.send_receive('POST', 2, 'targetUsername=' + user_name)
  455.         try:
  456.             data = json.loads(stream)
  457.         except:
  458.             return None
  459.         for obj in data:
  460.             if self.strings_match(obj['data']['username'], user_name, 0.95):
  461.                 return obj['data']['userUuid']
  462.         return None
  463.  
  464.     def strings_match(self, a, b, r=0.75):
  465.         if type(a) != type(str(None)):
  466.             a = str(a)
  467.         if type(b) != type(str(None)):
  468.             b = str(b)
  469.         return difflib.SequenceMatcher(None, a.lower(), b.lower()).ratio() >= r
  470.  
  471. def main():
  472.     crawlers = list()
  473.     cookies = dict()
  474.     cookies['echat-authentication-cookie=c7be9b71-95ca-4487-be2b-719f8d65046e'] = 'solmaz'
  475.     cookies['echat-authentication-cookie=a6e09d4d-77e1-4b21-ad29-59a3c563c211'] = 'biqam'
  476.     cookies['echat-authentication-cookie=c0776854-897f-44b6-841a-3caee0b36ab1'] = 'razor'
  477.     cookies['echat-authentication-cookie=f2a93a6b-b9aa-444c-8eed-1bb2245d97ff'] = 'awkward_silence'
  478.     cookies['echat-authentication-cookie=c084a5de-3a5a-4856-9cca-4aee159a0791'] = 'breathing_corpse'
  479.     cookies['echat-authentication-cookie=e63cac1a-449f-49ee-9098-403b4c6d3f00'] = 'salad shirazi'
  480.     for cookie in cookies.keys():
  481.         crawler = Crawler(cookie, '215315')
  482.         crawler.start()
  483.         crawlers.append(crawler)
  484.     for crawler in crawlers:
  485.         crawler.join()
  486.  
  487. if __name__ == '__main__':
  488.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement