core: fix: matchmaking and game

This commit is contained in:
2024-04-22 11:37:08 +02:00
parent d31d3e053e
commit e125eb16c7
16 changed files with 135 additions and 134 deletions

View File

@ -3,25 +3,24 @@ from __future__ import annotations
from django.db import models
from django.db.models import QuerySet, CASCADE
from profiles.models import ProfileModel
from django.contrib.auth.models import User
import time
# Create your models here.
class GameModel(models.Model):
finished = models.BooleanField(default = False)
started = models.BooleanField(default = False)
winner = models.ForeignKey(ProfileModel, on_delete=CASCADE, null=True, blank=True)
winner = models.ForeignKey(User, on_delete=CASCADE, null=True, blank=True)
start_timestamp = models.BigIntegerField(null = True, blank = True)
stop_timestamp = models.BigIntegerField(null = True, blank = True)
game_type = models.CharField(max_length = 60, default = "pong")
def create(self, players: list[ProfileModel]):
def create(self, players: list[User]):
self.save()
for player in players:
GameMembersModel(game = self.pk, player=player).save()
GameMembersModel(game = self, player=player).save()
return self.pk
def start(self):
@ -35,9 +34,12 @@ class GameModel(models.Model):
self.stop_timestamp = round(time.time() * 1000, 1)
self.save()
def get_players(self) -> list[ProfileModel]:
def get_players(self) -> list[User]:
return [game_player.player for game_player in GameMembersModel.objects.filter(game = self)]
def get_players_profiles(self) -> list[User]:
return [game_player.player.profilemodel for game_player in GameMembersModel.objects.filter(game = self)]
def get_score_by_player_id(self, player_id: int) -> list[int]:
query: QuerySet = GameGoalModel.objects.filter(game_id = self.pk, player_id = player_id)
score_data: list[int] = [game_goal.timestamp for game_goal in query]
@ -56,10 +58,10 @@ class GameModel(models.Model):
class GameMembersModel(models.Model):
game = models.ForeignKey(GameModel, on_delete=CASCADE)
player = models.ForeignKey(ProfileModel, on_delete=CASCADE)
player = models.ForeignKey(User, on_delete=CASCADE)
class GameGoalModel(models.Model):
game = models.ForeignKey(GameModel, on_delete=CASCADE)
player = models.ForeignKey(ProfileModel, on_delete=CASCADE)
player = models.ForeignKey(User, on_delete=CASCADE)
timestamp = models.IntegerField()

View File

@ -6,6 +6,8 @@ from .ASpectator import ASpectator
from ..models import GameModel
from django.contrib.auth.models import User
class AGame(AbstractRoom):
def __init__(self, game_type: str, game_id: int, game_manager):
@ -16,23 +18,23 @@ class AGame(AbstractRoom):
self.model: GameModel = GameModel.objects.get(pk = game_id, game_type = game_type)
players_id: list[int] = self.model.get_players_id()
players: list[User] = self.model.get_players()
self.players: list[APlayer] = [APlayer(player_id, None, self) for player_id in players_id]
self.players: list[APlayer] = [APlayer(player.pk, None, self) for player in players]
self.spectators: list[ASpectator] = []
self.game_id: int = game_id
def get_players_id(self) -> list[int]:
return [player.user_id for player in self.players]
return [player.pk for player in self.players]
def get_players_connected(self) -> list[APlayer]:
return [player for player in self.players if player.is_connected()]
def get_player_by_user_id(self, user_id: int) -> APlayer:
for player in self.players:
if (player.user_id == user_id):
if (player.user.pk == user_id):
return player
return None

View File

@ -10,9 +10,6 @@ if TYPE_CHECKING:
class APlayer(ASpectator):
def __init__(self, user_id: int, socket: WebsocketConsumer, game: AGame):
super().__init__(user_id, socket, game)
def is_connected(self) -> bool:
return self.socket != None

View File

