feat: add ability to send stats to server
This commit is contained in:
@@ -92,3 +92,7 @@ color:
|
||||
piece-inner-border-1-player-2: "#F83801"
|
||||
piece-outer-border-1: "#000000"
|
||||
piece-ghost: "#9BFCF0"
|
||||
|
||||
online:
|
||||
server-url: "ws://webapi.tetri5.com"
|
||||
#server-url: "ws://localhost:5001"
|
||||
|
||||
@@ -5,6 +5,7 @@ import queue # refer to https://docs.python.org/3/library/queue.html for cross t
|
||||
import uuid
|
||||
from typing import Dict, List
|
||||
from threading import Thread
|
||||
from tetri5.util import ConfigurationManager
|
||||
|
||||
class MultiplayerService():
|
||||
_thread = None
|
||||
@@ -16,6 +17,8 @@ class MultiplayerService():
|
||||
_send_piece_queue = queue.Queue()
|
||||
_receive_stack_queue = queue.Queue()
|
||||
_send_stack_queue = queue.Queue()
|
||||
_receive_stats_queue = queue.Queue()
|
||||
_send_stats_queue = queue.Queue()
|
||||
_receive_message_queue = queue.Queue()
|
||||
_send_message_queue = queue.Queue()
|
||||
|
||||
@@ -37,6 +40,10 @@ class MultiplayerService():
|
||||
def send_stack(cls, stack: "StackDto") -> None:
|
||||
cls._send_stack_queue.put(stack)
|
||||
|
||||
@classmethod
|
||||
def send_stats(cls, stats: "StatsDto") -> None:
|
||||
cls._send_stats_queue.put(stats)
|
||||
|
||||
@classmethod
|
||||
def send_message(cls, message: str) -> None:
|
||||
cls._send_message_queue.put(message)
|
||||
@@ -60,6 +67,15 @@ class MultiplayerService():
|
||||
cls._receive_stack_queue.task_done()
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def try_receive_stats(cls) -> "StatsDto":
|
||||
if cls._receive_stats_queue.empty():
|
||||
return None
|
||||
|
||||
result = cls._receive_stats_queue.get()
|
||||
cls._receive_stats_queue.task_done()
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def try_receive_message(cls) -> str:
|
||||
if cls._receive_message_queue.empty():
|
||||
@@ -80,7 +96,6 @@ class MultiplayerService():
|
||||
_NetworkConnectionService.close_connection()
|
||||
|
||||
class _NetworkConnectionService():
|
||||
_URI = "ws://webapi.tetri5.com" # TODO get from config file
|
||||
_websocket = None
|
||||
_is_closed = False
|
||||
_join_game = False
|
||||
@@ -127,7 +142,7 @@ class _NetworkConnectionService():
|
||||
if MultiplayerService._send_stack_queue.empty():
|
||||
return
|
||||
|
||||
# get next piece to send and send to server
|
||||
# get next stack to send and send to server
|
||||
stack = MultiplayerService._send_stack_queue.get()
|
||||
|
||||
# construct json message
|
||||
@@ -139,6 +154,24 @@ class _NetworkConnectionService():
|
||||
await cls._websocket.send(json_message)
|
||||
MultiplayerService._send_stack_queue.task_done()
|
||||
|
||||
@classmethod
|
||||
async def _try_send_stats(cls) -> None:
|
||||
# if no messages to proccess, return
|
||||
if MultiplayerService._send_stats_queue.empty():
|
||||
return
|
||||
|
||||
# get next stats to send and send to server
|
||||
stats = MultiplayerService._send_stats_queue.get()
|
||||
|
||||
# construct json message
|
||||
json_message = json.dumps({"action": "send_stats",\
|
||||
"clientId": MultiplayerService._client_id,\
|
||||
"gameId": MultiplayerService._current_game_id,\
|
||||
"stats": stats.__dict__})
|
||||
|
||||
await cls._websocket.send(json_message)
|
||||
MultiplayerService._send_stats_queue.task_done()
|
||||
|
||||
@classmethod
|
||||
async def _try_send_message(cls) -> None:
|
||||
# if no messages to proccess, return
|
||||
@@ -175,6 +208,9 @@ class _NetworkConnectionService():
|
||||
MultiplayerService._receive_piece_queue.put(PieceDto.create(data["piece"]))
|
||||
if data["type"] == "receive_stack":
|
||||
MultiplayerService._receive_stack_queue.put(StackDto.create(data["stack"]))
|
||||
if data["type"] == "receive_stats":
|
||||
MultiplayerService._receive_stats_queue.put(StatsDto.create(data["stats"]))
|
||||
print(data["stats"])
|
||||
if data["type"] == "exit_game":
|
||||
print("Exit the game!")
|
||||
cls.close_connection()
|
||||
@@ -194,6 +230,7 @@ class _NetworkConnectionService():
|
||||
await cls._try_enter_game()
|
||||
await cls._try_send_piece()
|
||||
await cls._try_send_stack()
|
||||
await cls._try_send_stats()
|
||||
await cls._try_send_message()
|
||||
await cls._try_receive_message()
|
||||
|
||||
@@ -202,12 +239,13 @@ class _NetworkConnectionService():
|
||||
await cls._websocket.close()
|
||||
break
|
||||
|
||||
# ping_interval=None is important, otherwise the server will disconnect us
|
||||
# https://stackoverflow.com/a/58993145/11512104
|
||||
@classmethod
|
||||
async def _connect_to_server(cls) -> None:
|
||||
print("Connecting to server...") # TODO replace with logging
|
||||
cls._websocket = await websockets.connect(cls._URI, ping_interval=None)
|
||||
# ping_interval=None is important, otherwise the server will disconnect us
|
||||
# https://stackoverflow.com/a/58993145/11512104
|
||||
url = ConfigurationManager.get("online", "server-url")
|
||||
cls._websocket = await websockets.connect(url, ping_interval=None)
|
||||
print("Connected to server...") # TODO replace with logging
|
||||
|
||||
@classmethod
|
||||
@@ -235,4 +273,14 @@ class StackDto():
|
||||
|
||||
@staticmethod
|
||||
def create(data: Dict) -> "StackDto":
|
||||
return StackDto(data["points"], data["square_colors"])
|
||||
return StackDto(data["points"], data["square_colors"])
|
||||
|
||||
class StatsDto():
|
||||
def __init__(self, score: int, lines: int, is_well_full: bool) -> None:
|
||||
self.score = score
|
||||
self.lines = lines
|
||||
self.is_well_full = is_well_full
|
||||
|
||||
@staticmethod
|
||||
def create(data: Dict) -> "StatsDto":
|
||||
return StatsDto(data["score"], data["lines"], data["is_well_full"])
|
||||
@@ -266,7 +266,12 @@ class MultiplayerScene(Scene):
|
||||
def __init__(self, change_scene: FunctionType) -> None:
|
||||
self._tile_size = ConfigurationManager.get("engine", "tile-size")
|
||||
self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg"))
|
||||
self._lines_per_level = ConfigurationManager.get("engine", "lines-per-level")
|
||||
self._lines_per_level = ConfigurationManager.get("engine", "lines-per-level")
|
||||
self._points_table = ConfigurationManager.get("engine", "points-table")
|
||||
|
||||
self._score_player_one = 0
|
||||
self._score_player_two = 0
|
||||
self._total_lines_player_two = 0
|
||||
|
||||
# wells init
|
||||
self._well_player_one = Well(ConfigurationManager.get("position", "well-player-1"),\
|
||||
@@ -328,15 +333,20 @@ class MultiplayerScene(Scene):
|
||||
if self._well_player_two is not None:
|
||||
self._well_player_two.draw(surface)
|
||||
|
||||
score_player_one = str(self._score_player_one).zfill(6)
|
||||
score_player_two = str(self._score_player_two).zfill(6)
|
||||
lines_player_one = str(self._stack_player_one.total_lines).zfill(4)
|
||||
lines_player_two = str(self._total_lines_player_two).zfill(4)
|
||||
|
||||
# scores
|
||||
TextGenerator.draw("Score", self._score_label_player_one_pos, surface)
|
||||
TextGenerator.draw("000000", self._score_value_player_one_pos, surface)
|
||||
TextGenerator.draw(score_player_one, self._score_value_player_one_pos, surface)
|
||||
TextGenerator.draw("Score", self._score_label_player_two_pos, surface)
|
||||
TextGenerator.draw("000000", self._score_value_player_two_pos, surface)
|
||||
TextGenerator.draw(score_player_two, self._score_value_player_two_pos, surface)
|
||||
|
||||
# lines
|
||||
TextGenerator.draw("Lines 0000", self._lines_label_player_one_pos, surface)
|
||||
TextGenerator.draw("Lines 0000", self._lines_label_player_two_pos, surface)
|
||||
TextGenerator.draw("Lines " + lines_player_one, self._lines_label_player_one_pos, surface)
|
||||
TextGenerator.draw("Lines " + lines_player_two, self._lines_label_player_two_pos, surface)
|
||||
|
||||
# next
|
||||
TextGenerator.draw("NEXT", self._next_label_player_one_pos, surface)
|
||||
@@ -349,6 +359,13 @@ class MultiplayerScene(Scene):
|
||||
self._stack_player_one.update(elapsed_time)
|
||||
self._update_stack_player_two()
|
||||
|
||||
self._score_player_one += self._points_table[self._stack_player_one.lines_completed_last] * (self._get_level_player_one() + 1)
|
||||
opponent_stats = MultiplayerService.try_receive_stats()
|
||||
if opponent_stats is not None:
|
||||
self._score_player_two = opponent_stats.score
|
||||
self._total_lines_player_two = opponent_stats.lines
|
||||
|
||||
# SEND TO SERVER
|
||||
if self._current_piece_player_one is not None:
|
||||
MultiplayerService.send_piece(PieceDto(self._current_piece_player_one._points,\
|
||||
self._current_piece_player_one._center,\
|
||||
@@ -365,6 +382,7 @@ class MultiplayerScene(Scene):
|
||||
],
|
||||
)
|
||||
)
|
||||
MultiplayerService.send_stats(StatsDto(self._score_player_one, self._stack_player_one.total_lines, False))
|
||||
|
||||
def _update_piece_player_one(self, elapsed_time: int) -> None:
|
||||
if self._current_piece_player_one is not None:
|
||||
|
||||
Reference in New Issue
Block a user