diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index db99db9..3a531d5 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -68,18 +68,37 @@ class Squirrel(Hazelnut): curses.init_color(curses.COLOR_WHITE, 1000, 1000, 1000) for i in range(curses.COLOR_BLACK + 1, curses.COLOR_WHITE): curses.init_pair(i + 1, i, curses.COLOR_BLACK) - - self.hazelnuts = dict() + + #dictionnaries of neighbours + self.potentialhazelnuts = dict() + self.activehazelnuts = dict() #of the form [hazelnut, time of last + #hello, time of last long hello, is symetric] self.add_system_message(f"Listening on {self.address}:{self.port}") - + + def new_hazel(self, address: IPv6Address, port: int) -> Hazelnut: + """ + Returns a new hazelnut (with no id nor nickname) + """ + hazelnut = Hazelnut(address=address, port=port) + return hazelnut + + def is_active(self, hazel: Hazelnut) -> bool : + return (hazel.address, hazel.port) in self.activehazelnuts + + def is_potential(self, hazel: Hazelnut) -> bool : + return (hazel.address, hazel.port) in self.potentialhazelnuts + + def remove_from_potential(self, address: IPv6Address, port: int)-> None: + self.potentialhazelnuts.pop((address, port), None) + def find_hazelnut(self, address: str, port: int) -> Hazelnut: """ - Translate an address into a hazelnut, and store it in the list of the hazelnuts, ie. the neighbours. + Translate an address into a hazelnut. If this hazelnut does not exist, + creates a new hazelnut. """ - if (address, port) in self.hazelnuts: - return self.hazelnuts[(address, port)] + if (address, port) in self.activehazelnuts: + return self.activehazelnuts[(address, port)][0] hazelnut = Hazelnut(address=address, port=port) - self.hazelnuts[(address, port)] = hazelnut return hazelnut def send_packet(self, client: Hazelnut, pkt: Packet) -> int: @@ -205,7 +224,7 @@ class Squirrel(Hazelnut): self.add_message(msg) pkt = Packet.construct(DataTLV.construct(msg, self)) - for hazelnut in list(self.hazelnuts.values()): + for hazelnut in list(self.activehazelnuts.values()): self.send_packet(hazelnut, pkt) def handle_mouse_click(self, y: int, x: int, attr: int) -> None: diff --git a/squinnondation/messages.py b/squinnondation/messages.py index 5ad2886..051ab58 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -6,6 +6,7 @@ from ipaddress import IPv6Address from enum import Enum import socket import sys +import time class TLV: @@ -143,7 +144,20 @@ class HelloTLV(TLV): return data def handle(self, squirrel: Any, sender: Any) -> None: - # TODO Implement HelloTLV + timeH = time.time() + timeHL = None + if not squirrel.is_active(sender) : + sender.id = source_id #The sender we are given misses an id + else : + timeHL = squirrel.activehazelnuts[(sender.address, sender.port)] + if self.is_long and dest_id == squirrel.id : + timeHL = time.time() + #elif source_id != sender.id : + #That neighbour is lying about its ID + squirrel.remove_from_potential(sender.address, sender.port) + + squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\ + timeHL, True] squirrel.add_system_message("Aaaawwww, someone spoke to me and said me Hello smiling_face_with_" + (":3_hearts:" if self.is_long else "smiling_eyes:")) @@ -171,9 +185,9 @@ class NeighbourTLV(TLV): self.port.to_bytes(2, sys.byteorder) def handle(self, squirrel: Any, sender: Any) -> None: - # TODO Implement NeighbourTLV - squirrel.add_system_message("I have a friend!") - squirrel.add_system_message(f"Welcome {self.ip_address}:{self.port}!") + if not (ip_address,port) in squirrel.activehazelnuts and not (ip_address,port) in squirrel.potentialhazelnuts: + squirrel.potentialhazelnuts[(ip_address, port)] = squirrel.new_hazel(ip_address, port) + squirrel.add_system_message(f"New potential friend {self.ip_address}:{self.port}!") class DataTLV(TLV): @@ -301,9 +315,10 @@ class GoAwayTLV(TLV): self.message.encode("UTF-8")[:self.length - 1] def handle(self, squirrel: Any, sender: Any) -> None: - # TODO Implement GoAwayTLV - squirrel.add_system_message("Some told me that he went away. That's not very nice :( " - "I should send him some cake.") + if squirrel.is_active(sender) : + squirrel.activehazelnuts.pop((sender.addess, sender.port)) + squirrel.potentialhazelnuts[(sender.address, sender.port)] = sender + squirrel.add_system_message("Some told me that he went away : "+message) class WarningTLV(TLV): diff --git a/squinnondation/squinnondation.py b/squinnondation/squinnondation.py index 1769fbb..c1f900b 100644 --- a/squinnondation/squinnondation.py +++ b/squinnondation/squinnondation.py @@ -74,7 +74,7 @@ class Squinnondation: if instance.args.client_address and instance.args.client_port: hazelnut = Hazelnut(address=instance.args.client_address, port=instance.args.client_port) - squirrel.hazelnuts[(instance.args.client_address, instance.args.client_port)] = hazelnut + squirrel.activehazelnuts[(instance.args.client_address, instance.args.client_port)] = hazelnut Worm(squirrel).start() squirrel.wait_for_key()