@ -3,6 +3,8 @@ from channels.generic.websocket import WebsocketConsumer
from transcendence.abstract.AbstractRoomMember import AbstractRoomMember
from django.contrib.auth.models import User
from typing import TYPE_CHECKING
if TYPE_CHECKING:
@ -10,8 +12,8 @@ if TYPE_CHECKING:
class ASpectator(AbstractRoomMember):
def __init__(self, user_id: int, socket: WebsocketConsumer, game):
def __init__(self, user: User, socket: WebsocketConsumer, game):
super().__init__(user_id, socket)
super().__init__(user, socket)
self.game: AGame = game

View File

@ -22,7 +22,7 @@ import threading
from typing import TYPE_CHECKING
if TYPE_CHECKING:
pass
from profiles.models import ProfileModel
class PongGame(AGame):
@ -36,7 +36,7 @@ class PongGame(AGame):
radius: float = min(config.MAP_SIZE_X, config.MAP_SIZE_Y) / 2 - 10
players_id: list[int] = self.model.get_players_id()
players: list[ProfileModel] = self.model.get_players()
nb_sides = 4
@ -58,16 +58,16 @@ class PongGame(AGame):
self.walls: list[Wall]
self.players: list[PongPlayer]
nb_players: int = len(players_id)
nb_players: int = len(players)
if (nb_players == 2):
self.players = [PongPlayer(self, players_id[0], None, segments[0]), PongPlayer(self, players_id[1], None, segments[2])]
self.players = [PongPlayer(self, players[0], None, segments[0]), PongPlayer(self, players[1], None, segments[2])]
self.walls = [Wall(segments[1].start, segments[1].stop), Wall(segments[3].start, segments[3].stop)]
else:
self.players = []
self.walls = []
for i in range(4):
if (i < nb_players):
self.players.append(PongPlayer(self, players_id[i], None, segments[i]))
self.players.append(PongPlayer(self, players[i], None, segments[i]))
else:
self.walls.append(Wall(segments[i]))

View File

@ -17,9 +17,9 @@ if TYPE_CHECKING:
class PongPlayer(APlayer):
def __init__(self, game: PongGame, user_id: int, socket: WebsocketConsumer, rail: Segment) -> None:
def __init__(self, game: PongGame, user: User, socket: WebsocketConsumer, rail: Segment) -> None:
super().__init__(user_id, socket, game)
super().__init__(user, socket, game)
self.position: Position = Position(0.5, 0)
@ -29,8 +29,6 @@ class PongPlayer(APlayer):
self.game: PongGame
self.username: str = User.objects.get(pk = self.user_id).username
def eliminate(self):
self.disconnect(1000)
@ -43,7 +41,7 @@ class PongPlayer(APlayer):
if (detail is None):
return
if (detail == "update_my_paddle_pos"):
self.update_position(data)
@ -119,8 +117,8 @@ class PongPlayer(APlayer):
def to_dict(self) -> dict:
data = {
"username": self.username,
"id": self.user_id,
"username": self.user.username,
"id": self.user.pk,
"position": self.position.to_dict(),
"score": self.score,

View File

@ -270,7 +270,6 @@ async def render_ball(game: PongGame):
async def render_players(game: PongGame):
while True:
for player in game._updated_players:
await SyncToAsync(game.broadcast)("update_player", player.to_dict(), [player])

View File

@ -3,7 +3,8 @@ from rest_framework import serializers
from django.contrib.auth.models import User
from django.db.models import QuerySet
from .models import GameModel, GameMembersModel
from .models import GameModel
from profiles.serializers.ProfileSerializer import ProfileSerializer
class GameSerializer(serializers.ModelSerializer):
@ -28,19 +29,4 @@ class GameSerializer(serializers.ModelSerializer):
return "waiting"
def get_players(self, instance: GameModel):
players_data: list = []
for player_id in instance.get_players_id():
query: QuerySet = User.objects.filter(pk = player_id)
username: str = "Deleted User"
if (query.exists()):
username = query[0].username
data: dict = {
"id": player_id,
"username": username,
"score": instance.get_score_by_player_id(player_id)
}
players_data.append(data)
return players_data
return ProfileSerializer(instance.get_players_profiles(), many=True).data