merge with Xamora

This commit is contained in:
Xamora 2024-01-08 20:39:06 +01:00
commit ad50d1a179
18 changed files with 191 additions and 27 deletions

View File

@ -1,10 +0,0 @@
body {
margin: 0.5em;
font-family: 'Quicksand', sans-serif;
font-size: 30px;
}
a {
color: #009579;
}

View File

@ -109,10 +109,15 @@ document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener("click", e => {
if (e.target.matches("[data-link]")) {
e.preventDefault();
document.querySelectorAll('[data-link]').forEach(e => {
e.classList.remove('active');
});
e.target.classList.add('active');
navigateTo(e.target.href.slice(location.origin.length));
}
});
router(location.pathname);
document.querySelector('a[href=\'' + location.pathname + '\']')?.classList.add('active');
});
export { client, navigateTo }

View File

@ -4,18 +4,23 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Single Page App</title>
<link rel="stylesheet" href="{% static 'css/index.css' %}">
<title>Bozo Pong</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
</head>
<body>
<nav class="nav">
<a href="/" class="nav__link" data-link>Dashboard</a>
<a href="/search" class="nav__link" data-link>Search</a>
<a href="/home" class="nav__link" data-link>Home</a>
<a href="/login" class="nav__link" data-link>Login</a>
<a href="/register" class="nav__link" data-link>Register</a>
</nav>
<div id="app"></div>
<body data-bs-theme="dark">
<nav class="navbar navbar-expand-lg bg-body-tertiary rounded m-1">
<div class="container-fluid">
<div class="navbar-nav d-flex flex-row gap-2">
<a href="/" class="nav-link" data-link>Dashboard</a>
<a href="/search" class="nav-link" data-link>Search</a>
<a href="/home" class="nav-link" data-link>Home</a>
<a href="/login" class="nav-link" data-link>Login</a>
<a href="/register" class="nav-link" data-link>Register</a>
</div>
</div>
</nav>
<br>
<div id="app" class="m-2"></div>
<script type="module" src="{% static 'js/index.js' %}"></script>
</body>
</html>

9
games/config.py Normal file
View File

@ -0,0 +1,9 @@
PADDLE_SPEED_MAX = 1
PADDLE_SIZE_HEIGHT = 10
PADDLE_SIZE_WIDTH = 100
PADDLE_RAIL = PADDLE_SIZE_WIDTH * 5
BALL_SPEED_INC = 1
BALL_SPEED_START = 1
BALL_SIZE = 4

42
games/consumers.py Normal file
View File

@ -0,0 +1,42 @@
from channels.generic.websocket import AsyncWebsocketConsumer
from django.contrib.auth.models import User
import json
from .objects.GameRoomManager import GameRoomManager
game_room_manager: GameRoomManager = GameRoomManager()
class GameWebSocket(AsyncWebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.channel_name = "games"
self.group_name = "games"
def connect(self):
self.user: User = self.scope["user"]
if (self.user.is_anonymous or not self.user.is_authenticated):
return
self.channel_layer.group_add(self.group_name, self.channel_name)
self.game_id = int(self.scope['url_route']['kwargs']['game_id'])
self.room = game_room_manager.get(self.game_id)
if (self.room is None):
self.member.send("Tournament not found")
self.disconnect(1017)
self.room.append(self.member)
def receive(self, text_data: str = None, bytes_data: bytes = None):
self.member.receive(text_data, bytes_data)
def disconnect(self, close_code):
member = self.room.get_member_by_socket(self)
if (member is not None):
self.room.remove(self.member, close_code)

View File

@ -1,5 +1,7 @@
from django.db import models
from channels.generic.websocket import AsyncWebsocketConsumer
# Create your models here.
class GameModel(models.Model):

View File

@ -0,0 +1,17 @@
from channels.generic.websocket import AsyncWebsocketConsumer
from transcendence.abstract.AbstractRoomMember import AbstractRoomMember
class GameMember(AbstractRoomMember):
def __init__(self, user_id: int, socket: AsyncWebsocketConsumer):
super().__init__(user_id, socket)
self.is_a_player = False
def receive(self, data: dict):
if (not self.is_a_player):
self.send("You are not a player.")
return
def send_ball(self, ball):
pass

View File

@ -0,0 +1,7 @@
from transcendence.abstract.AbstractRoom import AbstractRoom
class GameRoom(AbstractRoom):
def __init__(self, game_room_manager, game_id: int):
super().__init__(game_room_manager)
self.game_id = game_id

View File

@ -0,0 +1,19 @@
from transcendence.abstract.AbstractRoomManager import AbstractRoomManager
from ..models import GameModel
from . import GameRoom
class GameRoomManager(AbstractRoomManager):
def get(self, game_id: int):
for room in self._room_list:
if (room.game_id == game_id):
return room
if (GameModel.objects.filter(pk = game_id).exists()):
room = GameRoom(self, game_id)
self.append(room)
return room
return None

6
games/routing.py Normal file
View File

@ -0,0 +1,6 @@
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/games/(?P<game_id>\d+)$', consumers.GameWebSocket.as_asgi())
]

