Finished networking #9
82
client.py
82
client.py
|
@ -3,8 +3,9 @@
|
||||||
# Apr 2025
|
# Apr 2025
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import network_utilities
|
|
||||||
import socket
|
import socket
|
||||||
|
import select
|
||||||
|
import network_utilities
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
@ -17,44 +18,46 @@ class Game:
|
||||||
self.__server = server
|
self.__server = server
|
||||||
|
|
||||||
def start_game(self):
|
def start_game(self):
|
||||||
data = network_utilities.pack_varint(1)
|
data = network_utilities.pack_varint(2)
|
||||||
self.__server.send(data)
|
self.__server.send(data)
|
||||||
|
|
||||||
def start_round(self, difficulty: int):
|
def start_round(self, difficulty: int):
|
||||||
data = network_utilities.pack_varint(2)
|
data = network_utilities.pack_varint(3)
|
||||||
data += network_utilities.pack_varint(difficulty)
|
data += network_utilities.pack_varint(difficulty)
|
||||||
self.__server.send(data)
|
self.__server.send(data)
|
||||||
|
|
||||||
def guess_reference(self, url: str):
|
def guess_reference(self, url: str):
|
||||||
data = network_utilities.pack_varint(3)
|
data = network_utilities.pack_varint(4)
|
||||||
data += network_utilities.pack_string(url)
|
data += network_utilities.pack_string(url)
|
||||||
self.__server.send(data)
|
self.__server.send(data)
|
||||||
|
|
||||||
def end_game(self):
|
def end_game(self):
|
||||||
data = network_utilities.pack_varint(4)
|
data = network_utilities.pack_varint(5)
|
||||||
self.__server.send(data)
|
self.__server.send(data)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
packet_id = network_utilities.unpack_varint(self.__server)
|
ready_to_read, _, _ = select.select([self.__server], [], [], 0)
|
||||||
if packet_id == 1:
|
if ready_to_read:
|
||||||
name = network_utilities.unpack_string(self.__server)
|
packet_id = network_utilities.unpack_varint(self.__server)
|
||||||
self.__player.player_joined(name)
|
if packet_id == 1:
|
||||||
elif packet_id == 2:
|
name = network_utilities.unpack_string(self.__server)
|
||||||
text = network_utilities.unpack_string(self.__server)
|
self.__player.player_joined(name)
|
||||||
self.__player.new_verse(text)
|
elif packet_id == 2:
|
||||||
elif packet_id == 3:
|
text = network_utilities.unpack_string(self.__server)
|
||||||
self.__player.guess_incorrect()
|
self.__player.new_verse(text)
|
||||||
elif packet_id == 4:
|
elif packet_id == 3:
|
||||||
self.__player.guess_correct()
|
self.__player.guess_incorrect()
|
||||||
elif packet_id == 5:
|
elif packet_id == 4:
|
||||||
points = network_utilities.unpack_varint(self.__server)
|
self.__player.guess_correct()
|
||||||
url = network_utilities.unpack_string(self.__server)
|
elif packet_id == 5:
|
||||||
player = network_utilities.unpack_string(self.__server)
|
points = network_utilities.unpack_varint(self.__server)
|
||||||
self.__player.verse_guessed(points, url, player)
|
url = network_utilities.unpack_string(self.__server)
|
||||||
elif packet_id == 6:
|
player = network_utilities.unpack_string(self.__server)
|
||||||
players = network_utilities.unpack_string_array(self.__server)
|
self.__player.verse_guessed(points, url, player)
|
||||||
scores = network_utilities.unpack_varint_array(self.__server)
|
elif packet_id == 6:
|
||||||
self.__player.game_over(players, scores)
|
players = network_utilities.unpack_string_array(self.__server)
|
||||||
|
scores = network_utilities.unpack_varint_array(self.__server)
|
||||||
|
self.__player.game_over(players, scores)
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
|
@ -80,7 +83,12 @@ class Player:
|
||||||
def score(self) -> int: return self.__score
|
def score(self) -> int: return self.__score
|
||||||
|
|
||||||
def join_game(self, host: str = 'localhost', port: int = 7788):
|
def join_game(self, host: str = 'localhost', port: int = 7788):
|
||||||
pass
|
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
conn.connect((host, port))
|
||||||
|
data = network_utilities.pack_varint(1)
|
||||||
|
data += network_utilities.pack_string(self.name)
|
||||||
|
conn.send(data)
|
||||||
|
self.__game = Game(self, conn)
|
||||||
|
|
||||||
def start_game(self):
|
def start_game(self):
|
||||||
if self.__game is not None:
|
if self.__game is not None:
|
||||||
|
@ -99,20 +107,30 @@ class Player:
|
||||||
self.__game.end_game()
|
self.__game.end_game()
|
||||||
|
|
||||||
def player_joined(self, name: str):
|
def player_joined(self, name: str):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
def new_verse(self, text: str):
|
def new_verse(self, text: str):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
def guess_incorrect(self):
|
def guess_incorrect(self):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
def guess_correct(self):
|
def guess_correct(self):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
def verse_guessed(self, points: int, url: str, player: str):
|
def verse_guessed(self, points: int, url: str, player: str):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
def game_over(self, players: list[str], scores: list[int]):
|
def game_over(self, players: list[str], scores: list[int]):
|
||||||
pass
|
if self.__game is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.__game is not None:
|
||||||
|
self.__game.update()
|
||||||
|
|
||||||
|
|
39
library.py
39
library.py
|
@ -3,13 +3,12 @@
|
||||||
# Apr 2025
|
# Apr 2025
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
import socket
|
import socket
|
||||||
|
import select
|
||||||
if TYPE_CHECKING:
|
import network_utilities
|
||||||
from server import Game
|
from server import Game
|
||||||
|
|
||||||
|
|
||||||
class Library:
|
class Library:
|
||||||
|
@ -34,23 +33,31 @@ class Library:
|
||||||
with self.__socket as s:
|
with self.__socket as s:
|
||||||
s.bind((self.__host, self.__port))
|
s.bind((self.__host, self.__port))
|
||||||
s.listen(1)
|
s.listen(1)
|
||||||
|
s.setblocking(False)
|
||||||
while True:
|
while True:
|
||||||
conn, _ = s.accept()
|
ready_to_read, _, _ = select.select([s], [], [], 0)
|
||||||
...
|
for game in self.__games[:]:
|
||||||
|
if not game.finished: game.update()
|
||||||
|
else: self.__games.remove(game)
|
||||||
|
if ready_to_read:
|
||||||
|
conn, _ = s.accept()
|
||||||
|
conn.setblocking(False)
|
||||||
|
if network_utilities.unpack_varint(conn) == 1:
|
||||||
|
name = network_utilities.unpack_string(conn)
|
||||||
|
self.join_game(name, conn)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("KeyboardInterrupt\nExiting...")
|
print("KeyboardInterrupt\nExiting...")
|
||||||
return
|
return
|
||||||
|
|
||||||
def join_game(self, name: str, game_num: int = -1):
|
def join_game(self, name: str, conn: socket.socket):
|
||||||
if game_num == -1:
|
for i, game in enumerate(self.__games):
|
||||||
for i, game in enumerate(self.__games):
|
if not game.active:
|
||||||
if not game.active:
|
game_num = i
|
||||||
game_num = i
|
break
|
||||||
break
|
else:
|
||||||
else:
|
self.__games.append(Game(self))
|
||||||
self.__games.append(Game())
|
game_num = len(self.__games) - 1
|
||||||
game_num = len(self.__games) - 1
|
self.__games[game_num].add_player(name, conn)
|
||||||
self.__games[game_num].add_player(name)
|
|
||||||
|
|
||||||
def get_verse(self, difficulty: int, game: Game):
|
def get_verse(self, difficulty: int, game: Game):
|
||||||
url = self.__select_verse(difficulty)
|
url = self.__select_verse(difficulty)
|
||||||
|
|
53
server.py
53
server.py
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
import select
|
||||||
|
import datetime
|
||||||
import network_utilities
|
import network_utilities
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -20,6 +22,7 @@ class Game:
|
||||||
__total_scores: list[int]
|
__total_scores: list[int]
|
||||||
__active: bool
|
__active: bool
|
||||||
__finished: bool
|
__finished: bool
|
||||||
|
__created: datetime.datetime
|
||||||
|
|
||||||
def __init__(self, library: Library):
|
def __init__(self, library: Library):
|
||||||
self.__library = library
|
self.__library = library
|
||||||
|
@ -29,6 +32,7 @@ class Game:
|
||||||
self.__total_scores = []
|
self.__total_scores = []
|
||||||
self.__active = False
|
self.__active = False
|
||||||
self.__finished = False
|
self.__finished = False
|
||||||
|
self.__created = datetime.datetime.now()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def active(self) -> bool: return self.__active
|
def active(self) -> bool: return self.__active
|
||||||
|
@ -36,9 +40,9 @@ class Game:
|
||||||
@property
|
@property
|
||||||
def finished(self) -> bool: return self.__finished
|
def finished(self) -> bool: return self.__finished
|
||||||
|
|
||||||
def add_player(self, name: str, socket: socket):
|
def add_player(self, name: str, conn: socket):
|
||||||
if not self.__active:
|
if not self.__active:
|
||||||
self.__clients.append(Player(name, self, socket))
|
self.__clients.append(Player(name, self, conn))
|
||||||
self.__total_scores.append(0)
|
self.__total_scores.append(0)
|
||||||
for player in self.__clients:
|
for player in self.__clients:
|
||||||
player.player_joined(name)
|
player.player_joined(name)
|
||||||
|
@ -69,6 +73,21 @@ class Game:
|
||||||
|
|
||||||
def end_game(self):
|
def end_game(self):
|
||||||
self.__finished = True
|
self.__finished = True
|
||||||
|
for player in self.__clients:
|
||||||
|
player.game_over(
|
||||||
|
[i.name for i in self.__clients], self.__total_scores)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if not self.__active and (
|
||||||
|
datetime.datetime.now() - self.__created >=
|
||||||
|
datetime.timedelta(minutes=10)
|
||||||
|
) or (
|
||||||
|
datetime.datetime.now() - self.__created >=
|
||||||
|
datetime.timedelta(1)
|
||||||
|
): self.__finished = True
|
||||||
|
if not self.__finished:
|
||||||
|
for player in self.__clients:
|
||||||
|
player.update()
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
|
@ -77,10 +96,10 @@ class Player:
|
||||||
__game: Game
|
__game: Game
|
||||||
__client: socket
|
__client: socket
|
||||||
|
|
||||||
def __init__(self, name: str, game: Game, socket: socket):
|
def __init__(self, name: str, game: Game, conn: socket):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__game = game
|
self.__game = game
|
||||||
self.__client = socket
|
self.__client = conn
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str: return self.__name
|
def name(self) -> str: return self.__name
|
||||||
|
@ -115,16 +134,20 @@ class Player:
|
||||||
data += network_utilities.pack_string_array(players)
|
data += network_utilities.pack_string_array(players)
|
||||||
data += network_utilities.pack_varint_array(scores)
|
data += network_utilities.pack_varint_array(scores)
|
||||||
self.__client.send(data)
|
self.__client.send(data)
|
||||||
|
self.__client.close()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
packet_id = network_utilities.unpack_varint(self.__client)
|
ready_to_read, _, _ = select.select([self.__client], [], [], 0)
|
||||||
if packet_id == 1:
|
if ready_to_read:
|
||||||
self.__game.start_game()
|
packet_id = network_utilities.unpack_varint(self.__client)
|
||||||
elif packet_id == 2:
|
if packet_id == 2:
|
||||||
difficulty = network_utilities.unpack_varint(self.__client)
|
self.__game.start_game()
|
||||||
self.__game.start_round(difficulty)
|
elif packet_id == 3:
|
||||||
elif packet_id == 3:
|
difficulty = network_utilities.unpack_varint(self.__client)
|
||||||
url = network_utilities.unpack_string(self.__client)
|
self.__game.start_round(difficulty)
|
||||||
self.__game.guess_reference(url, self)
|
elif packet_id == 4:
|
||||||
elif packet_id == 4:
|
url = network_utilities.unpack_string(self.__client)
|
||||||
self.__game.end_game()
|
self.__game.guess_reference(url, self)
|
||||||
|
elif packet_id == 5:
|
||||||
|
self.__game.end_game()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue