load screen before loading an old save file

This commit is contained in:
Faraphel 2023-03-04 13:32:59 +01:00
parent 312210b323
commit 8048a3d43b
9 changed files with 172 additions and 10 deletions

View file

@ -3,7 +3,7 @@ A faire :
1. Principal : 1. Principal :
- Sauvegarde - Sauvegarde
- Historique / Replay - Historique
- Documenter - Documenter
2. Visuel : 2. Visuel :
@ -12,6 +12,7 @@ A faire :
- Changer les images, rajouter les fonds, ... - Changer les images, rajouter les fonds, ...
3. Hypothétique : 3. Hypothétique :
- Vrai musique
- Voir si les event listener intégré à pyglet sont plus pratiques que l'event propagation (?) - Voir si les event listener intégré à pyglet sont plus pratiques que l'event propagation (?)
- Faire une scène incluant par défaut les boutons "Retour" (?) - Faire une scène incluant par défaut les boutons "Retour" (?)

View file

@ -2,16 +2,18 @@ from typing import TYPE_CHECKING
from source.gui import widget, texture from source.gui import widget, texture
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.network import Host
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
class GameLoad(Scene): class GameLoad(Scene):
def __init__(self, window: "Window", **kwargs): def __init__(self, window: "Window", thread_host: Host, **kwargs):
super().__init__(window, **kwargs) super().__init__(window, **kwargs)
self.thread_host = thread_host # thread de l'hôte
self.label = self.add_widget( self.label = self.add_widget(
widget.Text, widget.Text,
@ -35,6 +37,8 @@ class GameLoad(Scene):
style=texture.Button.Style1 style=texture.Button.Style1
) )
self.refuse.add_listener("on_click_release", lambda *_: self.response(value=False))
self.accept = self.add_widget( self.accept = self.add_widget(
widget.Button, widget.Button,
@ -45,3 +49,11 @@ class GameLoad(Scene):
style=texture.Button.Style1 style=texture.Button.Style1
) )
self.accept.add_listener("on_click_release", lambda *_: self.response(value=True))
def response(self, value: bool):
self.thread_host.accept_load = value
self.window.remove_scene(self)
with self.thread_host.condition_load:
self.thread_host.condition_load.notify_all()

View file

@ -0,0 +1,26 @@
from typing import TYPE_CHECKING
from source.gui import widget, texture
from source.gui.scene.abc import Scene
from source.network import Host
if TYPE_CHECKING:
from source.gui.window import Window
class GameWaitLoad(Scene):
def __init__(self, window: "Window", **kwargs):
super().__init__(window, **kwargs)
self.label = self.add_widget(
widget.Text,
x=0.5, y=0.5, width=1.0,
anchor_x="center",
text="Une ancienne sauvegarde à été trouvé.\nL'hôte décide de son utilisation...",
align="center",
multiline=True,
font_size=28,
)

View file

@ -4,6 +4,7 @@ from .GameQuit import GameQuit
from .GameError import GameError from .GameError import GameError
from .GameSave import GameSave from .GameSave import GameSave
from .GameLoad import GameLoad from .GameLoad import GameLoad
from .GameWaitLoad import GameWaitLoad
from .Settings import Settings from .Settings import Settings
from .RoomHost import RoomHost from .RoomHost import RoomHost
from .RoomJoin import RoomJoin from .RoomJoin import RoomJoin

View file

