def authenticate(self): with self.rlock: if self.offline: self.auth_token = None return None tokens = load_auth_tokens() if self.auth_token is None: token = tokens.get(self.uname.lower()) if token is not None: self.auth_token = authentication.AuthenticationToken( username=self.uname, access_token=token['accessToken'], client_token=token['clientToken']) if self.auth_token is not None: try: self.auth_token.refresh() except YggdrasilError: self.auth_token = None if self.auth_token is None: try: self.auth_token = authentication.AuthenticationToken() self.auth_token.authenticate(self.uname, self.pword) except YggdrasilError: self.auth_token = None self._authenticate_save(tokens=tokens) raise self._authenticate_save(tokens=tokens) return self.auth_token
def __init__(self, username, password, *, admins=None): """ Init handles the following: - Client Authentication - Setting the current connection state - Setting the recognized 'admins' for this instance Parameters ---------- username : String Used for authentication password : String Used for authentication admins : list, optional The minecraft accounts to auto accept tpa's requests from Raises ------ YggdrasilError Username or Password was incorrect """ self.kickout = False self.admins = [] if admins is None else admins self.auth_token = authentication.AuthenticationToken() self.auth_token.authenticate(username, password)
def run(self): self.logger.debug( "Checking if the server {} is online before connecting.") if not self.config.mc_online: self.logger.info("Connecting in offline mode...") while not self.is_server_online(): self.logger.info( 'Not connecting to server because it appears to be offline.' ) time.sleep(15) self.bot_username = self.config.mc_username self.connection = Connection( self.config.mc_server, self.config.mc_port, username=self.config.mc_username, handle_exception=self.minecraft_handle_exception) else: self.auth_token = authentication.AuthenticationToken() try: self.auth_token.authenticate(self.config.mc_username, self.config.mc_password) except YggdrasilError as ex: self.logger.info(ex) sys.exit(os.EX_TEMPFAIL) self.bot_username = self.auth_token.profile.name self.logger.info("Logged in as %s...", self.auth_token.profile.name) while not self.is_server_online(): self.logger.info( 'Not connecting to server because it appears to be offline.' ) time.sleep(15) self.connection = Connection( self.config.mc_server, self.config.mc_port, auth_token=self.auth_token, handle_exception=self.minecraft_handle_exception) self.register_handlers(self.connection) self.connection_retries += 1 self.reactor_thread.start() self.connection.connect() try: self.aioloop.run_until_complete( self.discord_bot.start(self.config.discord_token)) except (KeyboardInterrupt, SystemExit): # log out of discord self.aioloop.run_until_complete(self.discord_bot.logout()) # log out of minecraft self.connection.disconnect() # shut down auth server from twisted.internet import reactor reactor.callFromThread(reactor.stop) # clean up auth server thread self.reactor_thread.join() finally: # close the asyncio event loop discord uses self.aioloop.close() return self.return_code
def main(): options = get_options() auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as " + auth_token.username) connection = Connection(options.address, options.port, auth_token) connection.connect() def print_chat(chat_packet): print("Position: " + str(chat_packet.position)) print("Data: " + chat_packet.json_data) connection.register_packet_listener(print_chat, ChatMessagePacket) while True: try: text = input() packet = ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def create_auth_token(user_data): """ Creates an `AuthenticationToken` instance from `user_data` If the provided accessToken is invalid, return `None` """ auth_token = authentication.AuthenticationToken( username=user_data["username"], access_token=user_data["accessToken"], client_token=user_data["clientToken"], ) profile = authentication.Profile(id_=user_data["uuid"], name=user_data["displayName"]) auth_token.profile = profile if auth_token.validate(): print("Validation passed") return auth_token else: print("Validation failed, attempting refresh") try: auth_token.refresh() except YggdrasilError as e: print("Unable to refresh token:", e) return None else: print("Token successfully refreshed!") return auth_token
def main(): options = get_options() auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() connection = Connection(options.address, options.port, auth_token) connection.connect() print("Logged in as " + auth_token.username) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("", 9001)) s.listen(5) connection.register_packet_listener(print_chat, ChatMessageClientboundPacket) #send_message("GET http://www.google.com/ HTTP/1.1\r\nhost: www.google.com\r\n\r\n", "address", connection) #GET http://www.uga.edu/ HTTP/1.1\r\nHost: www.uga.edu\r\n #time.sleep(100) #sys.exit() while True: try: (conn, addr) = s.accept() print("got packet") data = conn.recv(8192) send_message(data, addr, connection) except KeyboardInterrupt: sys.exit() s.close()
def main(): config = read_config() # split port and host match = re.match( r"((?P<host>[^\[\]:]+)|\[(?P<addr>[^\[\]]+)\])" r"(:(?P<port>\d+))?$", config["server"]) if match is None: raise ValueError(f"Invalid server address: '{config['server']}'") address = match.group("host") or match.group("addr") port = int(match.group("port") or 25565) auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(config["username"], config["password"]) except YggdrasilError as e: print(e) sys.exit() print(f"Authenticated successfully as {auth_token.username}") connection = Connection(address, port, auth_token=auth_token) def handle_goodbye(signum, frame): print("Signing out!") payload = { 'username': config["username"], 'password': config["password"] } try: authentication._make_request(authentication.AUTH_SERVER, "signout", payload) except: print("Failed to sign out with Yggdrasil") finally: sys.exit() def handle_disconnect(): print("Disconnected from server") if config["reconnect"] == True: connection.connect() else: sys.exit() connection.register_packet_listener( lambda packet: print(f"Connected to {address}!"), clientbound.play.JoinGamePacket) connection.register_packet_listener(handle_disconnect, clientbound.login.DisconnectPacket) try: connection.connect() except Exception as err: print(err) print("Failed to connect to specified server") sys.exit() signal.signal(signal.SIGINT, handle_goodbye) while True: time.sleep(1)
def authenticate(self): auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(self.email, self.password) return auth_token except YggdrasilError as e: input(e) sys.exit()
def __init__(self, username, password, bot_ign, reply_rate=20, whitelist=False): self.username = username self.password = password self.bot_ign = bot_ign self.debug = False self.whitelist = whitelist self.reply_rate = int(reply_rate) self.auth_token = authentication.AuthenticationToken() try: self.auth_token.authenticate(self.username, self.password) except YggdrasilError as error: print(error) exit() print("Logged in as %s." % self.auth_token.username) self.connection = Connection("mc.hypixel.net", 25565, auth_token=self.auth_token) self.command_delay = 0 self.msgQueue = [] self.partyQueue = [] self.commandQueue = [] self.msgCurrentChannel = "" self.party = {"inP": False, "from": "", "timestamp": 0} self.partyConfig = {} self.playercooldown = {} self.cooldownTimer = time.time() self.heartbeat = time.time() + 120 self.heartbeatCooldown = time.time() + 120 self.msgformat = msgformat.formats(self.bot_ign, 24) self.bots = {x: 0 for x in msgformat.bots if x != self.bot_ign} self.current_load = 0 self.inQueue = False self.inQueueTime = 0 self.muted = False self.muteDuration = 3600 self.unmutetime = 0 self.muteheartbeat = 0 self.leaderBuffer = [] self.mods = [] self.whitelisted = [] try: with open("whitelisted.txt", "r") as file: self.whitelisted = [x for x in file.read().split("\n")] except Exception: self.whitelisted = [] print("whitelisted loaded", len(self.whitelisted))
def authenticate_user(user_data): while True: if "username" in user_data: # Try using stored username to authenticate print("Ctrl+d to use a different account") try: username, password = get_credentials( username=user_data["username"]) except EOFError: # User aborted login - prompt for # new username+password username, password = get_credentials() else: username, password = get_credentials() # Update username in user_data user_data["username"] = username # Authenticate with mojang using username+password # Select clientToken if "clientToken" in user_data: # Use stored clientToken auth_token = authentication.AuthenticationToken( client_token=user_data["clientToken"]) else: # Use no clientToken - later store recieved # clientToken as new clientToken auth_token = authentication.AuthenticationToken() # Authenticate with given username+password try: auth_token.authenticate(username, password) except YggdrasilError as e: print("Authentication failed:", e) # Retry login continue else: # Authentication succeeded return auth_token
def __init__(self, terminal: Terminal, options: object): """ Parameters ---------- terminal : Terminal class representing and managing the terminal and it's subwindows options : object options parsed by the argument parser """ self._terminal = terminal auth_token = authentication.AuthenticationToken() if options.auth_type == 'Mojang': try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() # TODO Use correct status and not default to 0 as it's a failure self._client = Client(auth_token.profile.name, auth_token.profile.id_) self._terminal.info.update(self._client.name, util.format_uuid(self._client.uuid)) self._terminal.console.log('Successfully authenticated') self._address = options.address self._port = options.port self._connection = Connection(self._address, self._port, auth_token=auth_token) if hasattr(options, 'Bot'): self._bot = options.Bot(self._terminal, self._connection, self._client) else: self._bot = None self._register_listeners() self._connection.connect() while (True): key = self._terminal.stdscr.getkey() if (key == 'q'): sys.exit(0) if (key == 'KEY_UP'): self._terminal.console.scroll_up() elif (key == 'KEY_DOWN'): self._terminal.console.scroll_down() else: if hasattr(self._bot, 'keys') and key in self._bot.keys and inspect.ismethod(self._bot.keys[key]): self._bot.keys[key]()
def __init__(self, account: str, password: str, server_address: str, port: int, version: int, auto_reconnect: bool, auto_respawn: bool, lang: Lang): self.__email = account self.__password = base64.b64encode(password.encode()) self.__lang = lang self.__logger = logging.getLogger("Auth") logging.basicConfig(level=logging.INFO) tokens = self.__get_tokens() self.__auth = authentication.AuthenticationToken( username=self.__email, access_token=tokens["access"], client_token=tokens["client"]) self.auth() self.__auto_reconnect = auto_reconnect self.__auto_respawn = auto_respawn self.__connection = Connection(address=server_address, port=port, initial_version=version, auth_token=self.__auth) if not self.__auth.authenticated: return self.username = self.__auth.profile.name self.__logger = logging.getLogger(self.username) self.__connection.register_packet_listener( self.handle_join_game, clientbound.play.JoinGamePacket) self.__connection.register_packet_listener( self.print_chat, clientbound.play.ChatMessagePacket) self.__connection.register_packet_listener( self.handle_disconnect, clientbound.play.DisconnectPacket) self.__connection.register_packet_listener( self.handle_health_change, clientbound.play.UpdateHealthPacket) self.__connection.register_exception_handler(self.handle_exception) try: self.__connection.connect() except Exception as e: self.__logger.error(str(e)) self.__retry()
def new_connection(): m=authentication.AuthenticationToken() auth=False while not auth: #Retry authentication until we get it try: auth=m.authenticate(user,pw) except YggdrasilError as e: #If authentication fails print(e) time.sleep(5) print("Retrying...") c=Connection(server_ip,auth_token=m,initial_version=server_version) c.allowed_proto_versions={SUPPORTED_MINECRAFT_VERSIONS[server_version]} c.register_packet_listener(keep_alive,KeepAlivePacketClientbound) c.register_packet_listener(process_chat,ChatMessagePacket,early=True) c.register_packet_listener(respawn,UpdateHealthPacket) c.register_packet_listener(set_slot,SetSlotPacket) if debug: c.register_packet_listener(in_out,Packet,outgoing=True) c.register_packet_listener(lambda x:in_out(x,"IN"),Packet) return c
def main(): options = get_options() if options.offline: print("Connecting in offline mode") connection = Connection( options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as " + auth_token.username) connection = Connection( options.address, options.port, auth_token=auth_token) connection.connect() def print_chat(chat_packet): print("Position: " + str(chat_packet.position)) print("Data: " + chat_packet.json_data) connection.register_packet_listener(print_chat, ChatMessagePacket) while True: try: text = input() if text == "/respawn": print("respawning...") packet = ClientStatusPacket() packet.action_id = ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def __init__(self, options): self.auth_token = authentication.AuthenticationToken() try: self.auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as " + self.auth_token.username) self.network = Connection(options.address, options.port, self.auth_token) self.network.connect() self.register_listeners() #sys.stdout = Speaker(self) while not self.network.playing: pass self.respawn() while True: try: self.tick() except KeyboardInterrupt: print("Bye!") sys.exit()
def minecraft_handle_exception(self, exception, exc_info): self.logger.error("A minecraft exception occured! %s:", exception, exc_info=exc_info) if isinstance(exception, YggdrasilError): if (exception.yggdrasil_error == "ForbiddenOperationException" and exception.yggdrasil_error == "Invalid token"): self.logger.info( "Authentication token expired. Re-authenticating with Mojang." ) new_auth_token = authentication.AuthenticationToken() try: new_auth_token.authenticate(*self.credentials) self.connection.auth_token = new_auth_token except YggdrasilError as yggdrasil_err: self.logger.error( "Error while re-authenticating with Mojang.") self.logger.error(yggdrasil_err) self.logger.info('Reconnecting.') self.connection.connect() return self.handle_disconnect()
def main(): auth_token = authentication.AuthenticationToken() try: with open('minecraft.auth', 'r') as f: auth_token.client_token, auth_token.access_token = f.read().splitlines() # Library has issues need to do some hackey stuff to make sure it works. # I would use validate, but that would require some rewriting as well. auth_token.username = "******" auth_token.refresh() except (IOError, YggdrasilError): # IF there is no authentication file authenticate using username and password try: options = get_options() auth_token.authenticate(options["username"], options["password"]) except YggdrasilError as e: print(e) sys.exit() with open('minecraft.auth', 'w') as fout: fout.write(auth_token.client_token + '\n') fout.write(auth_token.access_token) print("Logged in as %s..." % auth_token.username) connection = Connection( "localhost", 25565, auth_token=auth_token) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener( handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): print("Message (%s): %s" % ( chat_packet.field_string('position'), chat_packet.json_data)) connection.register_packet_listener( print_chat, clientbound.play.ChatMessagePacket) global connected connected = True def disconnect(disconnect_packet): print("You were disconnected: %s" % disconnect_packet.json_data) global connected connected = False connection.register_packet_listener(disconnect, clientbound.play.DisconnectPacket) connection.connect() while connected: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection( options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection( options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener( print_incoming, Packet, early=True) connection.register_packet_listener( print_outgoing, Packet, outgoing=True) once = False def handle_join_game(join_game_packet): message_queue.append(("CONNECTION", "**Connected**")) once = True print('Connected.') connection.register_packet_listener( handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): print("[%s]: %s" % ( chat_packet.field_string('position'), parse_chat_item(json.loads(chat_packet.json_data)))) connection.register_packet_listener( print_chat, clientbound.play.ChatMessagePacket) # Add a deque for chat messages and register a method to get them message_queue = deque() def forward_chat(chat_packet): msg = parse_chat_item(json.loads(chat_packet.json_data)) if msg.startswith("<"): author, message = parse_message(msg) if (author != auth_token.username and message != ""): # Don't put in queue your own messages! message_queue.append((author, message)) connection.register_packet_listener( forward_chat, clientbound.play.ChatMessagePacket) # More maybe? Add here shit for a chatbot # Auto respawn because we can't send chat while dead def auto_respawn(update_health_packet): if update_health_packet.health <= 0: print("Respawning") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) connection.register_packet_listener( auto_respawn, clientbound.play.UpdateHealthPacket) # Start the discord thread and provide the message deque botThread = DiscordBotThread(message_queue, connection) botThread.daemon = True botThread.start() connection.connect() while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) # debug chat callback def print_chat(chat_packet): print("Message (%s): %s" % (chat_packet.field_string('position'), chat_packet.json_data)) # lists serves as output message queues outQueue = [] # boolean to tell if we are running running = True # console input callback def input_thread(): while running: text = input() outQueue.append(text) time.sleep(0.1) # helper function to insert into message queue def insert_into_queue(message, player, globalFlag): if globalFlag: outQueue.append(message) else: outQueue.append('/msg ' + player + ' ' + message) # helper function to handle commands def process_message(message, player, playerId, globalFlag): if message == '$whoami': insert_into_queue('You are ' + player + '!', player, globalFlag) if message == '$selling': try: dealFile = open('deals.json', 'r') deals = json.loads(dealFile.read()) dealFile.close() items = [] for item in deals['selling']: items.append(item['item']) insert_into_queue('Selling these items: ' + str(items), player, globalFlag) except: insert_into_queue( 'Sorry! Deals are not available at this time.', player, globalFlag) if message == '$buying': try: dealFile = open('deals.json', 'r') deals = json.loads(dealFile.read()) dealFile.close() insert_into_queue( 'Buying these items: ' + str(deals['buying']), player, globalFlag) except: insert_into_queue( 'Sorry! Deals are not available at this time.', player, globalFlag) if message == '$reps': try: dealFile = open('deals.json', 'r') deals = json.loads(dealFile.read()) dealFile.close() outQueue.append('Representatives of Astara: ' + str(deals['representatives'])) except: insert_into_queue( 'Sorry! Database is not available at this time.', player, globalFlag) if message == '$help': insert_into_queue('Hi! I\'m the Astaran Trade Bot. Minimum trade value is 1db.' + \ ' Here are some commands you can use: $selling, $buying, $price <item>, ' + \ '$whoami, $reps, $help', player, globalFlag) if message.startswith('$price '): try: query = message[7:] dealFile = open('deals.json', 'r') deals = json.loads(dealFile.read()) dealFile.close() name = '' price = '' for item in deals['selling']: for alias in item['alias']: if query.lower() == alias.lower(): name = item['item'] price = item['price'] break if name != '': break if name == '' or price == '': insert_into_queue('Sorry! No price listed for that item.', player, globalFlag) else: insert_into_queue('Astara sells ' + name + ' for ' + price, player, globalFlag) except: insert_into_queue('Sorry! No price listed for that item.', player, globalFlag) # chat processing callback def process_chat(chat_packet): position = chat_packet.field_string('position') if position == 'CHAT' or position == 'SYSTEM': data = json.loads(chat_packet.json_data) # Global Chat if data['translate'] == 'chat.type.text': # grab useful data from json message = data['with'][1] player = data['with'][0]['insertion'] hoverStr = data['with'][0]['hoverEvent']['value']['text'] start = hoverStr.index('id:\"') + 4 end = hoverStr.index('\",type:') playerId = hoverStr[start:end] # print chat message outStr = playerId + ' (' + player + '): ' + message print(outStr) # log message log = open('log.txt', 'a') log.write(outStr + '\n') log.close() # process message process_message(message, player, playerId, True) # Private Chat if data['translate'] == 'commands.message.display.incoming': # grab useful data from json message = data['with'][1]['text'] player = data['with'][0]['insertion'] hoverStr = data['with'][0]['hoverEvent']['value']['text'] start = hoverStr.index('id:\"') + 4 end = hoverStr.index('\",type:') playerId = hoverStr[start:end] # print chat message outStr = playerId + ' (' + player + ') PRIVATE: ' + message print(outStr) # log message log = open('log.txt', 'a') log.write(outStr + '\n') log.close() # process message process_message(message, player, playerId, False) # Register Debug callback #connection.register_packet_listener( # print_chat, clientbound.play.ChatMessagePacket) # Register our chatbot logic connection.register_packet_listener(process_chat, clientbound.play.ChatMessagePacket) # start network thread connection.connect() # start console thread inThread = threading.Thread(target=input_thread) inThread.start() # Main bot console loop while running: try: time.sleep(0.05) if len(outQueue) != 0: msg = outQueue.pop() if msg == '/respawn': print('Respawning...') packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) elif msg == '/exit': print('Disconnecting') running = False else: print('Sent Message: ' + msg) packet = serverbound.play.ChatPacket() packet.message = msg connection.write_packet(packet) except KeyboardInterrupt: outQueue.append('/exit')
def main(): global BOT_USERNAME config = Configuration("config.json") setup_logging(config.logging_level) database_session.initialize(config) if config.es_enabled: el.initialize(config) reactor_thread = Thread(target=run_auth_server, args=(config.auth_port, )) reactor_thread.start() def handle_disconnect(): log.info('Disconnected.') global PLAYER_LIST, PREVIOUS_PLAYER_LIST, ACCEPT_JOIN_EVENTS PREVIOUS_PLAYER_LIST = PLAYER_LIST.copy() ACCEPT_JOIN_EVENTS = False PLAYER_LIST = bidict() if connection.connected: log.info( "Forced a disconnection because the connection is still connected." ) connection.disconnect(immediate=True) time.sleep(15) while not is_server_online(): log.info( 'Not reconnecting to server because it appears to be offline.') time.sleep(15) log.info('Reconnecting.') connection.connect() def handle_disconnect_packet(join_game_packet): handle_disconnect() def minecraft_handle_exception(exception, exc_info): log.error("A minecraft exception occured! {}:".format(exception), exc_info=exc_info) handle_disconnect() def is_server_online(): server = MinecraftServer.lookup("{}:{}".format(config.mc_server, config.mc_port)) try: status = server.status() del status return True except ConnectionRefusedError: return False # AttributeError: 'TCPSocketConnection' object has no attribute 'socket' # This might not be required as it happens upstream except AttributeError: return False log.debug("Checking if the server {} is online before connecting.") if not config.mc_online: log.info("Connecting in offline mode...") while not is_server_online(): log.info( 'Not connecting to server because it appears to be offline.') time.sleep(15) BOT_USERNAME = config.mc_username connection = Connection(config.mc_server, config.mc_port, username=config.mc_username, handle_exception=minecraft_handle_exception) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(config.mc_username, config.mc_password) except YggdrasilError as e: log.info(e) sys.exit() BOT_USERNAME = auth_token.profile.name log.info("Logged in as %s..." % auth_token.profile.name) while not is_server_online(): log.info( 'Not connecting to server because it appears to be offline.') time.sleep(15) connection = Connection(config.mc_server, config.mc_port, auth_token=auth_token, handle_exception=minecraft_handle_exception) # Initialize the discord part discord_bot = discord.Client() def register_handlers(connection): connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) connection.register_packet_listener(handle_chat, clientbound.play.ChatMessagePacket) connection.register_packet_listener( handle_health_update, clientbound.play.UpdateHealthPacket) connection.register_packet_listener(handle_disconnect_packet, clientbound.play.DisconnectPacket) connection.register_packet_listener( handle_tab_list, clientbound.play.PlayerListItemPacket) connection.register_packet_listener( handle_player_list_header_and_footer_update, clientbound.play.PlayerListHeaderAndFooterPacket) def handle_player_list_header_and_footer_update(header_footer_packet): global TAB_FOOTER, TAB_HEADER log.debug("Got Tablist H/F Update: header={}".format( header_footer_packet.header)) log.debug("Got Tablist H/F Update: footer={}".format( header_footer_packet.footer)) TAB_HEADER = json.loads(header_footer_packet.header)["text"] TAB_FOOTER = json.loads(header_footer_packet.footer)["text"] def handle_tab_list(tab_list_packet): global ACCEPT_JOIN_EVENTS log.debug("Processing tab list packet") for action in tab_list_packet.actions: if isinstance( action, clientbound.play.PlayerListItemPacket.AddPlayerAction): log.debug( "Processing AddPlayerAction tab list packet, name: {}, uuid: {}" .format(action.name, action.uuid)) username = action.name player_uuid = action.uuid if action.name not in PLAYER_LIST.inv: PLAYER_LIST.inv[action.name] = action.uuid else: # Sometimes we get a duplicate add packet on join idk why return if action.name not in UUID_CACHE.inv: UUID_CACHE.inv[action.name] = action.uuid # Initial tablist backfill if ACCEPT_JOIN_EVENTS: webhook_payload = { 'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format( player_uuid), 'content': '', 'embeds': [{ 'color': 65280, 'title': '**Joined the game**' }] } for webhook in WEBHOOKS: requests.post(webhook, json=webhook_payload) if config.es_enabled: el.log_connection(uuid=action.uuid, reason=el.ConnectionReason.CONNECTED, count=len(PLAYER_LIST)) return else: # The bot's name is sent last after the initial back-fill if action.name == BOT_USERNAME: ACCEPT_JOIN_EVENTS = True if config.es_enabled: diff = set(PREVIOUS_PLAYER_LIST.keys()) - set( PLAYER_LIST.keys()) for idx, player_uuid in enumerate(diff): el.log_connection( uuid=player_uuid, reason=el.ConnectionReason.DISCONNECTED, count=len(PREVIOUS_PLAYER_LIST) - (idx + 1)) # Don't bother announcing the bot's own join message (who cares) but log it for analytics still if config.es_enabled: el.log_connection( uuid=action.uuid, reason=el.ConnectionReason.CONNECTED, count=len(PLAYER_LIST)) if config.es_enabled: el.log_connection(uuid=action.uuid, reason=el.ConnectionReason.SEEN) if isinstance( action, clientbound.play.PlayerListItemPacket.RemovePlayerAction): log.debug( "Processing RemovePlayerAction tab list packet, uuid: {}". format(action.uuid)) username = mc_uuid_to_username(action.uuid) player_uuid = action.uuid webhook_payload = { 'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format( player_uuid), 'content': '', 'embeds': [{ 'color': 16711680, 'title': '**Left the game**' }] } for webhook in WEBHOOKS: requests.post(webhook, json=webhook_payload) del UUID_CACHE[action.uuid] del PLAYER_LIST[action.uuid] if config.es_enabled: el.log_connection(uuid=action.uuid, reason=el.ConnectionReason.DISCONNECTED, count=len(PLAYER_LIST)) def handle_join_game(join_game_packet): global PLAYER_LIST log.info('Connected.') PLAYER_LIST = bidict() def handle_chat(chat_packet): json_data = json.loads(chat_packet.json_data) if "extra" not in json_data: return chat_string = "" for chat_component in json_data["extra"]: chat_string += chat_component["text"] # Handle chat message regexp_match = re.match("<(.*?)> (.*)", chat_string, re.M | re.I) if regexp_match: username = regexp_match.group(1) original_message = regexp_match.group(2) player_uuid = mc_username_to_uuid(username) if username.lower() == BOT_USERNAME.lower(): # Don't relay our own messages if config.es_enabled: bot_message_match = re.match( "<{}> (.*?): (.*)".format(BOT_USERNAME.lower()), chat_string, re.M | re.I) if bot_message_match: el.log_chat_message( uuid=mc_username_to_uuid( bot_message_match.group(1)), display_name=bot_message_match.group(1), message=bot_message_match.group(2), message_unformatted=chat_string) el.log_raw_message(type=ChatType( chat_packet.position).name, message=chat_packet.json_data) return log.info( "Incoming message from minecraft: Username: {} Message: {}". format(username, original_message)) log.debug("msg: {}".format(repr(original_message))) message = escape_markdown( remove_emoji(original_message.strip().replace( "@", "@\N{zero width space}"))) webhook_payload = { 'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format(player_uuid), 'content': '{}'.format(message) } for webhook in WEBHOOKS: requests.post(webhook, json=webhook_payload) if config.es_enabled: el.log_chat_message(uuid=player_uuid, display_name=username, message=original_message, message_unformatted=chat_string) if config.es_enabled: el.log_raw_message(type=ChatType(chat_packet.position).name, message=chat_packet.json_data) def handle_health_update(health_update_packet): if health_update_packet.health <= 0: log.debug("Respawned the player because it died") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) register_handlers(connection) connection.connect() @discord_bot.event async def on_ready(): log.info("Discord bot logged in as {} ({})".format( discord_bot.user.name, discord_bot.user.id)) global WEBHOOKS WEBHOOKS = [] session = database_session.get_session() channels = session.query(DiscordChannel).all() session.close() for channel in channels: channel_id = channel.channel_id discord_channel = discord_bot.get_channel(channel_id) channel_webhooks = await discord_channel.webhooks() found = False for webhook in channel_webhooks: if webhook.name == "_minecraft" and webhook.user == discord_bot.user: WEBHOOKS.append(webhook.url) found = True log.debug("Found webhook {} in channel {}".format( webhook.name, discord_channel.name)) if not found: # Create the hook await discord_channel.create_webhook(name="_minecraft") @discord_bot.event async def on_message(message): # We do not want the bot to reply to itself if message.author == discord_bot.user: return this_channel = message.channel.id global WEBHOOKS # PM Commands if message.content.startswith("mc!help"): try: send_channel = message.channel if isinstance(message.channel, discord.abc.GuildChannel): await message.delete() dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel msg = get_discord_help_string() await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return elif message.content.startswith("mc!register"): try: # TODO: Catch the Forbidden error in a smart way before running application logic send_channel = message.channel if isinstance(message.channel, discord.abc.GuildChannel): await message.delete() dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel session = database_session.get_session() discord_account = session.query(DiscordAccount).filter_by( discord_id=message.author.id).first() if not discord_account: new_discord_account = DiscordAccount(message.author.id) session.add(new_discord_account) session.commit() discord_account = session.query(DiscordAccount).filter_by( discord_id=message.author.id).first() new_token = generate_random_auth_token(16) account_link_token = AccountLinkToken(message.author.id, new_token) discord_account.link_token = account_link_token session.add(account_link_token) session.commit() msg = "Please connect your minecraft account to `{}.{}:{}` in order to link it to this bridge!"\ .format(new_token, config.auth_dns, config.auth_port) session.close() del session await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return # Global Commands elif message.content.startswith("mc!chathere"): if isinstance(message.channel, discord.abc.PrivateChannel): msg = "Sorry, this command is only available in public channels." await message.channel.send(msg) return if message.author.id not in config.admin_users: await message.delete() try: dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() dm_channel = message.author.dm_channel msg = "Sorry, you do not have permission to execute that command!" await dm_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return session = database_session.get_session() channels = session.query(DiscordChannel).filter_by( channel_id=this_channel).all() if not channels: new_channel = DiscordChannel(this_channel) session.add(new_channel) session.commit() session.close() del session webhook = await message.channel.create_webhook( name="_minecraft") WEBHOOKS.append(webhook.url) msg = "The bot will now start chatting here! To stop this, run `mc!stopchathere`." await message.channel.send(msg) else: msg = "The bot is already chatting in this channel! To stop this, run `mc!stopchathere`." await message.channel.send(msg) return elif message.content.startswith("mc!stopchathere"): if isinstance(message.channel, discord.abc.PrivateChannel): msg = "Sorry, this command is only available in public channels." await message.channel.send(msg) return if message.author.id not in config.admin_users: await message.delete() try: dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() dm_channel = message.author.dm_channel msg = "Sorry, you do not have permission to execute that command!" await dm_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return session = database_session.get_session() deleted = session.query(DiscordChannel).filter_by( channel_id=this_channel).delete() session.commit() session.close() for webhook in await message.channel.webhooks(): if webhook.name == "_minecraft" and webhook.user == discord_bot.user: # Copy the list to avoid some problems since # we're deleting indicies form it as we loop # through it if webhook.url in WEBHOOKS[:]: WEBHOOKS.remove(webhook.url) await webhook.delete() if deleted < 1: msg = "The bot was not chatting here!" await message.channel.send(msg) return else: msg = "The bot will no longer chat here!" await message.channel.send(msg) return elif message.content.startswith("mc!tab"): send_channel = message.channel try: if isinstance(message.channel, discord.abc.GuildChannel): await message.delete() dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel player_list = ", ".join( list(map(lambda x: x[1], PLAYER_LIST.items()))) msg = "{}\n" \ "Players online: {}\n" \ "{}".format(escape_markdown( strip_colour(TAB_HEADER)), escape_markdown( strip_colour(player_list)), escape_markdown( strip_colour(TAB_FOOTER))) await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return elif message.content.startswith("mc!"): # Catch-all send_channel = message.channel try: if isinstance(message.channel, discord.abc.GuildChannel): await message.delete() dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel msg = "Unknown command, type `mc!help` for a list of commands." await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return elif not message.author.bot: session = database_session.get_session() channel_should_chat = session.query(DiscordChannel).filter_by( channel_id=this_channel).first() if channel_should_chat: await message.delete() discord_user = session.query(DiscordAccount).filter_by( discord_id=message.author.id).first() if discord_user: if discord_user.minecraft_account: minecraft_uuid = discord_user.minecraft_account.minecraft_uuid session.close() del session minecraft_username = mc_uuid_to_username( minecraft_uuid) # Max chat message length: 256, bot username does not count towards this # Does not count|Counts # <BOT_USERNAME> minecraft_username: message padding = 2 + len(minecraft_username) message_to_send = remove_emoji( message.clean_content.encode('utf-8').decode( 'ascii', 'replace')).strip() message_to_discord = escape_markdown( message.clean_content) total_len = padding + len(message_to_send) if total_len > 256: message_to_send = message_to_send[:(256 - padding)] message_to_discord = message_to_discord[:(256 - padding)] elif len(message_to_send) <= 0: return session = database_session.get_session() channels = session.query(DiscordChannel).all() session.close() del session global PREVIOUS_MESSAGE, NEXT_MESSAGE_TIME if message_to_send == PREVIOUS_MESSAGE or \ datetime.now(timezone.utc) < NEXT_MESSAGE_TIME: send_channel = message.channel try: if isinstance(message.channel, discord.abc.GuildChannel): dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel msg = "Your message \"{}\" has been rate-limited.".format( message.clean_content) await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: return PREVIOUS_MESSAGE = message_to_send NEXT_MESSAGE_TIME = datetime.now( timezone.utc) + timedelta( seconds=config.message_delay) log.info( "Outgoing message from discord: Username: {} Message: {}" .format(minecraft_username, message_to_send)) for channel in channels: webhooks = await discord_bot.get_channel( channel.channel_id).webhooks() for webhook in webhooks: if webhook.name == "_minecraft": await webhook.send( username=minecraft_username, avatar_url= "https://visage.surgeplay.com/face/160/{}" .format(minecraft_uuid), content=message_to_discord) packet = serverbound.play.ChatPacket() packet.message = "{}: {}".format( minecraft_username, message_to_send) connection.write_packet(packet) else: send_channel = message.channel try: if isinstance(message.channel, discord.abc.GuildChannel): dm_channel = message.author.dm_channel if not dm_channel: await message.author.create_dm() send_channel = message.author.dm_channel msg = "Unable to send chat message: there is no Minecraft account linked to this discord " \ "account, please run `mc!register`." await send_channel.send(msg) except discord.errors.Forbidden: if isinstance(message.author, discord.abc.User): msg = "{}, please allow private messages from this bot.".format( message.author.mention) error_msg = await message.channel.send(msg) await asyncio.sleep(3) await error_msg.delete() finally: session.close() del session return else: session.close() del session discord_bot.run(config.discord_token)
def main(): """Our main function for running the simple pyCraft implementation. This function handles and maintains: - Gaining authentication tokens & 'logging in' - Connecting to the provided server, online or offline - Prints the chat packet data to standard out on Clientbound Packet - Writes Serverbound chat Packets when required - Dumping all packets to standard out Notes ----- This is a blocking function. """ options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it # unless explicitly requested by the user. if options.dump_unknown: print("--> [unknown packet] %s" % packet, file=sys.stderr) else: print("--> %s" % packet, file=sys.stderr) def print_outgoing(packet): print("<-- %s" % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print("Connected.") connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): print("Message (%s): %s" % (chat_packet.field_string("position"), chat_packet.json_data)) connection.register_packet_listener(print_chat, clientbound.play.ChatMessagePacket) connection.connect() while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet, output="default"): if output == "raw": print( "Message (%s): %s" % (chat_packet.field_string('position'), chat_packet.json_data)) chat_json = json.loads(chat_packet.json_data) if output == "pretty": print( json.dumps(chat_json, sort_keys=True, indent=4, separators=(',', ': '))) if output == "default": message = Message(chat_json) ts = datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S') print("[{}] {}".format(colored(ts, "grey"), message.formatted_str)) connection.register_packet_listener(print_chat, clientbound.play.ChatMessagePacket) connection.connect() def requeue(realm): message = "/joinqueue " + realm packet = serverbound.play.ChatPacket() packet.message = message print(message) connection.write_packet(packet) # Re-join realm every 60 seconds rt = RepeatedTimer(60, requeue, options.realm) while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: rt.stop() print("Bye!") sys.exit()
def main(): options = get_options() def handle_exception(*args): print('handle exception') os.kill(os.getpid(), signal.SIGINT) if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username, handle_exception=handle_exception, handle_exit=handle_exception) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): print("Message (%s): %s" % (chat_packet.field_string('position'), chat_packet.json_data)) connection.register_packet_listener(print_chat, clientbound.play.ChatMessagePacket) connection.connect() def send(text): print("sending", text) packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) time.sleep(10) send("/server main") # time.sleep(3) # send("Hello world! I'm online!") while connection.connected: try: time.sleep(10) send("/server main") # text = input() # if text == "/respawn": # print("respawning...") # packet = serverbound.play.ClientStatusPacket() # packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN # connection.write_packet(packet) # else: # send(text) except KeyboardInterrupt: send("Bye!") print("Bye!") time.sleep(5) sys.exit()
def main(): options = get_options() assets = AssetsManager(options.assets) mcdata = DataManager("./mcdata") if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username, allowed_versions=[options.mcversion]) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) return print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token, allowed_versions=[options.mcversion]) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return if type(packet) in [ clientbound.play.EntityVelocityPacket, clientbound.play.EntityLookPacket ]: # Prevents useless console spam return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) chat = ChatManager(assets) chat.register(connection) chunks = ChunksManager(mcdata) chunks.register(connection) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) connection.connect() while True: try: text = input() if text.startswith("!"): if text == "!respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) elif text.startswith("!print "): p = text.split(" ") chunks.print_chunk( chunks.get_chunk(int(p[1]), int(p[2]), int(p[3])), int(p[4])) elif text == "!chunks": area = chunks.get_loaded_area() y_count = area[1][1] - area[0][1] print("Bounds: %s" % (area, )) for y in range(area[0][1], area[1][1]): print("Slice %d:" % (y)) for z in range(area[0][2], area[1][2]): for x in range(area[0][0], area[1][0]): if (x, y, z) in chunks.chunks: c = 'X' else: c = '.' print(c, end="") print() elif text == "!export": area = chunks.get_loaded_area(True) export_area(area[0][0] * 16, area[0][1] * 16, area[0][2] * 16, area[1][0] * 16, area[1][1] * 16, area[1][2] * 16, chunks, assets, mcdata) else: print("Unknow test command: %s" % (text)) else: chat.send(connection, text) except KeyboardInterrupt: print("Bye!") sys.exit() except Exception as ex: print("Exception: %s" % (ex)) traceback.print_exc()
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.profile.name) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it # unless explicitly requested by the user. if options.dump_unknown: print('--> [unknown packet] %s' % packet, file=sys.stderr) else: print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): js = ujson.loads(chat_packet.json_data) if len(js) == 1 and js.get('text'): js['translate'] = "MCDR" js['with'] = [0, 0, 0] try: translate = js['translate'] msg = js['with'][-1] if type(msg) is dict: msg = msg['text'] # 1.15.2 server message = '[{} {}] '.format( datetime.now().strftime("%Y-%m-%d %H:%M:%S"), chat_packet.field_string('position')) try: name = js['with'][0]['insertion'] except: name = None if translate == 'chat.type.announcement': # from server message += '[Server] {}'.format(msg) elif translate == 'chat.type.text': # chat message += '<{}> {}'.format(name, msg) try: uuid = js['with'][0]['hoverEvent']['contents'][ 'id'] # 1.16 server except: try: text = js['with'][0]['hoverEvent']['value']['text'] except TypeError: # 1.15.2 server text = js['with'][0]['hoverEvent']['value'][0]['text'] uuid = text[text.find(',id:"'):].split('"')[1] elif translate == 'commands.message.display.incoming': # tell message += '<{}>(tell) {}'.format(name, msg['text']) elif translate in [ 'multiplayer.player.joined', 'multiplayer.player.left' ]: # login in/out game message += '{} {} the game'.format(name, translate.split('.')[2]) elif translate == 'chat.type.emote': # me message += '* {} {}'.format(name, msg) elif translate == 'MCDR': message += js.get('text') else: message = chat_packet.json_data print(message) except: print('Cannot resolve chat json data: \n {}'.format( chat_packet.json_data)) pass connection.register_packet_listener(print_chat, clientbound.play.ChatMessagePacket) connection.connect() while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
from PIL import Image from discord import Webhook, AsyncWebhookAdapter from discord.ext.commands import Bot, check import discord.ext.commands with open(os.path.join(os.pardir, "config.json"), encoding="utf-8") as json_file: config = json.load(json_file) TOKEN = config['token'] CHANNEL = config['channelID'] webhook_url = config['webhook'] ACCOUNT = config["mcAcc"].split(":") #ACCOUNT = custom_answers = config["custom"] auth_token = authentication.AuthenticationToken() #auth_token.authenticate(ACCOUNT[0], ACCOUNT[1]) while 1: try: auth_token.authenticate(ACCOUNT[0], ACCOUNT[1]) break except: print("waiting for mojang cooldown") time.sleep(10) print("Logged in as %s..." % auth_token.username) connection = Connection("gommehd.net", auth_token=auth_token) #connection = Connection("localhost", 62139, username="******") ''' def print_incoming(packet):
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection( options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection( options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it # unless explicitly requested by the user. if options.dump_unknown: print('--> [unknown packet] %s' % packet, file=sys.stderr) else: print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener( print_incoming, Packet, early=True) connection.register_packet_listener( print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener( handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): print("Message (%s): %s" % ( chat_packet.field_string('position'), chat_packet.json_data)) connection.register_packet_listener( print_chat, clientbound.play.ChatMessagePacket) def handle_zzz(chat_packet): if json.loads(chat_packet.json_data).get("with", " ")[-1] == "zzz": connection.disconnect() time.sleep(5) connection.connect() connection.register_packet_listener( handle_zzz, clientbound.play.ChatMessagePacket) connection.connect() while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def main(): options = get_options() if options.offline: print("Connecting in offline mode...") connection = Connection(options.address, options.port, username=options.username) else: auth_token = authentication.AuthenticationToken() try: auth_token.authenticate(options.username, options.password) except YggdrasilError as e: print(e) sys.exit() print("Logged in as %s..." % auth_token.username) connection = Connection(options.address, options.port, auth_token=auth_token) if options.dump_packets: def print_incoming(packet): if type(packet) is Packet: # This is a direct instance of the base Packet type, meaning # that it is a packet of unknown type, so we do not print it. return print('--> %s' % packet, file=sys.stderr) def print_outgoing(packet): print('<-- %s' % packet, file=sys.stderr) connection.register_packet_listener(print_incoming, Packet, early=True) connection.register_packet_listener(print_outgoing, Packet, outgoing=True) def handle_join_game(join_game_packet): print('Connected.') connection.register_packet_listener(handle_join_game, clientbound.play.JoinGamePacket) def print_raw_json(chat_packet): print("Message (%s): %s" % (chat_packet.field_string('position'), chat_packet.json_data)) def print_raw_text(chat_packet): print("Message (%s): " % chat_packet.field_string('position'), end="") printRawText(json.loads(chat_packet.json_data)) print("") def print_color_text(chat_packet): print("Message (%s): " % chat_packet.field_string('position'), end="") printColorText(json.loads(chat_packet.json_data)) print("") def keep_alive(packet): print("keep_alive[%d] packet receive." % packet.keep_alive_id) from random import randint ret = serverbound.play.KeepAlivePacket() ret.keep_alive_id = randint(0, 10000) connection.write_packet(ret) print("Write packet ok.") connection.register_packet_listener(print_color_text, clientbound.play.ChatMessagePacket) connection.register_packet_listener(keep_alive, clientbound.play.KeepAlivePacket) connection.connect() while True: try: text = input() if text == "/respawn": print("respawning...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Bye!") sys.exit()
def onMessage(self, payload, isBinary): if not isBinary: message = json.loads(payload.decode('utf8')) if message["type"] == "login": try: if message["username"] in connections and message[ "password"] == connections[ message["username"]]["password"]: connections[message["username"]][ "connection"].register_packet_listener( self.sendPacket, Packet, early=True) self.username = message["username"] print("Resuming session as " + connections[ message["username"]]["auth_token"].username + " on " + message["host"]) return print("Trying to log in as " + message["username"] + " on " + message["host"] + ":" + message["port"]) auth_token = authentication.AuthenticationToken() auth_token.authenticate(message["username"], message["password"]) connection = Connection(message["host"], int(message["port"]), auth_token=auth_token) connection.register_packet_listener(self.sendPacket, Packet, early=True) connection.register_packet_listener(self.onGameJoin, JoinGamePacket, early=True) connection.register_packet_listener( self.onDisconnection, DisconnectPacket) connection.connect() @connection.exception_handler(LoginDisconnect, early=True) def onFailedLogin(exc, exc_info): data = {"type": "LoginDisconnect", "packet": str(exc)} self.sendMessage(json.dumps( data, ensure_ascii=False).encode('utf8'), isBinary=False) connections[self.username]["connection"].disconnect() connections.pop(self.username) self._closeConnection() connections[message["username"]] = { "password": message["password"], "host": message["host"], "port": message["port"], "auth_token": auth_token, "connection": connection } self.username = message["username"] print("Started new session as " + auth_token.username + " on " + message["host"]) except Exception as e: print("Error while logging in: " + repr(e)) self.sendMessage( ("Error while logging in: " + repr(e)).encode('utf8'), False) self._closeConnection() elif message["type"] == "respawn": packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connections[self.username]["connection"].write_packet(packet) elif message["type"] == "chat": packet = serverbound.play.ChatPacket() packet.message = message["message"] connections[self.username]["connection"].write_packet(packet) elif message["type"] == "disconnect": connections[self.username]["connection"].disconnect() connections.pop(self.username) self._closeConnection() elif message["type"] == "connect": connections[self.username]["connection"].connect()
def main(): args = sys.argv[1:] if (len(args) != 1): print("Uso : bot.py queue\nEx: bot.py towny") sys.exit() else: EMAIL = "" PASSWORD = "" MULTIMC_INSTANCE = "" auth = authentication.AuthenticationToken() try: auth.authenticate(EMAIL, PASSWORD) except YggdrasilError as e: print(e) sys.exit() print("Logado como %s" % auth.username) connection = Connection("dc-f626de6d73b7.earthmc.net", 25577, auth_token=auth, allowed_versions=[477]) def entra_server(join_game_packet): print("Conectado no servidor") packet = serverbound.play.ChatPacket() packet.message = ("/joinqueue %s" % (args[0])) connection.write_packet(packet) connection.register_packet_listener(entra_server, clientbound.play.JoinGamePacket) def mensagem(chat_packet): if (chat_packet.field_string( 'position' ) == "SYSTEM" and chat_packet.json_data.startswith( '{"extra":[{"color":"yellow","text":"You are currently in position ' )): result = queue_message_from_dict( json.loads(chat_packet.json_data)) print( "Pos : (%s) %s [%s]" % (result.extra[1].text[:-1], result.extra[3].text, args[0])) if (int(result.extra[1].text[:-1].replace(" ", ""), 10) <= 5): connection.disconnect() os.system('multimc -l "%s"' % (MULTIMC_INSTANCE)) elif (chat_packet.field_string('position') == "CHAT"): result = chat_message_from_dict( json.loads(chat_packet.json_data)) print("[%s] %s > %s" % (result.extra[0].hover_event.value[0].extra[1].text[:-1], result.extra[0].extra[0].text[:-2], result.extra[1].extra[0].text)) elif (chat_packet.field_string('position') != "SYSTEM"): print("UNHANDLED %s MESSAGE : \n(%s)" % (chat_packet.field_string('position'), chat_packet.json_data)) connection.register_packet_listener(mensagem, clientbound.play.ChatMessagePacket) connection.connect() while True: try: text = input() if text == "/respawn": print("Respawnando ...") packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN connection.write_packet(packet) else: packet = serverbound.play.ChatPacket() packet.message = text connection.write_packet(packet) except KeyboardInterrupt: print("Tchau!") sys.exit()