mirror of
https://github.com/ammaraskar/pyCraft.git
synced 2025-01-18 05:32:07 +01:00
Merge pull request #1 from Advik-B/sourcery/master
Sourcery refactored master branch
This commit is contained in:
commit
fcd6f05865
@ -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")
|
||||
|
@ -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}'"
|
||||
|
@ -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<ver>\S+)$", msg)
|
||||
if match:
|
||||
if match := re.match(
|
||||
r"Outdated (client! Please use|server!"
|
||||
r" I'm still on) (?P<ver>\S+)$",
|
||||
msg,
|
||||
):
|
||||
ver = match.group('ver')
|
||||
self.connection._version_mismatch(server_version=ver)
|
||||
raise LoginDisconnect('The server rejected our login attempt '
|
||||
|
@ -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):
|
||||
|
@ -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 | \
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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'))
|
||||
|
94
setup.py
94
setup.py
@ -15,48 +15,52 @@ MAIN_AUTHORS = ["Ammar Askar <ammar@ammaraskar.com>",
|
||||
|
||||
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",
|
||||
],
|
||||
)
|
||||
|
15
start.py
15
start.py
@ -54,8 +54,8 @@ def get_options():
|
||||
r"(:(?P<port>\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)
|
||||
|
@ -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',
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user