Guest User

Untitled

a guest
Jun 20th, 2012
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.66 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. import socket, http.client
  3. import re
  4. import threading, time, random
  5. import hashlib
  6. import sys, logging
  7. import sqlite3
  8. from struct import pack, unpack
  9.  
  10. class Mouse():
  11. USER = b'Markelo'
  12. PASSWD = b'saedfaswdf'
  13. room = bytes('*bootcamp мы', 'utf8')
  14. DEBUG_LVL = logging.INFO
  15. roundNumber = b''
  16. nickname = b''
  17. uid = 0
  18. rank = 0
  19. bulle = b''
  20. bkey = b''
  21. map = b''
  22. map_id = 0
  23. MODE = 'SPIRITFLY' # NONE, SPIRITFLY, WIND, FOLLOW, EGG, CHEESEHOLE, HEARTS
  24. m_server = '176.31.101.37 ' # old '46.105.104.210', another new 176.31.234.223
  25.  
  26. class TFMBot():
  27. def __init__(self, HOST = '37.59.43.48', PORT = 443, BULLE = False):
  28. self.HOST = HOST
  29. self.PORT = PORT
  30. self.isBULLE = BULLE
  31. self.FINGERPRINT = b''
  32. self.MDT = []
  33. self.CMDTEC = 0
  34. self.players = {}
  35. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  36. self.dbconn = 0
  37. self.dbcursor = 0
  38. try:
  39. self.sock.connect((self.HOST, self.PORT))
  40. except socket.error as e:
  41. Logger.info('{0}:{1} Connection error {2}'.format(self.HOST, self.PORT, e.strerror))
  42. self.isConnected = False
  43. finally:
  44. Logger.info('{0}:{1} Connection established'.format(self.HOST, self.PORT))
  45. self.isConnected = True
  46. self.thread_read = threading.Thread(target=self.read)
  47. self.thread_keepalive = threading.Thread(target=self.keepalive)
  48. self.thread_read.start()
  49. if not self.isBULLE:
  50. self.write(self.getKikoo())
  51. else:
  52. packet = b'\x00\x00\x00\x00' + b'\x2c\x01' + Mouse.bkey
  53. packet = pack('!i', len(packet) + 4) + packet
  54. self.write(packet)
  55.  
  56. def getKikoo(self, host='kikoo.formice.com', path='/data.txt'):
  57. pattern = b'[0-9.]+\s([0-9]+)\s([A-Za-z0-9]+)'
  58. conn = http.client.HTTPConnection(host)
  59. conn.request("GET", path)
  60. r1 = conn.getresponse()
  61. data = b''
  62. version=0
  63. conn_key=b''
  64. while not r1.closed: data += r1.read(200)
  65. conn.close()
  66. if re.match(pattern, data):
  67. (version, conn_key) = re.search(pattern, data).groups()
  68. #conn_key = b'dbamrexjyswwfvhafwrj' # SSANEEY PROXY
  69. msg = pack('!i2shh' + str(len(conn_key)) + 's2s', 0, b'\x1c\x01', int(version), len(conn_key), conn_key, b'\x17\xed')
  70. #else: msg = b''
  71. return pack('!i', len(msg) + 4) + msg
  72.  
  73. # actions region
  74. def getCheese(self):
  75. self.buildPacket(b'\x05\x13', pack('!1s'+str(len(Mouse.roundNumber)) + 's', b'\x01', Mouse.roundNumber), 'old')
  76.  
  77. def getHole(self):
  78. self.buildPacket(b'\x05\x12', pack('!b1sb'+str(len(Mouse.roundNumber)) + 's', 1, b'0', 1, Mouse.roundNumber), 'old')
  79.  
  80. def getEgg(self):
  81. self.buildPacket(b'\x13\x14', pack('!1s'+str(len(Mouse.roundNumber)) + 's', b'\x01', Mouse.roundNumber), 'old')
  82.  
  83. def sendPM(self, nickname, message): # send private message
  84. snickname = pack('!H', len(nickname)) + nickname
  85. smessage = pack('!H', len(message)) + message
  86. self.buildPacket(b'\x06\x07', snickname + smessage)
  87. self.buildPacket(b'\x06\x1a', b'\x01\x63\x20' + nickname + b'\x20' + message, 'old')
  88.  
  89. def sendTM(self, message): # send tribe message
  90. smessage = pack('!h', len(message)) + message
  91. self.buildPacket(b'\x06\x08', smessage)
  92. self.buildPacket(b'\x06\x1a', b'\x01' + message, 'old')
  93.  
  94. def sendCM(self, message): # send chat message
  95. message = pack('!h', len(message)) + message
  96. self.buildPacket(b'\x06\x06', message)
  97.  
  98. def actionAntiafk(self):
  99. self.buildPacket(b'\x04\x0a', b'', 'old')
  100.  
  101. def actionDie(self):
  102. self.buildPacket(b'\x04\x05', pack('!i', int(Mouse.roundNumber))) # die
  103.  
  104. def actionSpawn(self, ID):
  105. self.buildPacket(b'\x05\x14', pack('!hHHHbbb', ID, 350, 200, 0, 20, 0, 1))
  106.  
  107. def actionSP(self, x, y):
  108. self.buildPacket(b'\x05\x14', pack('!hhhhbbb', 24, x+6, y+10, 0, 0, 0, 1))
  109. #self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 0, x, y, 20, 3, True, 10))
  110.  
  111. def actionMove(self):
  112. #roud_num(int), moving_right(byte), moving_left(byte), posX(short), posY(short), accelX(short), accelY(short), jump(byte), jump_img(byte), unknown, player_code(int)
  113. self.buildPacket(b'\x04\x04', pack('!ibbHHhhBBb', int(Mouse.roundNumber), 0, 0, 2700, 1117, 0, 0, 0, 0, 0))
  114.  
  115. def actionWind(self):
  116. self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 26, int(random.random()*600) + 100, int(random.random()*200) + 100, 5, 3, True, 10))
  117. time.sleep(0.5)
  118. self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 27, int(random.random()*600) + 100, int(random.random()*200) + 100, 5, 3, True, 10))
  119.  
  120. def gotoRoom(self, room):
  121. self.BULLE.shutdown()
  122. self.buildPacket(b'\x06\x1a', b'\x01room\x20' + room, 'old')
  123.  
  124. def gotoTribe(self):
  125. self.BULLE.shutdown()
  126. self.buildPacket(b'\x10\x01', b'')
  127.  
  128. def shutdown(self):
  129. self.isConnected = False
  130. self.thread_keepalive.join()
  131. self.thread_read.join()
  132. self.sock.close()
  133. Logger.info('Shutdown complete')
  134. # end actions region
  135.  
  136. def write(self, wrBuffer):
  137. if self.isConnected:
  138. while len(wrBuffer):
  139. try:
  140. Logger.debug('{0}:{1} <- {2}'.format(self.HOST, self.PORT, wrBuffer))
  141. sent = self.sock.send(wrBuffer)
  142. wrBuffer = wrBuffer[sent:]
  143. except socket.error as e:
  144. Logger.error('{0}:{1} send error {2} packet: {3}'.format(self.HOST, self.PORT, e.strerror, wrBuffer))
  145. sys.exit()
  146.  
  147. def read(self):
  148. rBuffer = b''
  149. try:
  150. self.dbconn = sqlite3.connect('tfmbot.sqlite')
  151. self.dbcursor = self.dbconn.cursor()
  152. except Exception as e:
  153. Logger.error('db connection faild: {0}'.format(e))
  154. while self.isConnected:
  155. try:
  156. rBuffer += self.sock.recv(8192)
  157. except socket.error as e:
  158. Logger.error('{0}:{1} recv error {2}'.format(self.HOST, self.PORT, e.strerror))
  159. sys.exit()
  160. while len(rBuffer) > 3:
  161. psize = unpack('!i', rBuffer[:4])[0]
  162. if psize > len(rBuffer):
  163. Logger.debug('Recv fragmented packet {0}'.format(rBuffer))
  164. break
  165. #Logger.debug('Recv error {0}'.format(sys.exc_info()))
  166. Logger.debug('Reading: size {0}, packet {1}'.format(psize, rBuffer))
  167. packet = rBuffer[:psize]
  168. rBuffer = rBuffer[psize:]
  169. #Logger.debug('{0}:{1} -> {2}'.format(self.HOST, self.PORT, packet))
  170. self.parseData(packet[4:])
  171. Logger.info('Read thread closed')
  172. self.dbcursor.close()
  173.  
  174. def parseData(self, packet):
  175. message = ''
  176. user = ''
  177. if packet[:2] == b'\x01\x01': packet = packet[4:]
  178. eventToken1 = packet[:1]
  179. eventToken2 = packet[1:2]
  180. msg = packet[2:]
  181. Logger.debug('{0}:{1} -> [{2}] [{3}] data: {4}'.format(self.HOST, self.PORT, unpack('!b', eventToken1)[0], unpack('!b', eventToken2)[0], msg))
  182. if eventToken1 == b'\x1a':
  183. if eventToken2 == b'\x1b': # Main server. Recv CMDTEC MDT packet
  184. Logger.debug('Recieved MDT packet. Parsing')
  185. msg = msg[1:].split(b'\x01')
  186. self.CMDTEC = int(msg[-1])
  187. for i in str(msg[-2], 'utf8'):
  188. if i == '0': i = '10'
  189. self.MDT.append(int(i))
  190. Logger.debug('CMDTEC: {0}, MDT: {1}'.format(self.CMDTEC, self.MDT))
  191. self.buildPacket(b'\x08\x02', b'\x02') #Skrillexia gja3ad7e bytes(hashlib.sha256(Mouse.PASSWD).hexdigest(), 'utf8') *vanilla spirit war
  192. self.buildPacket(b'\x1a\x04', b'\x01' + Mouse.USER + b'\x01' + (lambda : b'' if Mouse.PASSWD == b'' else bytes(hashlib.sha256(Mouse.PASSWD).hexdigest(), 'utf8'))() + b'\x01' + Mouse.room + b'\x01http://www.transformice.com/Transformice.swf?n=' + bytes(str(time.time()).split('.')[0], 'utf8'), 'old')
  193. self.thread_keepalive.start()
  194. elif eventToken2 == b'\x1a':
  195. Logger.debug('Recieved Ping request')
  196. self.buildPacket(b'\x1a\x1a', msg)
  197. elif eventToken1 == b'\x2c':
  198. if eventToken2 == b'\x01':
  199. msg = msg.split(b'\x00')
  200. Mouse.bulle = str(msg[-1][1:], 'utf8')
  201. Mouse.bkey = msg[-2]
  202. Logger.debug('Bulle {0}, Key {1}, Key size {2}'.format(Mouse.bulle, Mouse.bkey, len(Mouse.bkey)))
  203. self.BULLE = TFMBot(Mouse.bulle, 443, True)
  204. elif eventToken2 == b'\x02': # Bulle server. Recv CMDTEC MDT packet
  205. Logger.debug('CMDTEC and MDT for Bulle {0}'.format(unpack('!h10sh', msg)))
  206. msg = unpack('!h10sh', msg)
  207. self.CMDTEC = int(msg[-1])
  208. for i in str(msg[-2], 'utf8'):
  209. if i == '0': i = '10'
  210. self.MDT.append(int(i))
  211. Logger.debug('CMDTEC: {1}, MDT: {0}'.format(self.MDT, self.CMDTEC))
  212. self.thread_keepalive.start()
  213. elif eventToken1 == b'\x04':
  214. if eventToken2 == b'\x04': # Bulle server. MOVE
  215. try:
  216. msg = unpack('!ibbhhhhbbbi', msg) # id, moving_right, moving_left, x, y,
  217. except Exception as e:
  218. Logger.error('error {0} unapropriated move packet {1}'.format(e, msg))
  219. return
  220. Logger.debug('Recieved MOVE request {0}'.format(msg))
  221. for i in self.players:
  222. if msg[-1] == self.players[i][0]:
  223. Logger.debug('Moving {0}'.format(i))
  224. if msg[1] >0 or msg[2] > 0:
  225. self.players[i][1] = msg[1]
  226. self.players[i][2] = msg[2]
  227. self.players[i][3] = int(msg[3])
  228. self.players[i][4] = int(msg[4])
  229. Logger.debug(self.players)
  230. elif eventToken2 == b'\x09': # Bulle server. CROUCH
  231. Logger.debug('Recieved CROUCH request {0}'.format(msg))
  232. if re.match(b'^\x01[0-9]+\x01$', msg):
  233. target = int(re.search(b'^\x01([0-9]+)\x01$', msg).group(1))
  234. for i in self.players:
  235. if Mouse.MODE == 'SPIRITFLY' and target == self.players[i][0]:
  236. self.actionSP(int(self.players[i][3]*800/2700), int(self.players[i][4]*800/2700))
  237. elif eventToken1 == b'\x05':
  238. if eventToken2 == b'\x05': # Bulle server. Recv NEW_MAP packet
  239. try:
  240. msg = msg.split(b'\x01')
  241. Mouse.map_id = msg[1]
  242. Mouse.roundNumber = msg[3]
  243. except Exception as e:
  244. Logger.error('Recv round info faild: {0} {1}'.format(e, msg))
  245. finally:
  246. Logger.info('map_id {0}, round num {1}'.format(Mouse.map_id, Mouse.roundNumber))
  247. if Mouse.MODE == 'EGG':
  248. time.sleep(1)
  249. self.getCheese()
  250. time.sleep(1)
  251. self.getEgg()
  252. time.sleep(1)
  253. self.getHole()
  254. elif Mouse.MODE == 'CHEESEHOLE':
  255. time.sleep(1)
  256. self.getCheese()
  257. time.sleep(1)
  258. self.getHole()
  259. elif eventToken1 == b'\x06': # Recv message:
  260. if eventToken2 == b'\x06': # Bulle server. Recv chat message
  261. message = msg.split(b'\x00')
  262. try:
  263. Logger.info('[c][{0}]: {1}'.format(str(message[-2][1:], 'utf8'), str(message[-1][1:], 'utf8')))
  264. message = str(message[-1][1:], 'utf8')
  265. if message == 'сырнора' or message == 'норасыр':
  266. Logger.info('Recv command cheesehole: {0}'.format(message))
  267. self.getCheese()
  268. time.sleep(1)
  269. self.getHole()
  270. except ValueError as e:
  271. Logger.error('Recv chat message error {0} in {1}'.format(e, msg))
  272. elif eventToken2 == b'\x07': # Main server. Recv private message
  273. dest = msg[:1]
  274. msg = msg[1:].split(b'\x00')
  275. msg[0] = dest
  276. try:
  277. user = str(msg[1][1:-1], 'utf8')
  278. message = str(msg[2][1:], 'utf8')
  279. except ValueError as e:
  280. Logger.error('Recv private message error {0} in {1}'.format(e, msg))
  281. return
  282. rank = (lambda x: x if x else (0,))(self.dbcursor.execute('SELECT rights FROM users WHERE user = ?', (user,)).fetchone())[0]
  283. Logger.info('rank = {0}'.format(rank))
  284. Logger.debug(msg)
  285. Logger.info('[w{3}][{0}][{1}]: {2}'.format(user, unpack('!b', msg[1][-1:])[0], message, (lambda x: '->' if x == b'\x00' else '<-')(msg[0])))
  286. if re.match('\.cheese', message) and rank > 9:
  287. Logger.info('Recv command .cheese in round {0}'.format(Mouse.roundNumber))
  288. self.BULLE.getCheese()
  289. elif re.match('\.hole', message) and rank > 9:
  290. Logger.info('Recv command .hole in round {0}'.format(Mouse.roundNumber))
  291. self.BULLE.getHole()
  292. elif re.match('\.egg', message) and rank > 9:
  293. Logger.info('Recv command .egg in round {0}'.format(Mouse.roundNumber))
  294. self.BULLE.getEgg()
  295. elif re.match('\.die', message) or re.match('\.eid', message) and rank >= 0:
  296. Logger.info('Recv command .die in round {0}'.format(Mouse.roundNumber))
  297. self.BULLE.actionDie()
  298. elif re.match('\.spawn', message) and rank > 9:
  299. Logger.info('Recv command .spawn in round {0}'.format(Mouse.roundNumber))
  300. self.BULLE.actionSpawn(35)
  301. elif re.match('\.move', message) and rank > 9:
  302. Logger.info('Recv command .move in round {0}'.format(Mouse.roundNumber))
  303. self.BULLE.actionMove()
  304. elif re.match('\.room\s+[\w\*\s]+', message) and rank > 9:
  305. Logger.info('Recv command .room {0}'.format(message))
  306. Mouse.room = bytes(re.search('\.room\s+([\w\*\s]+)', message).group(1), 'utf8')
  307. Logger.info(Mouse.room)
  308. self.gotoRoom(Mouse.room)
  309. elif re.match('\.tribe', message) and rank > 9:
  310. Logger.info('Recv command .tribe {0}'.format(message))
  311. Mouse.room = b''
  312. self.gotoTribe()
  313. elif re.match('\.mode\s+\w+', message) and rank > 9:
  314. Mouse.MODE = re.search('\.mode\s+(\w+)', message).groups(1)[0]
  315. Logger.info('Recv command .mode {0} in message {1}'.format(Mouse.MODE, message))
  316. elif re.match('\.user\s+add\s+[A-Za-z0-9]+\s+\d+', message) and rank > 9:
  317. Logger.info('Recv command .user add {0}'.format(message))
  318. (user, rank) = re.search('\.user\s+add\s+([A-Za-z0-9]+)\s+(\d+)', message).groups()
  319. Logger.info('User {0} now has rank {1}'.format(user, rank))
  320. elif re.match('\.test', message) and rank > 9:
  321. Logger.info('Recv command .test in round {0}'.format(Mouse.roundNumber))
  322. self.sendPM(b'Oyaeby', bytes('test message', 'utf8'))
  323. #self.BULLE.sendCM(bytes('кукареку', 'utf8'))
  324. #self.sendTM(bytes('пук пук', 'utf8'))
  325. elif eventToken2 == b'\x08': # Main server. Recv tribe message
  326. message = msg.split(b'\x00')
  327. try:
  328. Logger.info('[t][{1}]: {0}'.format(str(message[1][1:], 'utf8'), str(message[2][1:], 'utf8')))
  329. except ValueError as e:
  330. Logger.error('Recv tribe message error {0} in {1}'.format(e, msg))
  331. elif eventToken2 == b'\x11': # Bulle server. Recv 0.20s
  332. Logger.debug('recieved 0.20 packet in round {0}'.format(Mouse.roundNumber))
  333. self.actionDie()
  334. elif eventToken1 == b'\x08':
  335. if eventToken2 == b'\x09': # Bulle server. Recv room players
  336. msg = msg.split(b'\x01')
  337. self.players = {}
  338. for i in msg[1:]: # id, moving_right, moving_left, x, y,
  339. self.players[i.split(b'#')[0]] = [int(i.split(b'#')[1]), 1, 0, 0, 0]
  340. Logger.info('Room players: {0}'.format(self.players))
  341. Logger.info('Sending ANTIAFK packet')
  342. self.actionAntiafk()
  343.  
  344. def buildPacket(self, CC, data, proto='new'):
  345. loc3 = self.CMDTEC % 9000 + 1000
  346. self.FINGERPRINT = b''
  347. self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 1000)])
  348. self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 100) % 10])
  349. self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 10) % 10])
  350. self.FINGERPRINT += pack('b', self.MDT[loc3 % 10])
  351. self.CMDTEC += 1
  352. packet = self.FINGERPRINT + (lambda : b'\x01\x01' + pack('!h', len(data) + 2) if proto == 'old' else b'')() + CC + data
  353. packet = pack('!i', len(packet) + 4) + packet
  354. self.write(packet)
  355.  
  356. def keepalive(self):
  357. iteration = 0
  358. while self.isConnected:
  359. iteration += 1
  360. if Mouse.MODE == 'WIND' and self.isBULLE:
  361. self.actionWind()
  362. if iteration % 10 == 0:
  363. self.buildPacket(b"\x1a\x02", b'')
  364. if iteration > 180: iteration = 0
  365. time.sleep(1)
  366. Logger.debug('Keepalive thread closed')
  367.  
  368. Logger = logging.getLogger('TFMBot')
  369. Logger.setLevel(Mouse.DEBUG_LVL)
  370. #ch = logging.FileHandler('tfmbot_txt'+ str(time.time()) +'.log', encoding='utf-8')
  371. ch = logging.StreamHandler()
  372. ch.setLevel(Mouse.DEBUG_LVL)
  373. ch.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
  374. Logger.addHandler(ch)
  375.  
  376. s_main = TFMBot()
Advertisement
Add Comment
Please, Sign In to add comment