simplified the code for handling error in the network module
This commit is contained in:
parent
8ef6d0d239
commit
fce1ed0abf
5 changed files with 185 additions and 190 deletions
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Optional, Callable
|
|||
|
||||
from source.path import path_save
|
||||
from source.gui import scene
|
||||
from source.network import game_network
|
||||
from source.network import game_network, handle_error
|
||||
from source.network.packet import PacketUsername, PacketSettings, PacketHaveSaveBeenFound, PacketLoadOldSave
|
||||
from source.utils import StoppableThread
|
||||
from source.utils.thread import in_pyglet_context
|
||||
|
@ -36,107 +36,99 @@ class Client(StoppableThread):
|
|||
self.port = port
|
||||
|
||||
def run(self) -> None:
|
||||
print("[Client] Thread démarré")
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as connection:
|
||||
try:
|
||||
connection.connect((self.ip_address, self.port))
|
||||
except ConnectionRefusedError:
|
||||
# Appelle l'événement lorsque la connexion échoue
|
||||
if self.on_connexion_refused is not None:
|
||||
in_pyglet_context(self.on_connexion_refused)
|
||||
return
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as connection:
|
||||
try:
|
||||
connection.connect((self.ip_address, self.port))
|
||||
except ConnectionRefusedError:
|
||||
# Appelle l'événement lorsque la connexion échoue
|
||||
if self.on_connexion_refused is not None:
|
||||
in_pyglet_context(self.on_connexion_refused)
|
||||
return
|
||||
connection.settimeout(1) # défini le timeout à 1 seconde
|
||||
|
||||
connection.settimeout(1) # défini le timeout à 1 secondes
|
||||
# sauvegarde
|
||||
|
||||
print(f"[Client] Connecté avec {connection}")
|
||||
load_old_save: bool = False
|
||||
|
||||
# sauvegarde
|
||||
# attend que l'hôte indique s'il a trouvé une ancienne sauvegarde
|
||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||
|
||||
load_old_save: bool = False
|
||||
if packet_save_found:
|
||||
# si l'hôte a trouvé une ancienne sauvegarde, vérifier de notre côté également.
|
||||
|
||||
# attend que l'hôte indique s'il a trouvé une ancienne sauvegarde
|
||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||
path_old_save: Optional[Path] = None
|
||||
ip_address, _ = connection.getpeername()
|
||||
|
||||
if packet_save_found:
|
||||
# si l'hôte a trouvé une ancienne sauvegarde, vérifier de notre côté également.
|
||||
|
||||
path_old_save: Optional[Path] = None
|
||||
ip_address, _ = connection.getpeername()
|
||||
|
||||
for file in reversed(list(path_save.iterdir())):
|
||||
# la liste est inversée dans le cas où le fichier est en localhost, afin que l'hôte
|
||||
# prenne le fichier en -0.bn-save et le client en -1.bn-save
|
||||
if file.stem.startswith(ip_address):
|
||||
path_old_save = file
|
||||
break
|
||||
|
||||
# envoie à l'hôte si l'on possède également la sauvegarde
|
||||
PacketHaveSaveBeenFound(value=path_old_save is not None).send_data_connection(connection)
|
||||
|
||||
if path_old_save:
|
||||
# si l'on possède la sauvegarde, attend que l'hôte confirme son utilisation
|
||||
|
||||
from source.gui.scene import GameWaitLoad
|
||||
in_pyglet_context(self.window.set_scene, GameWaitLoad, path=path_old_save)
|
||||
|
||||
while True:
|
||||
# attend la décision de l'hôte
|
||||
try:
|
||||
load_old_save = PacketLoadOldSave.from_connection(connection).value
|
||||
for file in reversed(list(path_save.iterdir())):
|
||||
# la liste est inversée dans le cas où le fichier est en localhost, afin que l'hôte
|
||||
# prenne le fichier en -0.bn-save et le client en -1.bn-save
|
||||
if file.stem.startswith(ip_address):
|
||||
path_old_save = file
|
||||
break
|
||||
except socket.timeout:
|
||||
if self.stopped: return
|
||||
except ConnectionResetError:
|
||||
from source.gui.scene import GameError
|
||||
in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
GameError,
|
||||
text="Perte de connexion avec l'adversaire"
|
||||
)
|
||||
return
|
||||
|
||||
if load_old_save:
|
||||
# envoie à l'hôte si l'on possède également la sauvegarde
|
||||
PacketHaveSaveBeenFound(value=path_old_save is not None).send_data_connection(connection)
|
||||
|
||||
# charge la sauvegarde
|
||||
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||
save_data = json.load(file)
|
||||
if path_old_save:
|
||||
# si l'on possède la sauvegarde, attend que l'hôte confirme son utilisation
|
||||
|
||||
# paramètres & jeu
|
||||
from source.gui.scene import GameWaitLoad
|
||||
in_pyglet_context(self.window.set_scene, GameWaitLoad, path=path_old_save)
|
||||
|
||||
settings = PacketSettings.from_connection(connection)
|
||||
PacketUsername(username=self.username).send_data_connection(connection)
|
||||
enemy_username = PacketUsername.from_connection(connection).username
|
||||
while True:
|
||||
# attend la décision de l'hôte
|
||||
try:
|
||||
load_old_save = PacketLoadOldSave.from_connection(connection).value
|
||||
break
|
||||
except socket.timeout:
|
||||
if self.stopped: return
|
||||
|
||||
if load_old_save:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game.from_json, # depuis le fichier json
|
||||
if load_old_save:
|
||||
|
||||
data=save_data,
|
||||
# charge la sauvegarde
|
||||
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||
save_data = json.load(file)
|
||||
|
||||
thread=self,
|
||||
connection=connection
|
||||
)
|
||||
# paramètres & jeu
|
||||
|
||||
else:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game,
|
||||
settings = PacketSettings.from_connection(connection)
|
||||
PacketUsername(username=self.username).send_data_connection(connection)
|
||||
enemy_username = PacketUsername.from_connection(connection).username
|
||||
|
||||
if load_old_save:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game.from_json, # depuis le fichier json
|
||||
|
||||
data=save_data,
|
||||
|
||||
thread=self,
|
||||
connection=connection
|
||||
)
|
||||
|
||||
else:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game,
|
||||
|
||||
thread=self,
|
||||
connection=connection,
|
||||
|
||||
boats_length=settings.boats_length,
|
||||
name_ally=self.username,
|
||||
name_enemy=enemy_username,
|
||||
grid_width=settings.grid_width,
|
||||
grid_height=settings.grid_height,
|
||||
my_turn=not settings.host_start
|
||||
)
|
||||
|
||||
game_network(
|
||||
thread=self,
|
||||
connection=connection,
|
||||
|
||||
boats_length=settings.boats_length,
|
||||
name_ally=self.username,
|
||||
name_enemy=enemy_username,
|
||||
grid_width=settings.grid_width,
|
||||
grid_height=settings.grid_height,
|
||||
my_turn=not settings.host_start
|
||||
game_scene=game_scene,
|
||||
)
|
||||
|
||||
game_network(
|
||||
thread=self,
|
||||
connection=connection,
|
||||
game_scene=game_scene,
|
||||
)
|
||||
except Exception as exception:
|
||||
handle_error(self.window, exception)
|
||||
|
|
|
@ -6,7 +6,7 @@ from threading import Condition
|
|||
|
||||
from source.path import path_save
|
||||
from source.gui import scene
|
||||
from source.network import game_network
|
||||
from source.network import game_network, handle_error
|
||||
from source.utils import StoppableThread
|
||||
from source.utils.thread import in_pyglet_context
|
||||
from source.network.packet import PacketUsername, PacketLoadOldSave, PacketHaveSaveBeenFound
|
||||
|
@ -33,103 +33,93 @@ class Host(StoppableThread):
|
|||
self.accept_load: bool = False
|
||||
|
||||
def run(self) -> None:
|
||||
print("[Serveur] Thread démarré")
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
|
||||
server.bind(("", self.port)) # connecte le socket au port indiqué
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
|
||||
server.bind(("", self.port)) # connecte le socket au port indiqué
|
||||
|
||||
server.settimeout(1) # défini le timeout à 1 seconde
|
||||
server.listen() # écoute de nouvelle connexion
|
||||
|
||||
while True:
|
||||
try:
|
||||
connection, (ip_address, port) = server.accept() # accepte la première connexion entrante
|
||||
break # sort de la boucle
|
||||
except socket.timeout: # en cas de timeout
|
||||
if self.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||
# sinon, réessaye
|
||||
|
||||
print(f"[Serveur] Connecté avec {ip_address}")
|
||||
|
||||
# ancienne sauvegarde
|
||||
|
||||
path_old_save: Optional[Path] = None
|
||||
|
||||
for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'ip de l'adversaire
|
||||
if file.stem.startswith(ip_address):
|
||||
path_old_save = file
|
||||
break
|
||||
|
||||
# envoie à l'adversaire si une ancienne sauvegarde a été trouvée
|
||||
PacketHaveSaveBeenFound(value=path_old_save is not None).send_data_connection(connection)
|
||||
|
||||
if path_old_save is not None:
|
||||
# si une ancienne sauvegarde a été trouvée, attend que l'adversaire confirme avoir également la save
|
||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||
|
||||
# si l'adversaire à également la sauvegarde, demande à l'hôte de confirmer l'utilisation de la save
|
||||
if packet_save_found:
|
||||
|
||||
from source.gui.scene import GameLoad
|
||||
in_pyglet_context(self.window.set_scene, GameLoad, path=path_old_save, thread_host=self)
|
||||
|
||||
with self.condition_load: self.condition_load.wait() # attend que l'utilisateur choisisse l'option
|
||||
server.settimeout(1) # défini le timeout à 1 seconde
|
||||
server.listen() # écoute de nouvelle connexion
|
||||
|
||||
while True:
|
||||
try:
|
||||
connection, (ip_address, port) = server.accept() # accepte la première connexion entrante
|
||||
break # sort de la boucle
|
||||
except socket.timeout: # en cas de timeout
|
||||
if self.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||
# sinon, réessaye
|
||||
|
||||
print(f"[Serveur] Connecté avec {ip_address}")
|
||||
|
||||
# ancienne sauvegarde
|
||||
|
||||
path_old_save: Optional[Path] = None
|
||||
|
||||
for file in path_save.iterdir(): # cherche une ancienne sauvegarde correspondant à l'ip de l'adversaire
|
||||
if file.stem.startswith(ip_address):
|
||||
path_old_save = file
|
||||
break
|
||||
|
||||
# envoie à l'adversaire si une ancienne sauvegarde a été trouvée
|
||||
PacketHaveSaveBeenFound(value=path_old_save is not None).send_data_connection(connection)
|
||||
|
||||
if path_old_save is not None:
|
||||
# si une ancienne sauvegarde a été trouvée, attend que l'adversaire confirme avoir également la save
|
||||
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection).value
|
||||
|
||||
# si l'adversaire à également la sauvegarde, demande à l'hôte de confirmer l'utilisation de la save
|
||||
if packet_save_found:
|
||||
|
||||
from source.gui.scene import GameLoad
|
||||
in_pyglet_context(self.window.set_scene, GameLoad, path=path_old_save, thread_host=self)
|
||||
|
||||
with self.condition_load: self.condition_load.wait() # attend que l'utilisateur choisisse l'option
|
||||
|
||||
PacketLoadOldSave(value=self.accept_load).send_data_connection(connection)
|
||||
except ConnectionResetError:
|
||||
from source.gui.scene import GameError
|
||||
in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
GameError,
|
||||
text="Perte de connexion avec l'adversaire"
|
||||
)
|
||||
return
|
||||
|
||||
if self.accept_load:
|
||||
if self.accept_load:
|
||||
|
||||
# charge la sauvegarde
|
||||
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||
save_data = json.load(file)
|
||||
# charge la sauvegarde
|
||||
with open(path_old_save, "r", encoding="utf-8") as file:
|
||||
save_data = json.load(file)
|
||||
|
||||
# paramètres et jeu
|
||||
# paramètres et jeu
|
||||
|
||||
self.settings.send_data_connection(connection)
|
||||
enemy_username = PacketUsername.from_connection(connection).username
|
||||
PacketUsername(username=self.username).send_data_connection(connection)
|
||||
self.settings.send_data_connection(connection)
|
||||
enemy_username = PacketUsername.from_connection(connection).username
|
||||
PacketUsername(username=self.username).send_data_connection(connection)
|
||||
|
||||
if self.accept_load:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game.from_json, # depuis le fichier json
|
||||
if self.accept_load:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game.from_json, # depuis le fichier json
|
||||
|
||||
data=save_data,
|
||||
data=save_data,
|
||||
|
||||
thread=self,
|
||||
connection=connection
|
||||
)
|
||||
thread=self,
|
||||
connection=connection
|
||||
)
|
||||
|
||||
else:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game,
|
||||
else:
|
||||
game_scene = in_pyglet_context(
|
||||
self.window.set_scene,
|
||||
scene.Game,
|
||||
|
||||
thread=self,
|
||||
connection=connection,
|
||||
|
||||
boats_length=self.settings.boats_length,
|
||||
name_ally=self.username,
|
||||
name_enemy=enemy_username,
|
||||
grid_width=self.settings.grid_width,
|
||||
grid_height=self.settings.grid_height,
|
||||
my_turn=self.settings.host_start
|
||||
)
|
||||
|
||||
game_network(
|
||||
thread=self,
|
||||
connection=connection,
|
||||
|
||||
boats_length=self.settings.boats_length,
|
||||
name_ally=self.username,
|
||||
name_enemy=enemy_username,
|
||||
grid_width=self.settings.grid_width,
|
||||
grid_height=self.settings.grid_height,
|
||||
my_turn=self.settings.host_start
|
||||
game_scene=game_scene
|
||||
)
|
||||
|
||||
game_network(
|
||||
thread=self,
|
||||
connection=connection,
|
||||
game_scene=game_scene
|
||||
)
|
||||
|
||||
# TODO: englober les threads de try sur ConnectionResetError pour ramener au menu d'erreur directement
|
||||
# au lieu de le faire manuellement à chaque fois
|
||||
except Exception as exception:
|
||||
handle_error(self.window, exception)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from .game_network import game_network
|
||||
from .error import handle_error
|
||||
|
||||
from .Client import Client
|
||||
from .Host import Host
|
||||
|
|
25
source/network/error.py
Normal file
25
source/network/error.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
import builtins
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from source.utils.thread import in_pyglet_context
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
def handle_error(window: "Window", exception: Exception):
|
||||
message: str = "Erreur :\n"
|
||||
|
||||
match type(exception):
|
||||
case builtins.ConnectionResetError:
|
||||
message += "Perte de connexion avec l'adversaire."
|
||||
case _:
|
||||
message += str(exception)
|
||||
|
||||
from source.gui.scene import GameError
|
||||
in_pyglet_context(
|
||||
window.set_scene,
|
||||
GameError,
|
||||
text=message
|
||||
)
|
|
@ -32,30 +32,17 @@ def game_network(
|
|||
packet.PacketResponseSave: game_scene.network_on_response_save,
|
||||
}
|
||||
|
||||
try:
|
||||
while True:
|
||||
data_type = Packet.type_from_connection(connection)
|
||||
|
||||
if data_type is None:
|
||||
if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||
continue
|
||||
|
||||
data = data_type.from_connection(connection)
|
||||
|
||||
in_pyglet_context(
|
||||
game_methods[data_type], data # récupère la methode relié ce type de donnée
|
||||
) # Appelle la méthode.
|
||||
while True:
|
||||
data_type = Packet.type_from_connection(connection)
|
||||
|
||||
if data_type is None:
|
||||
if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||
continue
|
||||
|
||||
except Exception as exception:
|
||||
message: str = "Erreur :\n"
|
||||
data = data_type.from_connection(connection)
|
||||
|
||||
match type(exception):
|
||||
case builtins.ConnectionResetError:
|
||||
message += "Perte de connexion avec l'adversaire."
|
||||
case _:
|
||||
message += str(exception)
|
||||
in_pyglet_context(
|
||||
game_methods[data_type], data # récupère la methode relié ce type de donnée
|
||||
) # Appelle la méthode.
|
||||
|
||||
from source.gui.scene import GameError
|
||||
in_pyglet_context(game_scene.window.set_scene, GameError, text=message)
|
||||
if thread.stopped: return # vérifie si le thread n'est pas censé s'arrêter
|
||||
|
|
Loading…
Reference in a new issue