コード例 #1
0
 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
コード例 #2
0
    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)
コード例 #3
0
    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
コード例 #4
0
ファイル: start.py プロジェクト: virustotalop/pyCraft
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()
コード例 #5
0
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
コード例 #6
0
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()
コード例 #7
0
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)
コード例 #8
0
    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()
コード例 #9
0
ファイル: bwstatscore.py プロジェクト: Vyprath/Bedwars-Stats
    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))
コード例 #10
0
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
コード例 #11
0
    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]()
コード例 #12
0
    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()
コード例 #13
0
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
コード例 #14
0
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()
コード例 #15
0
 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()
コード例 #16
0
 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()
コード例 #17
0
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()
コード例 #18
0
ファイル: start.py プロジェクト: Merkie/Echo
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()
コード例 #19
0
ファイル: AstaraBot.py プロジェクト: priggec/pyCraft
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')
コード例 #20
0
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)
コード例 #21
0
ファイル: start.py プロジェクト: Skelmis/pyCraft
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()
コード例 #22
0
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()
コード例 #23
0
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()
コード例 #24
0
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()
コード例 #25
0
ファイル: start.py プロジェクト: Jerry-FaGe/pyCraft
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()
コード例 #26
0
ファイル: bot.py プロジェクト: xLeon-python/MCBot
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):
コード例 #27
0
ファイル: start.py プロジェクト: MissingNoShiny/pyCraft
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()
コード例 #28
0
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()
コード例 #29
0
    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()
コード例 #30
0
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()