diff --git a/bin/generate_travis_yml.py b/bin/generate_travis_yml.py index 387d0c2..89e2c7c 100755 --- a/bin/generate_travis_yml.py +++ b/bin/generate_travis_yml.py @@ -13,7 +13,7 @@ print("language: python") print("python: 3.5") print("env:") for env in parseconfig(None, 'tox').envlist: - print(" - TOX_ENV=%s" % env) + print(f" - TOX_ENV={env}") print("install:") print(" - pip install tox") print(" - pip install python-coveralls") diff --git a/minecraft/authentication.py b/minecraft/authentication.py index e0135fd..e936ec9 100644 --- a/minecraft/authentication.py +++ b/minecraft/authentication.py @@ -31,8 +31,7 @@ class Profile(object): raise AttributeError("Profile is not yet populated.") def __bool__(self): - bool_state = self.id_ is not None and self.name is not None - return bool_state + return self.id_ is not None and self.name is not None # Python 2 support def __nonzero__(self): @@ -277,9 +276,12 @@ def _make_request(server, endpoint, data): Returns: A `requests.Request` object. """ - res = requests.post(server + "/" + endpoint, data=json.dumps(data), - headers=HEADERS, timeout=15) - return res + return requests.post( + f"{server}/{endpoint}", + data=json.dumps(data), + headers=HEADERS, + timeout=15, + ) def _raise_from_response(res): @@ -295,7 +297,7 @@ def _raise_from_response(res): try: json_resp = res.json() - if not ("error" in json_resp and "errorMessage" in json_resp): + if "error" not in json_resp or "errorMessage" not in json_resp: raise ValueError except ValueError: message = "[{status_code}] Malformed error message: '{response_text}'" diff --git a/minecraft/networking/connection.py b/minecraft/networking/connection.py index 0b03e73..f8f9e9f 100644 --- a/minecraft/networking/connection.py +++ b/minecraft/networking/connection.py @@ -269,10 +269,16 @@ class Connection(object): """ outgoing = kwds.pop('outgoing', False) early = kwds.pop('early', False) - target = self.packet_listeners if not early and not outgoing \ - else self.early_packet_listeners if early and not outgoing \ - else self.outgoing_packet_listeners if not early \ + target = ( + self.packet_listeners + if not early and not outgoing + else self.early_packet_listeners + if early and not outgoing else self.early_outgoing_packet_listeners + if early + else self.outgoing_packet_listeners + ) + target.append(packets.PacketListener(method, *packet_types, **kwds)) def register_exception_handler(self, handler_func, *exc_types, **kwds): @@ -314,19 +320,10 @@ class Connection(object): self._exception_handlers.append((handler_func, exc_types)) def _pop_packet(self): - # Pops the topmost packet off the outgoing queue and writes it out - # through the socket - # - # Mostly an internal convenience function, caller should make sure - # they have the write lock acquired to avoid issues caused by - # asynchronous access to the socket. - # This should be the only method that removes elements from the - # outbound queue if len(self._outgoing_packet_queue) == 0: return False - else: - self._write_packet(self._outgoing_packet_queue.popleft()) - return True + self._write_packet(self._outgoing_packet_queue.popleft()) + return True def _write_packet(self, packet): # Immediately writes the given packet to the network. The caller must @@ -543,11 +540,12 @@ class Connection(object): server_protocol = KNOWN_MINECRAFT_VERSIONS.get(server_version) if server_protocol is None: - vs = 'version' if server_version is None else \ - ('version of %s' % server_version) + vs = 'version' if server_version is None else f'version of {server_version}' else: - vs = ('protocol version of %d' % server_protocol) + \ - ('' if server_version is None else ' (%s)' % server_version) + vs = 'protocol version of %d' % server_protocol + ( + '' if server_version is None else f' ({server_version})' + ) + ss = 'supported, but not allowed for this connection' \ if server_protocol in SUPPORTED_PROTOCOL_VERSIONS \ else 'not supported' @@ -615,11 +613,7 @@ class NetworkingThread(threading.Thread): # If any packets remain to be written, resume writing as soon # as possible after reading any available packets; otherwise, # wait for up to 50ms (1 tick) for new packets to arrive. - if self.connection._outgoing_packet_queue: - read_timeout = 0 - else: - read_timeout = 0.05 - + read_timeout = 0 if self.connection._outgoing_packet_queue else 0.05 # Read and react to as many as 50 packets. while num_packets < 50 and not self.interrupt: packet = self.connection.reactor.read_packet( @@ -658,49 +652,44 @@ class PacketReactor(object): for packet in self.__class__.get_clientbound_packets(context)} def read_packet(self, stream, timeout=0): - # Block for up to `timeout' seconds waiting for `stream' to become - # readable, returning `None' if the timeout elapses. - ready_to_read = select.select([stream], [], [], timeout)[0] - - if ready_to_read: - length = VarInt.read(stream) - - packet_data = packets.PacketBuffer() - packet_data.send(stream.read(length)) - # Ensure we read all the packet - while len(packet_data.get_writable()) < length: - packet_data.send( - stream.read(length - len(packet_data.get_writable()))) - packet_data.reset_cursor() - - if self.connection.options.compression_enabled: - decompressed_size = VarInt.read(packet_data) - if decompressed_size > 0: - decompressor = zlib.decompressobj() - decompressed_packet = decompressor.decompress( - packet_data.read()) - assert len(decompressed_packet) == decompressed_size, \ - 'decompressed length %d, but expected %d' % \ - (len(decompressed_packet), decompressed_size) - packet_data.reset() - packet_data.send(decompressed_packet) - packet_data.reset_cursor() - - packet_id = VarInt.read(packet_data) - - # If we know the structure of the packet, attempt to parse it - # otherwise, just return an instance of the base Packet class. - if packet_id in self.clientbound_packets: - packet = self.clientbound_packets[packet_id]() - packet.context = self.connection.context - packet.read(packet_data) - else: - packet = packets.Packet() - packet.context = self.connection.context - packet.id = packet_id - return packet - else: + if not (ready_to_read := select.select([stream], [], [], timeout)[0]): return None + length = VarInt.read(stream) + + packet_data = packets.PacketBuffer() + packet_data.send(stream.read(length)) + # Ensure we read all the packet + while len(packet_data.get_writable()) < length: + packet_data.send( + stream.read(length - len(packet_data.get_writable()))) + packet_data.reset_cursor() + + if self.connection.options.compression_enabled: + decompressed_size = VarInt.read(packet_data) + if decompressed_size > 0: + decompressor = zlib.decompressobj() + decompressed_packet = decompressor.decompress( + packet_data.read()) + assert len(decompressed_packet) == decompressed_size, \ + 'decompressed length %d, but expected %d' % \ + (len(decompressed_packet), decompressed_size) + packet_data.reset() + packet_data.send(decompressed_packet) + packet_data.reset_cursor() + + packet_id = VarInt.read(packet_data) + + # If we know the structure of the packet, attempt to parse it + # otherwise, just return an instance of the base Packet class. + if packet_id in self.clientbound_packets: + packet = self.clientbound_packets[packet_id]() + packet.context = self.connection.context + packet.read(packet_data) + else: + packet = packets.Packet() + packet.context = self.connection.context + packet.id = packet_id + return packet def react(self, packet): """Called with each incoming packet after early packet listeners are @@ -760,9 +749,11 @@ class LoginReactor(PacketReactor): msg = json.loads(packet.json_data)['text'] except (ValueError, TypeError, KeyError): msg = packet.json_data - match = re.match(r"Outdated (client! Please use|server!" - r" I'm still on) (?P\S+)$", msg) - if match: + if match := re.match( + r"Outdated (client! Please use|server!" + r" I'm still on) (?P\S+)$", + msg, + ): ver = match.group('ver') self.connection._version_mismatch(server_version=ver) raise LoginDisconnect('The server rejected our login attempt ' diff --git a/minecraft/networking/encryption.py b/minecraft/networking/encryption.py index 466317d..379dc27 100644 --- a/minecraft/networking/encryption.py +++ b/minecraft/networking/encryption.py @@ -11,9 +11,11 @@ def generate_shared_secret(): def create_AES_cipher(shared_secret): - cipher = Cipher(algorithms.AES(shared_secret), modes.CFB8(shared_secret), - backend=default_backend()) - return cipher + return Cipher( + algorithms.AES(shared_secret), + modes.CFB8(shared_secret), + backend=default_backend(), + ) def encrypt_token_and_secret(pubkey, verification_token, shared_secret): diff --git a/minecraft/networking/packets/clientbound/play/block_change_packet.py b/minecraft/networking/packets/clientbound/play/block_change_packet.py index 9d3a491..5f4a93f 100644 --- a/minecraft/networking/packets/clientbound/play/block_change_packet.py +++ b/minecraft/networking/packets/clientbound/play/block_change_packet.py @@ -128,7 +128,7 @@ class MultiBlockChangePacket(Packet): return record @classmethod - def send_with_context(self, record, socket, context): + def send_with_context(cls, record, socket, context): if context.protocol_later_eq(741): value = record.block_state_id << 12 | \ (record.x & 0xF) << 8 | \ diff --git a/minecraft/networking/packets/clientbound/play/combat_event_packet.py b/minecraft/networking/packets/clientbound/play/combat_event_packet.py index 1d98995..7d88d19 100644 --- a/minecraft/networking/packets/clientbound/play/combat_event_packet.py +++ b/minecraft/networking/packets/clientbound/play/combat_event_packet.py @@ -55,7 +55,7 @@ class CombatEventPacket(Packet): def type_from_id(cls, event_id): subcls = cls.type_from_id_dict.get(event_id) if subcls is None: - raise ValueError('Unknown combat event ID: %s.' % event_id) + raise ValueError(f'Unknown combat event ID: {event_id}.') return subcls class EnterCombatEvent(EventType): diff --git a/minecraft/networking/packets/clientbound/play/explosion_packet.py b/minecraft/networking/packets/clientbound/play/explosion_packet.py index 2224d0a..825eeea 100644 --- a/minecraft/networking/packets/clientbound/play/explosion_packet.py +++ b/minecraft/networking/packets/clientbound/play/explosion_packet.py @@ -28,7 +28,7 @@ class ExplosionPacket(Packet): @classmethod def read(cls, file_object): - return cls(*(Byte.read(file_object) for i in range(3))) + return cls(*(Byte.read(file_object) for _ in range(3))) @classmethod def send(cls, record, socket): diff --git a/minecraft/networking/packets/clientbound/play/face_player_packet.py b/minecraft/networking/packets/clientbound/play/face_player_packet.py index ebd5d7b..d5ef97c 100644 --- a/minecraft/networking/packets/clientbound/play/face_player_packet.py +++ b/minecraft/networking/packets/clientbound/play/face_player_packet.py @@ -34,8 +34,7 @@ class FacePlayerPacket(Packet): self.x = Double.read(file_object) self.y = Double.read(file_object) self.z = Double.read(file_object) - is_entity = Boolean.read(file_object) - if is_entity: + if is_entity := Boolean.read(file_object): # If the entity given by entity ID cannot be found, # this packet should be treated as if is_entity was false. self.entity_id = VarInt.read(file_object) @@ -64,15 +63,15 @@ class FacePlayerPacket(Packet): else: Boolean.send(False, packet_buffer) - else: # Protocol version 352 - if self.entity_id is not None: - Boolean.send(True, packet_buffer) - VarInt.send(self.entity_id, packet_buffer) - else: - Boolean.send(False, packet_buffer) - Double.send(self.x, packet_buffer) - Double.send(self.y, packet_buffer) - Double.send(self.z, packet_buffer) + elif self.entity_id is None: + Boolean.send(False, packet_buffer) + Double.send(self.x, packet_buffer) + Double.send(self.y, packet_buffer) + Double.send(self.z, packet_buffer) + + else: + Boolean.send(True, packet_buffer) + VarInt.send(self.entity_id, packet_buffer) # These aliases declare the Enum type corresponding to each field: Origin = OriginPoint diff --git a/minecraft/networking/packets/clientbound/play/join_game_and_respawn_packets.py b/minecraft/networking/packets/clientbound/play/join_game_and_respawn_packets.py index 0741e83..7444236 100644 --- a/minecraft/networking/packets/clientbound/play/join_game_and_respawn_packets.py +++ b/minecraft/networking/packets/clientbound/play/join_game_and_respawn_packets.py @@ -26,8 +26,7 @@ def nbt_to_snbt(tag): pynbt.TAG_Long_Array: 'L', } if type(tag) in arrays: - return '[' + arrays[type(tag)] + ';' + \ - ','.join(map(repr, tag.value)) + ']' + return ((f'[{arrays[type(tag)]};' + ','.join(map(repr, tag.value))) + ']') if isinstance(tag, pynbt.TAG_String): return repr(tag.value) @@ -36,8 +35,10 @@ def nbt_to_snbt(tag): return '[' + ','.join(map(nbt_to_snbt, tag.value)) + ']' if isinstance(tag, pynbt.TAG_Compound): - return '{' + ','.join(n + ':' + nbt_to_snbt(v) - for (n, v) in tag.items()) + '}' + return ( + '{' + ','.join(f'{n}:{nbt_to_snbt(v)}' for (n, v) in tag.items()) + ) + '}' + raise TypeError('Unknown NBT tag type: %r' % type(tag)) diff --git a/minecraft/networking/packets/clientbound/play/map_packet.py b/minecraft/networking/packets/clientbound/play/map_packet.py index 4b84377..5cadfce 100644 --- a/minecraft/networking/packets/clientbound/play/map_packet.py +++ b/minecraft/networking/packets/clientbound/play/map_packet.py @@ -55,7 +55,7 @@ class MapPacket(Packet): self.icons = [] self.width = width self.height = height - self.pixels = bytearray(0 for i in range(width*height)) + self.pixels = bytearray(0 for _ in range(width*height)) self.is_tracking_position = True self.is_locked = False @@ -67,7 +67,7 @@ class MapPacket(Packet): def __repr__(self): maps = (repr(map) for map in self.maps_by_id.values()) - return 'MapSet(%s)' % ', '.join(maps) + return f"MapSet({', '.join(maps)})" def read(self, file_object): self.map_id = VarInt.read(file_object) @@ -88,7 +88,7 @@ class MapPacket(Packet): icon_count = VarInt.read(file_object) self.icons = [] - for i in range(icon_count): + for _ in range(icon_count): if self.context.protocol_later_eq(373): type = VarInt.read(file_object) else: diff --git a/minecraft/networking/packets/clientbound/play/player_list_item_packet.py b/minecraft/networking/packets/clientbound/play/player_list_item_packet.py index cf003e3..5600e47 100644 --- a/minecraft/networking/packets/clientbound/play/player_list_item_packet.py +++ b/minecraft/networking/packets/clientbound/play/player_list_item_packet.py @@ -48,8 +48,7 @@ class PlayerListItemPacket(Packet): def read(self, file_object): self.name = String.read(file_object) self.value = String.read(file_object) - is_signed = Boolean.read(file_object) - if is_signed: + if is_signed := Boolean.read(file_object): self.signature = String.read(file_object) else: self.signature = None @@ -87,7 +86,7 @@ class PlayerListItemPacket(Packet): for subcls in cls.__subclasses__(): if subcls.action_id == action_id: return subcls - raise ValueError("Unknown player list action ID: %s." % action_id) + raise ValueError(f"Unknown player list action ID: {action_id}.") class AddPlayerAction(Action): __slots__ = 'name', 'properties', 'gamemode', 'ping', 'display_name' @@ -103,8 +102,7 @@ class PlayerListItemPacket(Packet): self.properties.append(property) self.gamemode = VarInt.read(file_object) self.ping = VarInt.read(file_object) - has_display_name = Boolean.read(file_object) - if has_display_name: + if has_display_name := Boolean.read(file_object): self.display_name = String.read(file_object) else: self.display_name = None @@ -143,8 +141,7 @@ class PlayerListItemPacket(Packet): VarInt.send(self.gamemode, packet_buffer) def apply(self, player_list): - player = player_list.players_by_uuid.get(self.uuid) - if player: + if player := player_list.players_by_uuid.get(self.uuid): player.gamemode = self.gamemode class UpdateLatencyAction(Action): @@ -158,8 +155,7 @@ class PlayerListItemPacket(Packet): VarInt.send(self.ping, packet_buffer) def apply(self, player_list): - player = player_list.players_by_uuid.get(self.uuid) - if player: + if player := player_list.players_by_uuid.get(self.uuid): player.ping = self.ping class UpdateDisplayNameAction(Action): @@ -167,8 +163,7 @@ class PlayerListItemPacket(Packet): action_id = 3 def _read(self, file_object): - has_display_name = Boolean.read(file_object) - if has_display_name: + if has_display_name := Boolean.read(file_object): self.display_name = String.read(file_object) else: self.display_name = None @@ -181,8 +176,7 @@ class PlayerListItemPacket(Packet): Boolean.send(False, packet_buffer) def apply(self, player_list): - player = player_list.players_by_uuid.get(self.uuid) - if player: + if player := player_list.players_by_uuid.get(self.uuid): player.display_name = self.display_name class RemovePlayerAction(Action): @@ -203,7 +197,7 @@ class PlayerListItemPacket(Packet): self.action_type = PlayerListItemPacket.Action.type_from_id(action_id) action_count = VarInt.read(file_object) self.actions = [] - for i in range(action_count): + for _ in range(action_count): action = self.action_type() action.read(file_object) self.actions.append(action) diff --git a/minecraft/networking/packets/clientbound/play/sound_effect_packet.py b/minecraft/networking/packets/clientbound/play/sound_effect_packet.py index 0e68980..ea9abd9 100644 --- a/minecraft/networking/packets/clientbound/play/sound_effect_packet.py +++ b/minecraft/networking/packets/clientbound/play/sound_effect_packet.py @@ -62,7 +62,7 @@ class SoundEffectPacket(Packet): class EffectPosition(Type): @classmethod def read(cls, file_object): - return Vector(*(Integer.read(file_object) / 8.0 for i in range(3))) + return Vector(*(Integer.read(file_object) / 8.0 for _ in range(3))) @classmethod def send(cls, value, socket): diff --git a/minecraft/networking/packets/clientbound/status/__init__.py b/minecraft/networking/packets/clientbound/status/__init__.py index 49a9c32..791520c 100644 --- a/minecraft/networking/packets/clientbound/status/__init__.py +++ b/minecraft/networking/packets/clientbound/status/__init__.py @@ -7,11 +7,10 @@ from minecraft.networking.types import ( # Formerly known as state_status_clientbound. def get_packets(context): - packets = { + return { ResponsePacket, PingResponsePacket, } - return packets class ResponsePacket(Packet): diff --git a/minecraft/networking/packets/packet.py b/minecraft/networking/packets/packet.py index d21f824..77a6c9d 100644 --- a/minecraft/networking/packets/packet.py +++ b/minecraft/networking/packets/packet.py @@ -117,9 +117,11 @@ class Packet(object): str = '0x%02X %s' % (self.id, str) fields = self.fields if fields is not None: - inner_str = ', '.join('%s=%s' % (a, self.field_string(a)) - for a in fields if hasattr(self, a)) - str = '%s(%s)' % (str, inner_str) + inner_str = ', '.join( + f'{a}={self.field_string(a)}' for a in fields if hasattr(self, a) + ) + + str = f'{str}({inner_str})' return str @property diff --git a/minecraft/networking/packets/packet_listener.py b/minecraft/networking/packets/packet_listener.py index 8437bd7..96e2720 100644 --- a/minecraft/networking/packets/packet_listener.py +++ b/minecraft/networking/packets/packet_listener.py @@ -4,10 +4,7 @@ from .packet import Packet class PacketListener(object): def __init__(self, callback, *args): self.callback = callback - self.packets_to_listen = [] - for arg in args: - if issubclass(arg, Packet): - self.packets_to_listen.append(arg) + self.packets_to_listen = [arg for arg in args if issubclass(arg, Packet)] def call_packet(self, packet): for packet_type in self.packets_to_listen: diff --git a/minecraft/networking/packets/serverbound/handshake/__init__.py b/minecraft/networking/packets/serverbound/handshake/__init__.py index 978227d..b646d2d 100644 --- a/minecraft/networking/packets/serverbound/handshake/__init__.py +++ b/minecraft/networking/packets/serverbound/handshake/__init__.py @@ -7,10 +7,7 @@ from minecraft.networking.types import ( # Formerly known as state_handshake_serverbound. def get_packets(context): - packets = { - HandShakePacket - } - return packets + return {HandShakePacket} class HandShakePacket(Packet): diff --git a/minecraft/networking/packets/serverbound/login/__init__.py b/minecraft/networking/packets/serverbound/login/__init__.py index dc6fba3..903ee78 100644 --- a/minecraft/networking/packets/serverbound/login/__init__.py +++ b/minecraft/networking/packets/serverbound/login/__init__.py @@ -63,10 +63,7 @@ class PluginResponsePacket(Packet): def read(self, file_object): self.message_id = VarInt.read(file_object) self.successful = Boolean.read(file_object) - if self.successful: - self.data = TrailingByteArray.read(file_object) - else: - self.data = None + self.data = TrailingByteArray.read(file_object) if self.successful else None def write_fields(self, packet_buffer): VarInt.send(self.message_id, packet_buffer) diff --git a/minecraft/networking/packets/serverbound/status/__init__.py b/minecraft/networking/packets/serverbound/status/__init__.py index 7c30760..cf1177c 100644 --- a/minecraft/networking/packets/serverbound/status/__init__.py +++ b/minecraft/networking/packets/serverbound/status/__init__.py @@ -7,11 +7,7 @@ from minecraft.networking.types import ( # Formerly known as state_status_serverbound. def get_packets(context): - packets = { - RequestPacket, - PingPacket - } - return packets + return {RequestPacket, PingPacket} class RequestPacket(Packet): diff --git a/minecraft/networking/types/basic.py b/minecraft/networking/types/basic.py index 52c4f27..b3029af 100644 --- a/minecraft/networking/types/basic.py +++ b/minecraft/networking/types/basic.py @@ -25,12 +25,12 @@ class Type(object): __slots__ = () @class_and_instancemethod - def read_with_context(cls_or_self, file_object, _context): - return cls_or_self.read(file_object) + def read_with_context(self, file_object, _context): + return self.read(file_object) @class_and_instancemethod - def send_with_context(cls_or_self, value, socket, _context): - return cls_or_self.send(value, socket) + def send_with_context(self, value, socket, _context): + return self.send(value, socket) @classmethod def read(cls, file_object): @@ -249,7 +249,7 @@ class ShortPrefixedByteArray(Type): @staticmethod def read(file_object): length = Short.read(file_object) - return struct.unpack(str(length) + "s", file_object.read(length))[0] + return struct.unpack(f"{str(length)}s", file_object.read(length))[0] @staticmethod def send(value, socket): @@ -261,12 +261,12 @@ class VarIntPrefixedByteArray(Type): @staticmethod def read(file_object): length = VarInt.read(file_object) - return struct.unpack(str(length) + "s", file_object.read(length))[0] + return struct.unpack(f"{str(length)}s", file_object.read(length))[0] @staticmethod def send(value, socket): VarInt.send(len(value), socket) - socket.send(struct.pack(str(len(value)) + "s", value)) + socket.send(struct.pack(f"{len(value)}s", value)) class TrailingByteArray(Type): @@ -379,7 +379,7 @@ class PrefixedArray(Type): def __read(self, file_object, element_read): length = self.length_type.read(file_object) - return [element_read(file_object) for i in range(length)] + return [element_read(file_object) for _ in range(length)] def __send(self, value, socket, element_send): self.length_type.send(len(value), socket) diff --git a/minecraft/networking/types/utility.py b/minecraft/networking/types/utility.py index ac3cb83..7379c30 100644 --- a/minecraft/networking/types/utility.py +++ b/minecraft/networking/types/utility.py @@ -21,12 +21,18 @@ class Vector(namedtuple('BaseVector', ('x', 'y', 'z'))): __slots__ = () def __add__(self, other): - return NotImplemented if not isinstance(other, Vector) else \ - type(self)(self.x + other.x, self.y + other.y, self.z + other.z) + return ( + type(self)(self.x + other.x, self.y + other.y, self.z + other.z) + if isinstance(other, Vector) + else NotImplemented + ) def __sub__(self, other): - return NotImplemented if not isinstance(other, Vector) else \ - type(self)(self.x - other.x, self.y - other.y, self.z - other.z) + return ( + type(self)(self.x - other.x, self.y - other.y, self.z - other.z) + if isinstance(other, Vector) + else NotImplemented + ) def __neg__(self): return type(self)(-self.x, -self.y, -self.z) @@ -83,9 +89,7 @@ class MutableRecord(object): def _all_slots(cls): for supcls in reversed(cls.__mro__): slots = supcls.__dict__.get('__slots__', ()) - slots = (slots,) if isinstance(slots, str) else slots - for slot in slots: - yield slot + yield from (slots,) if isinstance(slots, str) else slots Direction = namedtuple('Direction', ('yaw', 'pitch')) diff --git a/setup.py b/setup.py index 700a8fd..9ad9073 100644 --- a/setup.py +++ b/setup.py @@ -15,48 +15,52 @@ MAIN_AUTHORS = ["Ammar Askar ", URL = "https://github.com/ammaraskar/pyCraft" -setup(name="pyCraft", - version=__version__, - description="Python MineCraft library", - long_description=read("README.rst"), - url=URL, - download_url=URL + "/tarball/" + __version__, - author=", ".join(MAIN_AUTHORS), - install_requires=["cryptography>=1.5", - "requests", - "pynbt", - ], - packages=["minecraft", - "minecraft.networking", - "minecraft.networking.packets", - "minecraft.networking.packets.clientbound", - "minecraft.networking.packets.clientbound.status", - "minecraft.networking.packets.clientbound.handshake", - "minecraft.networking.packets.clientbound.login", - "minecraft.networking.packets.clientbound.play", - "minecraft.networking.packets.serverbound", - "minecraft.networking.packets.serverbound.status", - "minecraft.networking.packets.serverbound.handshake", - "minecraft.networking.packets.serverbound.login", - "minecraft.networking.packets.serverbound.play", - "minecraft.networking.types", - ], - keywords=["MineCraft", "networking", "pyCraft", "minecraftdev", "mc"], - classifiers=["Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Topic :: Games/Entertainment", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ] - ) +setup( + name="pyCraft", + version=__version__, + description="Python MineCraft library", + long_description=read("README.rst"), + url=URL, + download_url=f"{URL}/tarball/{__version__}", + author=", ".join(MAIN_AUTHORS), + install_requires=[ + "cryptography>=1.5", + "requests", + "pynbt", + ], + packages=[ + "minecraft", + "minecraft.networking", + "minecraft.networking.packets", + "minecraft.networking.packets.clientbound", + "minecraft.networking.packets.clientbound.status", + "minecraft.networking.packets.clientbound.handshake", + "minecraft.networking.packets.clientbound.login", + "minecraft.networking.packets.clientbound.play", + "minecraft.networking.packets.serverbound", + "minecraft.networking.packets.serverbound.status", + "minecraft.networking.packets.serverbound.handshake", + "minecraft.networking.packets.serverbound.login", + "minecraft.networking.packets.serverbound.play", + "minecraft.networking.types", + ], + keywords=["MineCraft", "networking", "pyCraft", "minecraftdev", "mc"], + classifiers=[ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Topic :: Games/Entertainment", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities", + ], +) diff --git a/start.py b/start.py index 353a158..86dffd5 100755 --- a/start.py +++ b/start.py @@ -54,8 +54,8 @@ def get_options(): r"(:(?P\d+))?$", options.server) if match is None: raise ValueError("Invalid server address: '%s'." % options.server) - options.address = match.group("host") or match.group("addr") - options.port = int(match.group("port") or 25565) + options.address = match["host"] or match["addr"] + options.port = int(match["port"] or 25565) return options @@ -85,12 +85,12 @@ def main(): # 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) + print(f'--> [unknown packet] {packet}', file=sys.stderr) else: - print('--> %s' % packet, file=sys.stderr) + print(f'--> {packet}', file=sys.stderr) def print_outgoing(packet): - print('<-- %s' % packet, file=sys.stderr) + print(f'<-- {packet}', file=sys.stderr) connection.register_packet_listener( print_incoming, Packet, early=True) @@ -104,8 +104,9 @@ def main(): handle_join_game, clientbound.play.JoinGamePacket) def print_chat(chat_packet): - print("Message (%s): %s" % ( - chat_packet.field_string('position'), chat_packet.json_data)) + print( + f"Message ({chat_packet.field_string('position')}): {chat_packet.json_data}" + ) connection.register_packet_listener( print_chat, clientbound.play.ChatMessagePacket) diff --git a/tests/fake_server.py b/tests/fake_server.py index 4cd2fb0..cdb30cd 100644 --- a/tests/fake_server.py +++ b/tests/fake_server.py @@ -102,8 +102,12 @@ class FakeClientHandler(object): # compression and encryption, if applicable, have been set up. The # client's LoginStartPacket is given as an argument. self.user_name = login_start_packet.name - self.user_uuid = uuid.UUID(bytes=hashlib.md5( - ('OfflinePlayer:%s' % self.user_name).encode('utf8')).digest()) + self.user_uuid = uuid.UUID( + bytes=hashlib.md5( + f'OfflinePlayer:{self.user_name}'.encode('utf8') + ).digest() + ) + self.write_packet(clientbound.login.LoginSuccessPacket( UUID=str(self.user_uuid), Username=self.user_name)) @@ -202,7 +206,7 @@ class FakeClientHandler(object): def write_packet(self, packet): # Send and log a clientbound packet. packet.context = self.server.context - logging.debug('[S-> ] %s' % packet) + logging.debug(f'[S-> ] {packet}') packet.write(self.socket, **( {'compression_threshold': self.server.compression_threshold} if self.compression_enabled else {})) @@ -217,7 +221,7 @@ class FakeClientHandler(object): packet.read(buffer) else: packet = packets.Packet(self.server.context, id=packet_id) - logging.debug('[ ->S] %s' % packet) + logging.debug(f'[ ->S] {packet}') return packet def _run_handshake(self): @@ -234,7 +238,7 @@ class FakeClientHandler(object): elif packet.next_state == 2: self._run_handshake_play(packet) else: - raise AssertionError('Unknown state: %s' % packet.next_state) + raise AssertionError(f'Unknown state: {packet.next_state}') except FakeServerDisconnect: pass @@ -248,8 +252,7 @@ class FakeClientHandler(object): msg = "Outdated server! I'm still on %s" \ % self.server.minecraft_version else: - msg = 'Outdated client! Please use %s' \ - % self.server.minecraft_version + msg = f'Outdated client! Please use {self.server.minecraft_version}' self.handle_login_server_disconnect(msg) def _run_login(self): @@ -341,8 +344,7 @@ class FakeClientHandler(object): data_length = types.VarInt.read(buffer) if data_length > 0: data = zlib.decompress(buffer.read()) - assert len(data) == data_length, \ - '%s != %s' % (len(data), data_length) + assert len(data) == data_length, f'{len(data)} != {data_length}' buffer.reset() buffer.send(data) buffer.reset_cursor() @@ -432,9 +434,9 @@ class FakeServer(object): while True: try: client_socket, addr = self.listen_socket.accept() - logging.debug('[ ++ ] Client %s connected.' % (addr,)) + logging.debug(f'[ ++ ] Client {addr} connected.') self.client_handler_type(self, client_socket).run() - logging.debug('[ -- ] Client %s disconnected.' % (addr,)) + logging.debug(f'[ -- ] Client {addr} disconnected.') except socket.timeout: pass with self.lock: @@ -566,11 +568,11 @@ class _FakeServerTest(unittest.TestCase): @client.listener(packets.Packet, early=True) def handle_incoming_packet(packet): - logging.debug('[ ->C] %s' % packet) + logging.debug(f'[ ->C] {packet}') @client.listener(packets.Packet, early=True, outgoing=True) def handle_outgoing_packet(packet): - logging.debug('[C-> ] %s' % packet) + logging.debug(f'[C-> ] {packet}') server_thread = threading.Thread( name='FakeServer', diff --git a/tests/test_connection.py b/tests/test_connection.py index bb10b4e..43d12cb 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -370,11 +370,10 @@ class ExceptionReconnectTest(ConnectTest): def _start_client(self, client): @client.listener(clientbound.play.JoinGamePacket) def handle_join_game(packet): - if self.phase == 0: - self.phase += 1 - raise self.CustomException - else: + if self.phase != 0: raise fake_server.FakeServerTestSuccess + self.phase += 1 + raise self.CustomException @client.exception_handler(self.CustomException, early=True) def handle_custom_exception(exc, exc_info): diff --git a/tests/test_packets.py b/tests/test_packets.py index a59462b..ec78696 100644 --- a/tests/test_packets.py +++ b/tests/test_packets.py @@ -77,7 +77,7 @@ class PacketSerializationTest(unittest.TestCase): logging.debug('protocol_version = %r' % protocol_version) context = ConnectionContext(protocol_version=protocol_version) - msg = ''.join(choice(string.ascii_lowercase) for i in range(500)) + msg = ''.join(choice(string.ascii_lowercase) for _ in range(500)) packet = serverbound.play.ChatPacket(context) packet.message = msg diff --git a/tests/test_serialization.py b/tests/test_serialization.py index e751c5e..7c4a342 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -27,7 +27,7 @@ TEST_DATA = { UnsignedShort: [0, 400], UnsignedLong: [0, 400], Integer: [-1000, 1000], - FixedPointInteger: [float(-13098.3435), float(-0.83), float(1000)], + FixedPointInteger: [-13098.3435, -0.83, float(1000)], Angle: [0, 360.0, 720, 47.12947238973, -108.7], VarInt: [1, 250, 50000, 10000000], Long: [50000000], @@ -44,7 +44,7 @@ TEST_DATA = { for x in [-0x200000, -123, -1, 0, 123, 0x1FFFFF] for z in [-0x200000, -456, -1, 0, 456, 0x1FFFFF] for y in [-0x80000, -789, -1, 0, 789, 0x7FFFF] - ] + ], }