View File

@ -21,4 +21,5 @@ class GameSerializer(serializers.ModelSerializer):
return "waiting"
def get_players_id(self, instance: GameModel):
players_id = [player_game.member_id for player_game in GameMembersModel.objects.filter(game_id=instance.pk)]
players_id = [player_game.player_id for player_game in GameMembersModel.objects.filter(game_id = instance.pk)]
return players_id

11
games/urls.py Normal file
View File

@ -0,0 +1,11 @@
from django.urls import path, re_path
from django.conf import settings
from django.conf.urls.static import static
from .viewset import GameViewSet
from .views import GameConfigView
urlpatterns = [
path("<int:pk>", GameViewSet.as_view({"get": "retrieve"}), name="game_page"),
path("", GameConfigView.as_view(), name = "game_config")
]

View File

@ -1,3 +1,23 @@
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions, status
# Create your views here.
from django.http import HttpRequest
from . import config
class GameConfigView(APIView):
permission_classes = (permissions.AllowAny,)
def get(self, request):
config_data = {
"BALL_SIZE": config.BALL_SIZE,
"PADDLE_SPEED_MAX": config.PADDLE_SPEED_MAX,
"PADDLE_SIZE_HEIGHT": config.PADDLE_SIZE_HEIGHT,
"PADDLE_SIZE_WIDTH": config.PADDLE_SIZE_WIDTH,
"PADDLE_RAIL": config.PADDLE_RAIL,
"BALL_SPEED_INC": config.BALL_SPEED_INC,
"BALL_SPEED_START": config.BALL_SPEED_START
}
return Response(config_data, status = status.HTTP_200_OK)

27
games/viewset.py Normal file
View File

@ -0,0 +1,27 @@
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import permissions, status
from rest_framework.authentication import SessionAuthentication
from django.http import HttpRequest
from django.db.models import QuerySet
from .models import GameModel
from .serializers import GameSerializer
# Create your views here.
class GameViewSet(viewsets.ModelViewSet):
queryset = GameModel.objects
serializer_class = GameSerializer
permission_classes = (permissions.AllowAny,)
authentication_classes = (SessionAuthentication,)
def retrieve(self, request: HttpRequest, pk):
if (not self.queryset.filter(pk = pk).exists()):
return Response({"detail": "Game not found."}, status=status.HTTP_404_NOT_FOUND)
game = self.queryset.get(pk=pk)
return Response(self.serializer_class(game).data, status=status.HTTP_200_OK)

View File

@ -12,7 +12,7 @@ class BlockView(APIView):
def get(self, request, pk):
block = BlockModel.objects.filter(pk=pk)
if (block):
if (block.exists()):
return Response(serializers.serialize("json", block), status=status.HTTP_200_OK)
else:
return Response("Not Found", status=status.HTTP_404_NOT_FOUND)

View File

@ -2,5 +2,5 @@ from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/tournaments/(?P<tournament_id>\d+)$', consumers.TournamentWebConsumer.as_asgi())
re_path(r'ws/games/(?P<game_id>\d+)$', consumers.TournamentWebConsumer.as_asgi())
]

View File

@ -14,6 +14,7 @@ from channels.auth import AuthMiddlewareStack
import chat.routing
import matchmaking.routing
import tournament.routing
import games.routing
from django.core.asgi import get_asgi_application
@ -25,7 +26,8 @@ application = ProtocolTypeRouter({
URLRouter(
chat.routing.websocket_urlpatterns +
matchmaking.routing.websocket_urlpatterns +
tournament.routing.websocket_urlpatterns
tournament.routing.websocket_urlpatterns +
games.routing.websocket_urlpatterns
)
)
})

View File

@ -23,5 +23,6 @@ urlpatterns = [
path('api/accounts/', include('accounts.urls')),
path('api/chat/', include('chat.urls')),
path('api/tournaments/', include('tournament.urls')),
path('api/games/', include('games.urls')),
path('', include('frontend.urls')),
]