diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index 4af8e31..5bd436d 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -128,13 +128,21 @@ class Squirrel(Hazelnut): creates a new hazelnut. """ if (address, port) in self.hazelnuts: - self.add_system_message(str(self.hazelnuts)) return self.hazelnuts[(address, port)] hazelnut = Hazelnut(address=address, port=port) self.hazelnuts[(address, port)] = hazelnut - self.add_system_message(str(self.hazelnuts)) return hazelnut + def find_hazelnut_by_id(self, hazel_id: int) -> Hazelnut: + """ + Retrieve the hazelnut that is known by its id. Return None if it is unknown. + The given identifier must be positive. + """ + if hazel_id > 0: + for hazelnut in self.hazelnuts.values(): + if hazelnut.id == hazel_id: + return hazelnut + def send_packet(self, client: Hazelnut, pkt: Packet) -> int: """ Send a formatted packet to a client. diff --git a/squinnondation/messages.py b/squinnondation/messages.py index f938c66..7ce7d1a 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -12,7 +12,6 @@ import time class TLV: """ The Tag-Length-Value contains the different type of data that can be sent. - TODO: add subclasses for each type of TLV """ type: int length: int @@ -159,6 +158,14 @@ class HelloTLV(TLV): def handle(self, squirrel: Any, sender: Any) -> None: time_h = time.time() + + if sender.id > 0 and sender.id != self.source_id: + squirrel.send_packet(sender, Packet.construct(WarningTLV.construct( + f"You were known as the ID {sender.id}, but you declared that you have the ID {self.source_id}."))) + squirrel.add_system_message(f"A client known as the id {sender.id} declared that it uses " + f"the id {self.source_id}.") + sender.id = self.source_id + if not sender.active: sender.id = self.source_id # The sender we are given misses an id time_hl = time.time() @@ -167,13 +174,6 @@ class HelloTLV(TLV): if self.is_long and self.dest_id == squirrel.id: time_hl = time.time() - if sender.id != self.source_id: - squirrel.send_packet(sender, Packet.construct(WarningTLV.construct( - f"You were known as the ID {sender.id}, but you declared that you have the ID {self.source_id}."))) - squirrel.add_system_message(f"A client known as the id {sender.id} declared that it uses " - f"the id {self.source_id}.") - sender.id = self.source_id - # Add entry to/actualize the active hazelnuts dictionnary sender.last_hello_time = time_h sender.last_long_hello_time = time_hl @@ -296,13 +296,15 @@ class DataTLV(TLV): "Unable to retrieve your username. Please use the syntax 'nickname: message'"))) else: nickname = nickname_match.group(1) - if sender.nickname is None: - sender.nickname = nickname - elif sender.nickname != nickname: - squirrel.send_packet(sender, Packet.construct(WarningTLV.construct( - "It seems that you used two different nicknames. " - f"Known nickname: {sender.nickname}, found: {nickname}"))) - sender.nickname = nickname + author = squirrel.find_hazelnut_by_id(self.sender_id) + if author: + if author.nickname is None: + author.nickname = nickname + elif author.nickname != nickname: + squirrel.send_packet(author, Packet.construct(WarningTLV.construct( + "It seems that you used two different nicknames. " + f"Known nickname: {author.nickname}, found: {nickname}"))) + author.nickname = nickname @staticmethod def construct(message: str, squirrel: Any) -> "DataTLV":