From 2f96ab14ade4d9dbd0bfcefcc7c078acd4807736 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Tue, 21 Feb 2023 23:25:50 +0100 Subject: [PATCH] added a better management for the network thread and a prototypal chat --- NOTE.md | 1 - source/gui/scene/Game.py | 12 +++++++- source/gui/scene/RoomCreate.py | 11 +++++--- source/gui/scene/RoomJoin.py | 7 +++-- source/gui/scene/Settings.py | 4 +-- source/gui/widget/Input.py | 3 ++ source/gui/widget/grid/GameGridEnemy.py | 1 - source/network/Client.py | 32 ++++++++++++++++++---- source/network/Host.py | 31 ++++++++++++++++----- source/network/SocketType.py | 7 +++++ source/network/{test => _test}/__init__.py | 0 source/network/{test => _test}/client.py | 0 source/network/{test => _test}/server.py | 0 13 files changed, 86 insertions(+), 23 deletions(-) create mode 100644 source/network/SocketType.py rename source/network/{test => _test}/__init__.py (100%) rename source/network/{test => _test}/client.py (100%) rename source/network/{test => _test}/server.py (100%) diff --git a/NOTE.md b/NOTE.md index 5cb4be6..1570e50 100644 --- a/NOTE.md +++ b/NOTE.md @@ -1,5 +1,4 @@ A faire : -- Prévisualisation des bateaux sur la grille avant de placer - Ecran de configuration de la partie - Nom dans les options diff --git a/source/gui/scene/Game.py b/source/gui/scene/Game.py index f26b91c..9ec23e3 100644 --- a/source/gui/scene/Game.py +++ b/source/gui/scene/Game.py @@ -1,3 +1,4 @@ +import socket from typing import TYPE_CHECKING import pyglet @@ -6,15 +7,18 @@ from source.gui.scene.abc import Scene from source.gui import widget, texture from source.gui.widget.grid import GameGridAlly, GameGridEnemy from source import core +from source.network.SocketType import SocketType if TYPE_CHECKING: from source.gui.window import Window class Game(Scene): - def __init__(self, window: "Window", **kwargs): + def __init__(self, window: "Window", connection: socket.socket, **kwargs): super().__init__(window, **kwargs) + self.connection = connection + self.batch_label = pyglet.graphics.Batch() self.batch_button_background = pyglet.graphics.Batch() self.batch_input_background = pyglet.graphics.Batch() @@ -134,6 +138,12 @@ class Game(Scene): background_batch=self.batch_input_background, label_batch=self.batch_label, ) + + def send_chat(): + connection.send(SocketType["CHAT"].value.to_bytes(1, "big")) + connection.send(self.chat_input.text.encode()) + + self.chat_input.add_listener("on_enter", send_chat) self.button_save = self.add_widget( widget.Button, diff --git a/source/gui/scene/RoomCreate.py b/source/gui/scene/RoomCreate.py index 59f8c53..35a7cb5 100644 --- a/source/gui/scene/RoomCreate.py +++ b/source/gui/scene/RoomCreate.py @@ -12,13 +12,16 @@ if TYPE_CHECKING: class RoomCreate(Scene): - def __init__(self, window: "Window", *args, **kwargs): - super().__init__(window, *args, **kwargs) + def __init__(self, window: "Window", **kwargs): + super().__init__(window, **kwargs) - r = requests.get('https://api.ipify.org') + """r = requests.get('https://api.ipify.org') r.raise_for_status() ip_address: str = r.content.decode('utf8') - port: int = 52321 + port: int = 52321""" + + ip_address = "127.0.0.1" + port = 52321 self.batch_button_background = pyglet.graphics.Batch() self.batch_label = pyglet.graphics.Batch() diff --git a/source/gui/scene/RoomJoin.py b/source/gui/scene/RoomJoin.py index 62673a7..9e4cdd0 100644 --- a/source/gui/scene/RoomJoin.py +++ b/source/gui/scene/RoomJoin.py @@ -70,12 +70,15 @@ class RoomJoin(Scene): label_batch=self.batch_label ) - self.connect.add_listener("on_click_release", lambda *_: network.Client( + self.connect.add_listener("on_click_release", self.button_connect) + + def button_connect(self, *_): + network.Client( window=self.window, ip_address=self.entry_ip.text, daemon=True, username="Client" - ).start()) + ).start() def button_back_callback(self, *_): from source.gui.scene import MainMenu diff --git a/source/gui/scene/Settings.py b/source/gui/scene/Settings.py index 54543f9..3680453 100644 --- a/source/gui/scene/Settings.py +++ b/source/gui/scene/Settings.py @@ -11,8 +11,8 @@ if TYPE_CHECKING: class Settings(Scene): - def __init__(self, window: "Window", *args, **kwargs): - super().__init__(window, *args, **kwargs) + def __init__(self, window: "Window", **kwargs): + super().__init__(window, **kwargs) self.batch_button_background = pyglet.graphics.Batch() self.batch_scroller_background = pyglet.graphics.Batch() diff --git a/source/gui/widget/Input.py b/source/gui/widget/Input.py index 707bc57..9275f92 100644 --- a/source/gui/widget/Input.py +++ b/source/gui/widget/Input.py @@ -105,6 +105,9 @@ class Input(BoxWidget): if symbol == pyglet.window.key.BACKSPACE: # si la touche "supprimé" est enfoncé self.text = self.text[0:-1] # retire le dernier caractère du texte + if symbol == pyglet.window.key.ENTER: + self.trigger_event("on_enter") + def on_text(self, char: str): if not self.activated: return # ignore si ce widget est désactivé / non sélectionné self.text += char # ajoute le caractère au label diff --git a/source/gui/widget/grid/GameGridEnemy.py b/source/gui/widget/grid/GameGridEnemy.py index ef97a71..7fff668 100644 --- a/source/gui/widget/grid/GameGridEnemy.py +++ b/source/gui/widget/grid/GameGridEnemy.py @@ -2,7 +2,6 @@ from typing import Type, TYPE_CHECKING import pyglet -from source.gui import texture from source.gui.texture.abc import Style from source.gui.widget.grid.abc import GameGrid from source.gui.sprite import Sprite diff --git a/source/network/Client.py b/source/network/Client.py index 85661dc..d2bc71f 100644 --- a/source/network/Client.py +++ b/source/network/Client.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING import pyglet.clock from source.gui import scene - +from source.network.SocketType import SocketType if TYPE_CHECKING: from source.gui.window import Window @@ -15,18 +15,40 @@ class Client(Thread): def __init__(self, window: "Window", username: str, ip_address: str, port: int = 52321, **kw): super().__init__(**kw) + self._stop = False + self.window = window self.username = username self.ip_address = ip_address self.port = port + def stop(self): + self._stop = True + def run(self) -> None: print("[Client] Thread démarré") - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((self.ip_address, self.port)) + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as connection: + connection.connect((self.ip_address, self.port)) + connection.settimeout(5) # défini le timeout à 5 secondes - print(f"[Client] Connecté avec {s}") + print(f"[Client] Connecté avec {connection}") - pyglet.clock.schedule_once(lambda dt: self.window.set_scene(scene.Game), 0) + pyglet.clock.schedule_once(lambda dt: self.window.set_scene(scene.Game, connection=connection), 0) + while True: + data = None + + try: data = connection.recv(1) + except socket.timeout: pass + + if not data: + if self._stop: return # vérifie si le thread n'est pas censé s'arrêter + continue + + socket_type = SocketType(int.from_bytes(data, "big")) + + print(socket_type) + + match socket_type: + case SocketType.CHAT: print(connection.recv(1024).decode()) diff --git a/source/network/Host.py b/source/network/Host.py index d27f283..a7be490 100644 --- a/source/network/Host.py +++ b/source/network/Host.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING import pyglet from source.gui import scene - +from source.network.SocketType import SocketType if TYPE_CHECKING: from source.gui.window import Window @@ -27,15 +27,15 @@ class Host(Thread): def run(self) -> None: print("[Serveur] Thread démarré") - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.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é - s.settimeout(5) # défini le timeout à 5 secondes - s.listen() # écoute de nouvelle connexion + server.settimeout(5) # défini le timeout à 5 secondes + server.listen() # écoute de nouvelle connexion while True: try: - connection, address = s.accept() # accepte la première connexion entrante + connection, address = server.accept() # accepte la première connexion entrante break # sort de la boucle except socket.timeout: # en cas de timeout if self._stop: return # vérifie si le thread n'est pas censé s'arrêter @@ -43,4 +43,21 @@ class Host(Thread): print(f"[Serveur] Connecté avec {address}") - pyglet.clock.schedule_once(lambda dt: self.window.set_scene(scene.Game), 0) + pyglet.clock.schedule_once(lambda dt: self.window.set_scene(scene.Game, connection=connection), 0) + + while True: + data = None + + try: data = connection.recv(1) + except socket.timeout: pass + + if not data: + if self._stop: return # vérifie si le thread n'est pas censé s'arrêter + continue + + socket_type = SocketType(int.from_bytes(data, "big")) + + print(socket_type) + + match socket_type: + case SocketType.CHAT: print(connection.recv(1024).decode()) diff --git a/source/network/SocketType.py b/source/network/SocketType.py new file mode 100644 index 0000000..ed212c1 --- /dev/null +++ b/source/network/SocketType.py @@ -0,0 +1,7 @@ +from enum import Enum + + +class SocketType(Enum): + CHAT = 0 + BOAT_PLACED = 1 + BOMB = 2 diff --git a/source/network/test/__init__.py b/source/network/_test/__init__.py similarity index 100% rename from source/network/test/__init__.py rename to source/network/_test/__init__.py diff --git a/source/network/test/client.py b/source/network/_test/client.py similarity index 100% rename from source/network/test/client.py rename to source/network/_test/client.py diff --git a/source/network/test/server.py b/source/network/_test/server.py similarity index 100% rename from source/network/test/server.py rename to source/network/_test/server.py