Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- import socket, http.client
- import re
- import threading, time, random
- import hashlib
- import sys, logging
- import sqlite3
- from struct import pack, unpack
- class Mouse():
- USER = b'Markelo'
- PASSWD = b'saedfaswdf'
- room = bytes('*bootcamp мы', 'utf8')
- DEBUG_LVL = logging.INFO
- roundNumber = b''
- nickname = b''
- uid = 0
- rank = 0
- bulle = b''
- bkey = b''
- map = b''
- map_id = 0
- MODE = 'SPIRITFLY' # NONE, SPIRITFLY, WIND, FOLLOW, EGG, CHEESEHOLE, HEARTS
- m_server = '176.31.101.37 ' # old '46.105.104.210', another new 176.31.234.223
- class TFMBot():
- def __init__(self, HOST = '37.59.43.48', PORT = 443, BULLE = False):
- self.HOST = HOST
- self.PORT = PORT
- self.isBULLE = BULLE
- self.FINGERPRINT = b''
- self.MDT = []
- self.CMDTEC = 0
- self.players = {}
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.dbconn = 0
- self.dbcursor = 0
- try:
- self.sock.connect((self.HOST, self.PORT))
- except socket.error as e:
- Logger.info('{0}:{1} Connection error {2}'.format(self.HOST, self.PORT, e.strerror))
- self.isConnected = False
- finally:
- Logger.info('{0}:{1} Connection established'.format(self.HOST, self.PORT))
- self.isConnected = True
- self.thread_read = threading.Thread(target=self.read)
- self.thread_keepalive = threading.Thread(target=self.keepalive)
- self.thread_read.start()
- if not self.isBULLE:
- self.write(self.getKikoo())
- else:
- packet = b'\x00\x00\x00\x00' + b'\x2c\x01' + Mouse.bkey
- packet = pack('!i', len(packet) + 4) + packet
- self.write(packet)
- def getKikoo(self, host='kikoo.formice.com', path='/data.txt'):
- pattern = b'[0-9.]+\s([0-9]+)\s([A-Za-z0-9]+)'
- conn = http.client.HTTPConnection(host)
- conn.request("GET", path)
- r1 = conn.getresponse()
- data = b''
- version=0
- conn_key=b''
- while not r1.closed: data += r1.read(200)
- conn.close()
- if re.match(pattern, data):
- (version, conn_key) = re.search(pattern, data).groups()
- #conn_key = b'dbamrexjyswwfvhafwrj' # SSANEEY PROXY
- msg = pack('!i2shh' + str(len(conn_key)) + 's2s', 0, b'\x1c\x01', int(version), len(conn_key), conn_key, b'\x17\xed')
- #else: msg = b''
- return pack('!i', len(msg) + 4) + msg
- # actions region
- def getCheese(self):
- self.buildPacket(b'\x05\x13', pack('!1s'+str(len(Mouse.roundNumber)) + 's', b'\x01', Mouse.roundNumber), 'old')
- def getHole(self):
- self.buildPacket(b'\x05\x12', pack('!b1sb'+str(len(Mouse.roundNumber)) + 's', 1, b'0', 1, Mouse.roundNumber), 'old')
- def getEgg(self):
- self.buildPacket(b'\x13\x14', pack('!1s'+str(len(Mouse.roundNumber)) + 's', b'\x01', Mouse.roundNumber), 'old')
- def sendPM(self, nickname, message): # send private message
- snickname = pack('!H', len(nickname)) + nickname
- smessage = pack('!H', len(message)) + message
- self.buildPacket(b'\x06\x07', snickname + smessage)
- self.buildPacket(b'\x06\x1a', b'\x01\x63\x20' + nickname + b'\x20' + message, 'old')
- def sendTM(self, message): # send tribe message
- smessage = pack('!h', len(message)) + message
- self.buildPacket(b'\x06\x08', smessage)
- self.buildPacket(b'\x06\x1a', b'\x01' + message, 'old')
- def sendCM(self, message): # send chat message
- message = pack('!h', len(message)) + message
- self.buildPacket(b'\x06\x06', message)
- def actionAntiafk(self):
- self.buildPacket(b'\x04\x0a', b'', 'old')
- def actionDie(self):
- self.buildPacket(b'\x04\x05', pack('!i', int(Mouse.roundNumber))) # die
- def actionSpawn(self, ID):
- self.buildPacket(b'\x05\x14', pack('!hHHHbbb', ID, 350, 200, 0, 20, 0, 1))
- def actionSP(self, x, y):
- self.buildPacket(b'\x05\x14', pack('!hhhhbbb', 24, x+6, y+10, 0, 0, 0, 1))
- #self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 0, x, y, 20, 3, True, 10))
- def actionMove(self):
- #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)
- self.buildPacket(b'\x04\x04', pack('!ibbHHhhBBb', int(Mouse.roundNumber), 0, 0, 2700, 1117, 0, 0, 0, 0, 0))
- def actionWind(self):
- self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 26, int(random.random()*600) + 100, int(random.random()*200) + 100, 5, 3, True, 10))
- time.sleep(0.5)
- self.buildPacket(b'\x04\x02', pack('!bhhbb?h', 27, int(random.random()*600) + 100, int(random.random()*200) + 100, 5, 3, True, 10))
- def gotoRoom(self, room):
- self.BULLE.shutdown()
- self.buildPacket(b'\x06\x1a', b'\x01room\x20' + room, 'old')
- def gotoTribe(self):
- self.BULLE.shutdown()
- self.buildPacket(b'\x10\x01', b'')
- def shutdown(self):
- self.isConnected = False
- self.thread_keepalive.join()
- self.thread_read.join()
- self.sock.close()
- Logger.info('Shutdown complete')
- # end actions region
- def write(self, wrBuffer):
- if self.isConnected:
- while len(wrBuffer):
- try:
- Logger.debug('{0}:{1} <- {2}'.format(self.HOST, self.PORT, wrBuffer))
- sent = self.sock.send(wrBuffer)
- wrBuffer = wrBuffer[sent:]
- except socket.error as e:
- Logger.error('{0}:{1} send error {2} packet: {3}'.format(self.HOST, self.PORT, e.strerror, wrBuffer))
- sys.exit()
- def read(self):
- rBuffer = b''
- try:
- self.dbconn = sqlite3.connect('tfmbot.sqlite')
- self.dbcursor = self.dbconn.cursor()
- except Exception as e:
- Logger.error('db connection faild: {0}'.format(e))
- while self.isConnected:
- try:
- rBuffer += self.sock.recv(8192)
- except socket.error as e:
- Logger.error('{0}:{1} recv error {2}'.format(self.HOST, self.PORT, e.strerror))
- sys.exit()
- while len(rBuffer) > 3:
- psize = unpack('!i', rBuffer[:4])[0]
- if psize > len(rBuffer):
- Logger.debug('Recv fragmented packet {0}'.format(rBuffer))
- break
- #Logger.debug('Recv error {0}'.format(sys.exc_info()))
- Logger.debug('Reading: size {0}, packet {1}'.format(psize, rBuffer))
- packet = rBuffer[:psize]
- rBuffer = rBuffer[psize:]
- #Logger.debug('{0}:{1} -> {2}'.format(self.HOST, self.PORT, packet))
- self.parseData(packet[4:])
- Logger.info('Read thread closed')
- self.dbcursor.close()
- def parseData(self, packet):
- message = ''
- user = ''
- if packet[:2] == b'\x01\x01': packet = packet[4:]
- eventToken1 = packet[:1]
- eventToken2 = packet[1:2]
- msg = packet[2:]
- Logger.debug('{0}:{1} -> [{2}] [{3}] data: {4}'.format(self.HOST, self.PORT, unpack('!b', eventToken1)[0], unpack('!b', eventToken2)[0], msg))
- if eventToken1 == b'\x1a':
- if eventToken2 == b'\x1b': # Main server. Recv CMDTEC MDT packet
- Logger.debug('Recieved MDT packet. Parsing')
- msg = msg[1:].split(b'\x01')
- self.CMDTEC = int(msg[-1])
- for i in str(msg[-2], 'utf8'):
- if i == '0': i = '10'
- self.MDT.append(int(i))
- Logger.debug('CMDTEC: {0}, MDT: {1}'.format(self.CMDTEC, self.MDT))
- self.buildPacket(b'\x08\x02', b'\x02') #Skrillexia gja3ad7e bytes(hashlib.sha256(Mouse.PASSWD).hexdigest(), 'utf8') *vanilla spirit war
- 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')
- self.thread_keepalive.start()
- elif eventToken2 == b'\x1a':
- Logger.debug('Recieved Ping request')
- self.buildPacket(b'\x1a\x1a', msg)
- elif eventToken1 == b'\x2c':
- if eventToken2 == b'\x01':
- msg = msg.split(b'\x00')
- Mouse.bulle = str(msg[-1][1:], 'utf8')
- Mouse.bkey = msg[-2]
- Logger.debug('Bulle {0}, Key {1}, Key size {2}'.format(Mouse.bulle, Mouse.bkey, len(Mouse.bkey)))
- self.BULLE = TFMBot(Mouse.bulle, 443, True)
- elif eventToken2 == b'\x02': # Bulle server. Recv CMDTEC MDT packet
- Logger.debug('CMDTEC and MDT for Bulle {0}'.format(unpack('!h10sh', msg)))
- msg = unpack('!h10sh', msg)
- self.CMDTEC = int(msg[-1])
- for i in str(msg[-2], 'utf8'):
- if i == '0': i = '10'
- self.MDT.append(int(i))
- Logger.debug('CMDTEC: {1}, MDT: {0}'.format(self.MDT, self.CMDTEC))
- self.thread_keepalive.start()
- elif eventToken1 == b'\x04':
- if eventToken2 == b'\x04': # Bulle server. MOVE
- try:
- msg = unpack('!ibbhhhhbbbi', msg) # id, moving_right, moving_left, x, y,
- except Exception as e:
- Logger.error('error {0} unapropriated move packet {1}'.format(e, msg))
- return
- Logger.debug('Recieved MOVE request {0}'.format(msg))
- for i in self.players:
- if msg[-1] == self.players[i][0]:
- Logger.debug('Moving {0}'.format(i))
- if msg[1] >0 or msg[2] > 0:
- self.players[i][1] = msg[1]
- self.players[i][2] = msg[2]
- self.players[i][3] = int(msg[3])
- self.players[i][4] = int(msg[4])
- Logger.debug(self.players)
- elif eventToken2 == b'\x09': # Bulle server. CROUCH
- Logger.debug('Recieved CROUCH request {0}'.format(msg))
- if re.match(b'^\x01[0-9]+\x01$', msg):
- target = int(re.search(b'^\x01([0-9]+)\x01$', msg).group(1))
- for i in self.players:
- if Mouse.MODE == 'SPIRITFLY' and target == self.players[i][0]:
- self.actionSP(int(self.players[i][3]*800/2700), int(self.players[i][4]*800/2700))
- elif eventToken1 == b'\x05':
- if eventToken2 == b'\x05': # Bulle server. Recv NEW_MAP packet
- try:
- msg = msg.split(b'\x01')
- Mouse.map_id = msg[1]
- Mouse.roundNumber = msg[3]
- except Exception as e:
- Logger.error('Recv round info faild: {0} {1}'.format(e, msg))
- finally:
- Logger.info('map_id {0}, round num {1}'.format(Mouse.map_id, Mouse.roundNumber))
- if Mouse.MODE == 'EGG':
- time.sleep(1)
- self.getCheese()
- time.sleep(1)
- self.getEgg()
- time.sleep(1)
- self.getHole()
- elif Mouse.MODE == 'CHEESEHOLE':
- time.sleep(1)
- self.getCheese()
- time.sleep(1)
- self.getHole()
- elif eventToken1 == b'\x06': # Recv message:
- if eventToken2 == b'\x06': # Bulle server. Recv chat message
- message = msg.split(b'\x00')
- try:
- Logger.info('[c][{0}]: {1}'.format(str(message[-2][1:], 'utf8'), str(message[-1][1:], 'utf8')))
- message = str(message[-1][1:], 'utf8')
- if message == 'сырнора' or message == 'норасыр':
- Logger.info('Recv command cheesehole: {0}'.format(message))
- self.getCheese()
- time.sleep(1)
- self.getHole()
- except ValueError as e:
- Logger.error('Recv chat message error {0} in {1}'.format(e, msg))
- elif eventToken2 == b'\x07': # Main server. Recv private message
- dest = msg[:1]
- msg = msg[1:].split(b'\x00')
- msg[0] = dest
- try:
- user = str(msg[1][1:-1], 'utf8')
- message = str(msg[2][1:], 'utf8')
- except ValueError as e:
- Logger.error('Recv private message error {0} in {1}'.format(e, msg))
- return
- rank = (lambda x: x if x else (0,))(self.dbcursor.execute('SELECT rights FROM users WHERE user = ?', (user,)).fetchone())[0]
- Logger.info('rank = {0}'.format(rank))
- Logger.debug(msg)
- 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])))
- if re.match('\.cheese', message) and rank > 9:
- Logger.info('Recv command .cheese in round {0}'.format(Mouse.roundNumber))
- self.BULLE.getCheese()
- elif re.match('\.hole', message) and rank > 9:
- Logger.info('Recv command .hole in round {0}'.format(Mouse.roundNumber))
- self.BULLE.getHole()
- elif re.match('\.egg', message) and rank > 9:
- Logger.info('Recv command .egg in round {0}'.format(Mouse.roundNumber))
- self.BULLE.getEgg()
- elif re.match('\.die', message) or re.match('\.eid', message) and rank >= 0:
- Logger.info('Recv command .die in round {0}'.format(Mouse.roundNumber))
- self.BULLE.actionDie()
- elif re.match('\.spawn', message) and rank > 9:
- Logger.info('Recv command .spawn in round {0}'.format(Mouse.roundNumber))
- self.BULLE.actionSpawn(35)
- elif re.match('\.move', message) and rank > 9:
- Logger.info('Recv command .move in round {0}'.format(Mouse.roundNumber))
- self.BULLE.actionMove()
- elif re.match('\.room\s+[\w\*\s]+', message) and rank > 9:
- Logger.info('Recv command .room {0}'.format(message))
- Mouse.room = bytes(re.search('\.room\s+([\w\*\s]+)', message).group(1), 'utf8')
- Logger.info(Mouse.room)
- self.gotoRoom(Mouse.room)
- elif re.match('\.tribe', message) and rank > 9:
- Logger.info('Recv command .tribe {0}'.format(message))
- Mouse.room = b''
- self.gotoTribe()
- elif re.match('\.mode\s+\w+', message) and rank > 9:
- Mouse.MODE = re.search('\.mode\s+(\w+)', message).groups(1)[0]
- Logger.info('Recv command .mode {0} in message {1}'.format(Mouse.MODE, message))
- elif re.match('\.user\s+add\s+[A-Za-z0-9]+\s+\d+', message) and rank > 9:
- Logger.info('Recv command .user add {0}'.format(message))
- (user, rank) = re.search('\.user\s+add\s+([A-Za-z0-9]+)\s+(\d+)', message).groups()
- Logger.info('User {0} now has rank {1}'.format(user, rank))
- elif re.match('\.test', message) and rank > 9:
- Logger.info('Recv command .test in round {0}'.format(Mouse.roundNumber))
- self.sendPM(b'Oyaeby', bytes('test message', 'utf8'))
- #self.BULLE.sendCM(bytes('кукареку', 'utf8'))
- #self.sendTM(bytes('пук пук', 'utf8'))
- elif eventToken2 == b'\x08': # Main server. Recv tribe message
- message = msg.split(b'\x00')
- try:
- Logger.info('[t][{1}]: {0}'.format(str(message[1][1:], 'utf8'), str(message[2][1:], 'utf8')))
- except ValueError as e:
- Logger.error('Recv tribe message error {0} in {1}'.format(e, msg))
- elif eventToken2 == b'\x11': # Bulle server. Recv 0.20s
- Logger.debug('recieved 0.20 packet in round {0}'.format(Mouse.roundNumber))
- self.actionDie()
- elif eventToken1 == b'\x08':
- if eventToken2 == b'\x09': # Bulle server. Recv room players
- msg = msg.split(b'\x01')
- self.players = {}
- for i in msg[1:]: # id, moving_right, moving_left, x, y,
- self.players[i.split(b'#')[0]] = [int(i.split(b'#')[1]), 1, 0, 0, 0]
- Logger.info('Room players: {0}'.format(self.players))
- Logger.info('Sending ANTIAFK packet')
- self.actionAntiafk()
- def buildPacket(self, CC, data, proto='new'):
- loc3 = self.CMDTEC % 9000 + 1000
- self.FINGERPRINT = b''
- self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 1000)])
- self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 100) % 10])
- self.FINGERPRINT += pack('b', self.MDT[int(loc3 / 10) % 10])
- self.FINGERPRINT += pack('b', self.MDT[loc3 % 10])
- self.CMDTEC += 1
- packet = self.FINGERPRINT + (lambda : b'\x01\x01' + pack('!h', len(data) + 2) if proto == 'old' else b'')() + CC + data
- packet = pack('!i', len(packet) + 4) + packet
- self.write(packet)
- def keepalive(self):
- iteration = 0
- while self.isConnected:
- iteration += 1
- if Mouse.MODE == 'WIND' and self.isBULLE:
- self.actionWind()
- if iteration % 10 == 0:
- self.buildPacket(b"\x1a\x02", b'')
- if iteration > 180: iteration = 0
- time.sleep(1)
- Logger.debug('Keepalive thread closed')
- Logger = logging.getLogger('TFMBot')
- Logger.setLevel(Mouse.DEBUG_LVL)
- #ch = logging.FileHandler('tfmbot_txt'+ str(time.time()) +'.log', encoding='utf-8')
- ch = logging.StreamHandler()
- ch.setLevel(Mouse.DEBUG_LVL)
- ch.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
- Logger.addHandler(ch)
- s_main = TFMBot()
Advertisement
Add Comment
Please, Sign In to add comment