@ -1,9 +1,11 @@
import socket import socket
from typing import TYPE_CHECKING, Any from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional
from source import path_save
from source.gui import scene from source.gui import scene
from source.network import game_network from source.network import game_network
from source.network.packet import PacketUsername, PacketSettings from source.network.packet import PacketUsername, PacketSettings, PacketHaveSaveBeenFound, PacketLoadOldSave
from source.utils import StoppableThread from source.utils import StoppableThread
from source.utils.thread import in_pyglet_context from source.utils.thread import in_pyglet_context
@ -33,7 +35,46 @@ class Client(StoppableThread):
print(f"[Client] Connecté avec {connection}") print(f"[Client] Connecté avec {connection}")
... # sauvegarde
# attend que l'hôte indique s'il a trouvé une ancienne sauvegarde
packet_save_found = PacketHaveSaveBeenFound.from_connection(connection)
if packet_save_found.value:
# 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 path_save.iterdir():
if file.stem == 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)
while True:
# attend la décision de l'hôte
try:
load_old_save = PacketLoadOldSave.from_connection(connection)
break
except socket.timeout:
if self.stopped: return
print("accept load", load_old_save)
if load_old_save.value:
...
# TODO: Charger nos données
# paramètres & jeu
settings: Any = PacketSettings.from_connection(connection) settings: Any = PacketSettings.from_connection(connection)
PacketUsername(username=self.username).send_data_connection(connection) PacketUsername(username=self.username).send_data_connection(connection)

View file

@ -1,12 +1,14 @@
import socket import socket
from typing import TYPE_CHECKING from pathlib import Path
from typing import TYPE_CHECKING, Optional
from threading import Condition
from source import path_save from source import path_save
from source.gui import scene from source.gui import scene
from source.network import game_network from source.network import game_network
from source.utils import StoppableThread from source.utils import StoppableThread
from source.utils.thread import in_pyglet_context from source.utils.thread import in_pyglet_context
from source.network.packet import PacketUsername from source.network.packet import PacketUsername, PacketLoadOldSave, PacketHaveSaveBeenFound
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
@ -26,6 +28,9 @@ class Host(StoppableThread):
self.settings = settings self.settings = settings
self.port = port self.port = port
self.condition_load = Condition()
self.accept_load: Optional[bool] = None
def run(self) -> None: def run(self) -> None:
print("[Serveur] Thread démarré") print("[Serveur] Thread démarré")
@ -45,9 +50,35 @@ class Host(StoppableThread):
print(f"[Serveur] Connecté avec {ip_address}") print(f"[Serveur] Connecté avec {ip_address}")
# check pour ancienne sauvegarde contre ce joueur # 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 == 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)
# si l'adversaire à également la sauvegarde, demande à l'hôte de confirmer l'utilisation de la save
if packet_save_found.value:
from source.gui.scene import GameLoad
in_pyglet_context(self.window.set_scene, GameLoad, 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)
if self.accept_load:
...
# TODO: Charger nos données
# paramètres & jeu # paramètres & jeu

View file

@ -0,0 +1,24 @@
import struct
from dataclasses import field, dataclass
from source.network.packet.abc import SimplePacket
@dataclass
class PacketHaveSaveBeenFound(SimplePacket):
"""
A packet that is sent when the player accept or refuse a requested save.
"""
value: bool = field() # True si requête accepter, sinon False
packet_format = ">?"
def to_bytes(self) -> bytes:
return struct.pack(self.packet_format, self.value)
@classmethod
def from_bytes(cls, data: bytes) -> "PacketHaveSaveBeenFound":
value, *_ = struct.unpack(cls.packet_format, data)
return cls(value=value)

View file

@ -0,0 +1,24 @@
import struct
from dataclasses import field, dataclass
from source.network.packet.abc import SimplePacket
@dataclass
class PacketLoadOldSave(SimplePacket):
"""
A packet that is sent when the player accept or refuse a requested save.
"""
value: bool = field() # True si requête accepter, sinon False
packet_format = ">?"
def to_bytes(self) -> bytes:
return struct.pack(self.packet_format, self.value)
@classmethod
def from_bytes(cls, data: bytes) -> "PacketLoadOldSave":
value, *_ = struct.unpack(cls.packet_format, data)
return cls(value=value)

View file

@ -7,3 +7,5 @@ from .PacketResponseSave import PacketResponseSave
from .PacketSettings import PacketSettings from .PacketSettings import PacketSettings
from .PacketUsername import PacketUsername from .PacketUsername import PacketUsername
from .PacketQuit import PacketQuit from .PacketQuit import PacketQuit
from .PacketLoadOldSave import PacketLoadOldSave
from .PacketHaveSaveBeenFound import PacketHaveSaveBeenFound