simplified packet with the struct module
This commit is contained in:
parent
a2d37c37f7
commit
bda05d3f8e
3 changed files with 38 additions and 27 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import struct
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from source.network.packet.abc import Packet
|
from source.network.packet.abc import Packet
|
||||||
|
@ -13,14 +15,13 @@ class PacketBombPlaced(Packet):
|
||||||
position: Point2D = field()
|
position: Point2D = field()
|
||||||
|
|
||||||
packet_size: int = 2
|
packet_size: int = 2
|
||||||
|
packet_format: str = ">BB"
|
||||||
|
|
||||||
def to_bytes(self):
|
def to_bytes(self):
|
||||||
x, y = self.position
|
x, y = self.position
|
||||||
return x.to_bytes(1, "big") + y.to_bytes(1, "big")
|
return struct.pack(self.packet_format, x, y)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, data: bytes):
|
def from_bytes(cls, data: bytes):
|
||||||
return cls(position=(
|
x, y = struct.unpack(cls.packet_format, data)
|
||||||
int.from_bytes(data[0:1], "big"),
|
return cls(position=(x, y))
|
||||||
int.from_bytes(data[1:2], "big"),
|
|
||||||
))
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import socket
|
import struct
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from source.core.enums import BombState
|
from source.core.enums import BombState
|
||||||
|
@ -16,22 +16,13 @@ class PacketBombState(Packet):
|
||||||
bomb_state: BombState = field()
|
bomb_state: BombState = field()
|
||||||
|
|
||||||
packet_size: int = 3
|
packet_size: int = 3
|
||||||
|
packet_format: str = ">BBb"
|
||||||
|
|
||||||
def to_bytes(self):
|
def to_bytes(self):
|
||||||
x, y = self.position
|
x, y = self.position
|
||||||
|
return struct.pack(self.packet_format, x, y, self.bomb_state.value)
|
||||||
return (
|
|
||||||
x.to_bytes(1, "big") +
|
|
||||||
y.to_bytes(1, "big") +
|
|
||||||
self.bomb_state.value.to_bytes(1, "big")
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, data: bytes):
|
def from_bytes(cls, data: bytes):
|
||||||
return cls(
|
x, y, bomb_state = struct.unpack(cls.packet_format, data)
|
||||||
position=(
|
return cls(position=(x, y), bomb_state=BombState(bomb_state))
|
||||||
int.from_bytes(data[0:1], "big"),
|
|
||||||
int.from_bytes(data[1:2], "big"),
|
|
||||||
),
|
|
||||||
bomb_state=BombState(int.from_bytes(data[2:3], "big"))
|
|
||||||
)
|
|
||||||
|
|
|
@ -51,17 +51,36 @@ class Packet(ABC):
|
||||||
connection.send(self.to_bytes())
|
connection.send(self.to_bytes())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_connection(cls, connection: socket.socket) -> Optional["Packet"]:
|
def cls_from_connection(cls, connection: socket.socket) -> Optional[Type["Packet"]]:
|
||||||
|
"""
|
||||||
|
Receive a packet type from a socket.
|
||||||
|
:param connection: the socket where to get the header from
|
||||||
|
:return: the packet class, or None if there was nothing in the socket to receive.
|
||||||
|
"""
|
||||||
|
packet_header: Optional[bytes] = None
|
||||||
|
try:
|
||||||
|
packet_header = connection.recv(1)
|
||||||
|
except socket.timeout:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return cls.cls_from_header(packet_header) if packet_header else None # ignore si le header est invalide
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def instance_from_connection(cls, connection: socket.socket) -> Optional["Packet"]:
|
||||||
|
"""
|
||||||
|
Receive a packet instance data from a socket.
|
||||||
|
:param connection: the socket where to get the data from
|
||||||
|
:return: the packet, or None if there was nothing in the socket to receive.
|
||||||
|
"""
|
||||||
|
return cls.from_bytes(connection.recv(cls.packet_size))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_connection(cls, connection: socket.socket) -> Optional[Type["Packet"]]:
|
||||||
"""
|
"""
|
||||||
Receive a packet from a socket.
|
Receive a packet from a socket.
|
||||||
:param connection: the socket where to get the data from
|
:param connection: the socket where to get the data from
|
||||||
:return: the packet, or None if there was nothing in the socket to receive.
|
:return: the packet, or None if there was nothing in the socket to receive.
|
||||||
"""
|
"""
|
||||||
packet_header: Optional[bytes] = None
|
subcls = cls.cls_from_connection(connection)
|
||||||
try: packet_header = connection.recv(1)
|
return None if subcls is None else subcls.instance_from_connection(connection)
|
||||||
except socket.timeout: pass
|
|
||||||
|
|
||||||
if not packet_header: return None # si le header du packet est invalide, ignore
|
|
||||||
subcls = cls.cls_from_header(packet_header)
|
|
||||||
|
|
||||||
return subcls.from_bytes(connection.recv(subcls.packet_size))
|
|
||||||
|
|
Loading…
Reference in a new issue