mirror of
https://github.com/AudebertAdrien/ft_transcendence.git
synced 2026-02-04 11:40:25 +01:00
Merge branch 'chaku' of github.com:AudebertAdrien/ft_transcendence into trash2
This commit is contained in:
commit
86074d359c
1
.env
1
.env
@ -13,6 +13,7 @@ DB_HOST=db
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
PWD_PATH=${PWD}
|
PWD_PATH=${PWD}
|
||||||
PROJECT_PATH=${PWD_PATH}/pong
|
PROJECT_PATH=${PWD_PATH}/pong
|
||||||
|
DJANGO_LOGS=${PWD_PATH}/logs
|
||||||
|
|
||||||
# ElasticSearch settings
|
# ElasticSearch settings
|
||||||
STACK_VERSION=8.14.3
|
STACK_VERSION=8.14.3
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ __pycache__/
|
|||||||
data/
|
data/
|
||||||
.env
|
.env
|
||||||
makefile
|
makefile
|
||||||
|
logs/django.log
|
||||||
|
|||||||
@ -1,21 +1,28 @@
|
|||||||
input {
|
input {
|
||||||
udp {
|
file {
|
||||||
host => "0.0.0.0"
|
path => "/usr/share/logstash/logs/django.log"
|
||||||
port => 5044
|
start_position => "beginning"
|
||||||
|
sincedb_path => "/dev/null"
|
||||||
|
codec => "json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter {}
|
filter {
|
||||||
|
json {
|
||||||
|
source => "message"
|
||||||
|
target => "json_message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
output {
|
output {
|
||||||
elasticsearch {
|
elasticsearch {
|
||||||
index => "logstash-%{+YYYY.MM.dd}"
|
|
||||||
hosts => ["https://es01:9200"]
|
hosts => ["https://es01:9200"]
|
||||||
user => "elastic"
|
user => "elastic"
|
||||||
password => elastic_pass
|
password => "${ELASTIC_PASSWORD}"
|
||||||
ssl_enabled => true
|
ssl_enabled => true
|
||||||
ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt"
|
ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt"
|
||||||
ssl_verification_mode => "full"
|
ssl_verification_mode => "full"
|
||||||
|
index => "django-logs-%{+YYYY.MM.dd}"
|
||||||
|
}
|
||||||
|
stdout { codec => rubydebug }
|
||||||
}
|
}
|
||||||
#stdout {}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -58,8 +58,6 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 120
|
retries: 120
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
backend:
|
backend:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
@ -74,6 +72,7 @@ services:
|
|||||||
venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application"
|
venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application"
|
||||||
volumes:
|
volumes:
|
||||||
- pong:/transcendence/pong
|
- pong:/transcendence/pong
|
||||||
|
- pong_django_logs:/transcendence/logs
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
networks:
|
networks:
|
||||||
@ -200,6 +199,7 @@ services:
|
|||||||
- certs:/usr/share/logstash/certs
|
- certs:/usr/share/logstash/certs
|
||||||
- pong_logstash_data01:/usr/share/logstash/data
|
- pong_logstash_data01:/usr/share/logstash/data
|
||||||
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
|
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
|
||||||
|
- pong_django_logs:/usr/share/logstash/logs
|
||||||
ports:
|
ports:
|
||||||
- "5044:5044/udp"
|
- "5044:5044/udp"
|
||||||
command: logstash -f /usr/share/logstash/pipeline/logstash.conf
|
command: logstash -f /usr/share/logstash/pipeline/logstash.conf
|
||||||
@ -217,6 +217,12 @@ volumes:
|
|||||||
type: none
|
type: none
|
||||||
device: ${PROJECT_PATH}
|
device: ${PROJECT_PATH}
|
||||||
o: bind
|
o: bind
|
||||||
|
pong_django_logs:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
device: ${DJANGO_LOGS}
|
||||||
|
o: bind
|
||||||
pong_pg_data:
|
pong_pg_data:
|
||||||
driver: local
|
driver: local
|
||||||
pong_es_data_01:
|
pong_es_data_01:
|
||||||
|
|||||||
8
makefile
8
makefile
@ -4,7 +4,7 @@ CONTAINER=$(c)
|
|||||||
|
|
||||||
up: down
|
up: down
|
||||||
$(COMPOSE) build
|
$(COMPOSE) build
|
||||||
$(COMPOSE) up $(CONTAINER) || true
|
$(COMPOSE) up -d $(CONTAINER) || true
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(COMPOSE) build $(CONTAINER)
|
$(COMPOSE) build $(CONTAINER)
|
||||||
@ -20,8 +20,8 @@ down:
|
|||||||
|
|
||||||
destroy:
|
destroy:
|
||||||
$(COMPOSE) down -v --rmi all
|
$(COMPOSE) down -v --rmi all
|
||||||
#sudo lsof -i :5432 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true
|
sudo lsof -i :5432 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true
|
||||||
#sudo lsof -i :80 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true
|
sudo lsof -i :80 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true
|
||||||
|
|
||||||
logs:
|
logs:
|
||||||
$(COMPOSE) logs -f $(CONTAINER)
|
$(COMPOSE) logs -f $(CONTAINER)
|
||||||
@ -32,7 +32,7 @@ ps:
|
|||||||
db-shell:
|
db-shell:
|
||||||
$(COMPOSE) exec db psql -U 42student players_db
|
$(COMPOSE) exec db psql -U 42student players_db
|
||||||
|
|
||||||
re: destroy down up
|
re: destroy up
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage:"
|
@echo "Usage:"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from channels.generic.websocket import AsyncWebsocketConsumer
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from channels.db import database_sync_to_async
|
from channels.db import database_sync_to_async
|
||||||
from .matchmaking import match_maker
|
from .matchmaking import match_maker
|
||||||
|
from .tournament import tournament_match_maker
|
||||||
|
|
||||||
class GameConsumer(AsyncWebsocketConsumer):
|
class GameConsumer(AsyncWebsocketConsumer):
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
@ -18,6 +19,8 @@ class GameConsumer(AsyncWebsocketConsumer):
|
|||||||
await self.authenticate(data['token'])
|
await self.authenticate(data['token'])
|
||||||
elif data['type'] == 'authenticate2':
|
elif data['type'] == 'authenticate2':
|
||||||
await self.authenticate2(data['token_1'], data['token_2'])
|
await self.authenticate2(data['token_1'], data['token_2'])
|
||||||
|
elif data['type'] == 'authenticate3':
|
||||||
|
await self.authenticate3(data['token'])
|
||||||
elif data['type'] == 'key_press':
|
elif data['type'] == 'key_press':
|
||||||
if self.game:
|
if self.game:
|
||||||
await self.game.handle_key_press(self, data['key'])
|
await self.game.handle_key_press(self, data['key'])
|
||||||
@ -74,10 +77,25 @@ class GameConsumer(AsyncWebsocketConsumer):
|
|||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def authenticate3(self, token):
|
||||||
|
user = await self.get_user_from_token(token)
|
||||||
|
if user:
|
||||||
|
self.user = user
|
||||||
|
await self.send(text_data=json.dumps({'type': 'authenticated'}))
|
||||||
|
print(f"User {self.user} authenticated")
|
||||||
|
await self.join_tournament_waiting_room()
|
||||||
|
else:
|
||||||
|
await self.send(text_data=json.dumps({'type': 'error', 'message': 'Authentication failed'}))
|
||||||
|
print("Authentication failed")
|
||||||
|
|
||||||
|
async def join_tournament_waiting_room(self):
|
||||||
|
await tournament_match_maker.add_player(self)
|
||||||
|
|
||||||
async def disconnect(self, close_code):
|
async def disconnect(self, close_code):
|
||||||
if self.game:
|
if self.game:
|
||||||
await self.game.end_game(disconnected_player=self)
|
await self.game.end_game(disconnected_player=self)
|
||||||
await match_maker.remove_player(self)
|
await match_maker.remove_player(self)
|
||||||
|
await tournament_match_maker.remove_player(self)
|
||||||
print(f"User {self.user.username if hasattr(self, 'user') else 'Unknown'} disconnected")
|
print(f"User {self.user.username if hasattr(self, 'user') else 'Unknown'} disconnected")
|
||||||
|
|
||||||
async def set_game(self, game):
|
async def set_game(self, game):
|
||||||
|
|||||||
@ -24,7 +24,8 @@ class Game:
|
|||||||
'ball_position': {'x': 390, 'y': 190},
|
'ball_position': {'x': 390, 'y': 190},
|
||||||
'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])},
|
'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])},
|
||||||
'player1_score': 0,
|
'player1_score': 0,
|
||||||
'player2_score': 0
|
'player2_score': 0,
|
||||||
|
'game_text': ''
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
self.botgame = player2 is None
|
self.botgame = player2 is None
|
||||||
@ -36,7 +37,8 @@ class Game:
|
|||||||
'ball_position': {'x': 390, 'y': 190},
|
'ball_position': {'x': 390, 'y': 190},
|
||||||
'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])},
|
'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])},
|
||||||
'player1_score': 0,
|
'player1_score': 0,
|
||||||
'player2_score': 0
|
'player2_score': 0,
|
||||||
|
'game-text': ''
|
||||||
}
|
}
|
||||||
self.speed = 1
|
self.speed = 1
|
||||||
self.game_loop_task = None
|
self.game_loop_task = None
|
||||||
@ -55,9 +57,13 @@ class Game:
|
|||||||
|
|
||||||
async def game_loop(self):
|
async def game_loop(self):
|
||||||
print(" In the game loop..")
|
print(" In the game loop..")
|
||||||
|
x = 0
|
||||||
while not self.ended:
|
while not self.ended:
|
||||||
if self.botgame:
|
if self.botgame:
|
||||||
await self.update_bot_position()
|
x += 1
|
||||||
|
if x == 60:
|
||||||
|
await self.update_bot_position()
|
||||||
|
x = 0
|
||||||
await self.handle_pad_movement()
|
await self.handle_pad_movement()
|
||||||
await self.update_game_state()
|
await self.update_game_state()
|
||||||
await self.send_game_state()
|
await self.send_game_state()
|
||||||
@ -68,9 +74,9 @@ class Game:
|
|||||||
if self.game_state['player2_position'] < target_y < self.game_state['player2_position'] + 80:
|
if self.game_state['player2_position'] < target_y < self.game_state['player2_position'] + 80:
|
||||||
pass
|
pass
|
||||||
elif self.game_state['player2_position'] < target_y:
|
elif self.game_state['player2_position'] < target_y:
|
||||||
self.game_state['player2_position'] = min(self.game_state['player2_position'] + (5 * self.speed), 300)
|
self.game_state['player2_position'] = min(self.game_state['player2_position'] + (50 * self.speed), 300)
|
||||||
elif self.game_state['player2_position'] + 80 > target_y:
|
elif self.game_state['player2_position'] + 80 > target_y:
|
||||||
self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0)
|
self.game_state['player2_position'] = max(self.game_state['player2_position'] - (50 * self.speed), 0)
|
||||||
|
|
||||||
async def update_game_state(self):
|
async def update_game_state(self):
|
||||||
if self.ended:
|
if self.ended:
|
||||||
@ -94,21 +100,18 @@ class Game:
|
|||||||
self.game_state['ball_velocity']['x'] *= -1
|
self.game_state['ball_velocity']['x'] *= -1
|
||||||
self.bt2 += 1
|
self.bt2 += 1
|
||||||
self.update_ball_velocity()
|
self.update_ball_velocity()
|
||||||
# Check for scoring
|
# Check if some player won the game
|
||||||
#print(f"########### score user 1 {self.game_state['player1_score']} ###########")
|
|
||||||
#print(f"§§§§§§§§§§§ score user 2 {self.game_state['player2_score']} §§§§§§§§§§§")
|
|
||||||
|
|
||||||
if self.game_state['ball_position']['x'] <= 10:
|
if self.game_state['ball_position']['x'] <= 10:
|
||||||
self.game_state['player2_score'] += 1
|
self.game_state['player2_score'] += 1
|
||||||
if self.game_state['player2_score'] > 2:
|
if self.game_state['player2_score'] > 2:
|
||||||
print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
self.game_state['game_text'] = f"{self.game_state['player2_name']} WINS!"
|
||||||
await self.send_game_state()
|
await self.send_game_state()
|
||||||
await self.end_game()
|
await self.end_game()
|
||||||
self.reset_ball()
|
self.reset_ball()
|
||||||
elif self.game_state['ball_position']['x'] >= 790:
|
elif self.game_state['ball_position']['x'] >= 790:
|
||||||
self.game_state['player1_score'] += 1
|
self.game_state['player1_score'] += 1
|
||||||
if self.game_state['player1_score'] > 2:
|
if self.game_state['player1_score'] > 2:
|
||||||
print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
self.game_state['game_text'] = f"{self.game_state['player1_name']} WINS!"
|
||||||
await self.send_game_state()
|
await self.send_game_state()
|
||||||
await self.end_game()
|
await self.end_game()
|
||||||
self.reset_ball()
|
self.reset_ball()
|
||||||
@ -201,7 +204,8 @@ class Game:
|
|||||||
'player': disconnected_name
|
'player': disconnected_name
|
||||||
})
|
})
|
||||||
if not self.botgame:
|
if not self.botgame:
|
||||||
await remaining_player.send(message)
|
if not self.localgame:
|
||||||
|
await remaining_player.send(message)
|
||||||
# Notify both players that the game has ended
|
# Notify both players that the game has ended
|
||||||
end_message = json.dumps({
|
end_message = json.dumps({
|
||||||
'type': 'game_ended',
|
'type': 'game_ended',
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class MatchMaker:
|
|||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
self.timer += 1
|
self.timer += 1
|
||||||
# Waiting for more than 30s -> BOT game
|
# Waiting for more than 30s -> BOT game
|
||||||
if self.timer >= 30 and self.waiting_players:
|
if self.timer >= 15 and self.waiting_players:
|
||||||
player1 = self.waiting_players.pop(0)
|
player1 = self.waiting_players.pop(0)
|
||||||
print(f"*** MATCH FOUND: {player1.user.username} vs BOT")
|
print(f"*** MATCH FOUND: {player1.user.username} vs BOT")
|
||||||
self.botgame = True
|
self.botgame = True
|
||||||
@ -110,6 +110,3 @@ class MatchMaker:
|
|||||||
|
|
||||||
# Instance of the class
|
# Instance of the class
|
||||||
match_maker = MatchMaker()
|
match_maker = MatchMaker()
|
||||||
|
|
||||||
# to get what you want use get_player_p_win(player_name) !! (voir utils.py)
|
|
||||||
#
|
|
||||||
10
pong/game/templates/pong/tournament_waiting_room.html
Normal file
10
pong/game/templates/pong/tournament_waiting_room.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!-- templates/tournament_waiting_room.html -->
|
||||||
|
<div class="tournament-waiting-room">
|
||||||
|
<h2>Tournament Waiting Room</h2>
|
||||||
|
<p>Players currently waiting: {{ players|length }}</p>
|
||||||
|
<ul>
|
||||||
|
{% for player in players %}
|
||||||
|
<li>{{ player }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
36
pong/game/tournament.py
Normal file
36
pong/game/tournament.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# /pong/game/tournament.py
|
||||||
|
|
||||||
|
import json
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
|
class TournamentMatchMaker:
|
||||||
|
def __init__(self):
|
||||||
|
self.waiting_players = []
|
||||||
|
|
||||||
|
async def add_player(self, player):
|
||||||
|
if player not in self.waiting_players:
|
||||||
|
self.waiting_players.append(player)
|
||||||
|
print(f"User {player.user.username} joins the TOURNAMENT WAITING ROOM")
|
||||||
|
await self.update_waiting_room()
|
||||||
|
|
||||||
|
async def remove_player(self, player):
|
||||||
|
if player in self.waiting_players:
|
||||||
|
self.waiting_players.remove(player)
|
||||||
|
await self.update_waiting_room()
|
||||||
|
|
||||||
|
async def update_waiting_room(self):
|
||||||
|
html = self.generate_waiting_room_html()
|
||||||
|
for player in self.waiting_players:
|
||||||
|
await player.send(json.dumps({
|
||||||
|
'type': 'update_waiting_room',
|
||||||
|
'html': html
|
||||||
|
}))
|
||||||
|
|
||||||
|
def generate_waiting_room_html(self):
|
||||||
|
context = {
|
||||||
|
'players': [player.user.username for player in self.waiting_players]
|
||||||
|
}
|
||||||
|
return render_to_string('pong/tournament_waiting_room.html', context)
|
||||||
|
|
||||||
|
# Instance of the class
|
||||||
|
tournament_match_maker = TournamentMatchMaker()
|
||||||
@ -22,6 +22,7 @@ from channels.db import database_sync_to_async
|
|||||||
await update_player_statistics(p1)
|
await update_player_statistics(p1)
|
||||||
print("############# END STAT P1")
|
print("############# END STAT P1")
|
||||||
await update_player_statistics(p2)
|
await update_player_statistics(p2)
|
||||||
|
print("############# END STAT P2")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error in endfortheouche: {e}")
|
print(f"Error in endfortheouche: {e}")
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,9 @@ Django settings for pong project.
|
|||||||
Generated by 'django-admin startproject' using Django 3.2.
|
Generated by 'django-admin startproject' using Django 3.2.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import os
|
import os
|
||||||
|
import logging.config
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@ -136,18 +137,36 @@ CHANNEL_LAYERS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1, # The version of the logging configuration schema
|
||||||
'disable_existing_loggers': False,
|
'disable_existing_loggers': False, # Allows existing loggers to keep logging
|
||||||
'handlers': {
|
'formatters': { # Defines how log messages will be formatted
|
||||||
'console': {
|
'json': {
|
||||||
'level': 'DEBUG',
|
'()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
|
||||||
'class': 'logging.StreamHandler',
|
# Formatter that outputs logs in JSON format, which is ideal for ingestion by Logstash.
|
||||||
|
},
|
||||||
|
'default': {
|
||||||
|
'format': '[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s',
|
||||||
|
# This is a basic text formatter with timestamp, log level, logger name, line number, and the actual message.
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'loggers': {
|
'handlers': { # Handlers determine where the log messages are sent
|
||||||
'django': {
|
'file': {
|
||||||
'handlers': ['console'],
|
'level': 'INFO', # Minimum log level to be handled (INFO and above)
|
||||||
'level': 'DEBUG',
|
'class': 'logging.FileHandler',
|
||||||
|
'filename': os.path.join(BASE_DIR, 'logs/django.log'), # The file where logs will be saved
|
||||||
|
'formatter': 'json', # Uses the JSON formatter defined above
|
||||||
|
},
|
||||||
|
'console': {
|
||||||
|
'level': 'DEBUG', # Minimum log level to be handled (DEBUG and above)
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'default', # Uses the default text formatter
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': { # Loggers are the actual log streams that get configured
|
||||||
|
'django': { # The Django logger catches all messages sent by the Django framework
|
||||||
|
'handlers': ['file', 'console'], # Sends logs to both the file and the console
|
||||||
|
'level': 'DEBUG', # Minimum log level to be logged
|
||||||
|
'propagate': True, # If True, messages will be passed to the parent loggers as well
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -28,6 +28,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const loginButton2 = document.getElementById('login2');
|
const loginButton2 = document.getElementById('login2');
|
||||||
|
|
||||||
const gameContainer = document.getElementById('game1');
|
const gameContainer = document.getElementById('game1');
|
||||||
|
const tournamentContainer = document.getElementById('tournament-bracket');
|
||||||
|
|
||||||
const menuButton = document.querySelector('.burger-menu');
|
const menuButton = document.querySelector('.burger-menu');
|
||||||
const dropdownMenu = document.getElementById('dropdown-menu');
|
const dropdownMenu = document.getElementById('dropdown-menu');
|
||||||
@ -351,7 +352,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startTournament() {
|
function startTournament() {
|
||||||
console.log("For now, do nothing, hurry up and work Senor chaku !!!!")
|
tournamentContainer.style.display = 'flex';
|
||||||
|
logo.style.display = 'none';
|
||||||
|
pongElements.style.display = 'none';
|
||||||
|
//menuButton.style.display = 'none';
|
||||||
|
formBlock.style.display = 'none';
|
||||||
|
startWebSocketConnection(token, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startWebSocketConnection(token, players) {
|
function startWebSocketConnection(token, players) {
|
||||||
@ -360,11 +366,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
socket.onopen = function (event) {
|
socket.onopen = function (event) {
|
||||||
console.log('WebSocket connection established');
|
console.log('WebSocket connection established');
|
||||||
if (players === 1) {
|
if (players === 1) {
|
||||||
console.log("Sending token for 1 player game");
|
console.log("Sending token for a quick match game");
|
||||||
socket.send(JSON.stringify({ type: 'authenticate', token: token }));
|
socket.send(JSON.stringify({ type: 'authenticate', token: token }));
|
||||||
} else {
|
} else if (players === 2) {
|
||||||
console.log("Sending tokens for 2 player game");
|
console.log("Sending tokens for a local game");
|
||||||
socket.send(JSON.stringify({ type: 'authenticate2', token_1: token, token_2: token2 }));
|
socket.send(JSON.stringify({ type: 'authenticate2', token_1: token, token_2: token2 }));
|
||||||
|
} else {
|
||||||
|
console.log("Sending token for a tournament game")
|
||||||
|
socket.send(JSON.stringify({ type: 'authenticate3', token: token }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -376,7 +385,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
console.log('Entered the WAITING ROOM');
|
console.log('Entered the WAITING ROOM');
|
||||||
} else if (data.type === 'game_start') {
|
} else if (data.type === 'game_start') {
|
||||||
console.log('Game started:', data.game_id, '(', data.player1, 'vs', data.player2, ')');
|
console.log('Game started:', data.game_id, '(', data.player1, 'vs', data.player2, ')');
|
||||||
startGame(data.game_id, data.player1, data.player2);
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
} else if (data.type === 'game_state_update') {
|
} else if (data.type === 'game_state_update') {
|
||||||
updateGameState(data.game_state);
|
updateGameState(data.game_state);
|
||||||
} else if (data.type === 'player_disconnected') {
|
} else if (data.type === 'player_disconnected') {
|
||||||
@ -385,6 +394,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
console.log("Game ended:", data.game_id);
|
console.log("Game ended:", data.game_id);
|
||||||
} else if (data.type === 'error') {
|
} else if (data.type === 'error') {
|
||||||
console.error(data.message);
|
console.error(data.message);
|
||||||
|
} else if (data.type === 'update_waiting_room') {
|
||||||
|
document.getElementById('tournament-bracket').innerHTML = data.html;
|
||||||
} else {
|
} else {
|
||||||
console.log('Message from server:', data.type, data.message);
|
console.log('Message from server:', data.type, data.message);
|
||||||
}
|
}
|
||||||
@ -399,14 +410,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function startGame(gameCode, player1_name, player2_name) {
|
|
||||||
document.getElementById('gameCode').textContent = `Game Code: ${gameCode}`;
|
|
||||||
document.getElementById('player1-name').textContent = `${player1_name}`;
|
|
||||||
document.getElementById('player2-name').textContent = `${player2_name}`;
|
|
||||||
document.addEventListener('keydown', handleKeyDown);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'w' || event.key === 's') {
|
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'w' || event.key === 's') {
|
||||||
//console.log('Key press: ', event.key);
|
//console.log('Key press: ', event.key);
|
||||||
@ -427,24 +430,21 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderGame() {
|
function renderGame() {
|
||||||
const player1Pad = document.getElementById('player1-pad');
|
document.getElementById('player1-name').textContent = `${gameState.player1_name}`;
|
||||||
player1Pad.style.top = `${gameState.player1_position}px`;
|
document.getElementById('player2-name').textContent = `${gameState.player2_name}`;
|
||||||
|
|
||||||
const player2Pad = document.getElementById('player2-pad');
|
document.getElementById('player1-pad').style.top = `${gameState.player1_position}px`;
|
||||||
player2Pad.style.top = `${gameState.player2_position}px`;
|
document.getElementById('player2-pad').style.top = `${gameState.player2_position}px`;
|
||||||
|
|
||||||
const ball = document.getElementById('ball');
|
document.getElementById('ball').style.left = `${gameState.ball_position.x}px`;
|
||||||
ball.style.left = `${gameState.ball_position.x}px`;
|
document.getElementById('ball').style.top = `${gameState.ball_position.y}px`;
|
||||||
ball.style.top = `${gameState.ball_position.y}px`;
|
|
||||||
|
|
||||||
const player1Score = document.getElementById('player1-score');
|
document.getElementById('player1-score').textContent = gameState.player1_score;
|
||||||
player1Score.textContent = gameState.player1_score;
|
document.getElementById('player2-score').textContent = gameState.player2_score;
|
||||||
|
|
||||||
const player2Score = document.getElementById('player2-score');
|
document.getElementById('game-text').textContent = gameState.game_text;
|
||||||
player2Score.textContent = gameState.player2_score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////// BEG BURGER BUTTON ////////////////////////////////
|
////////////////////////////// BEG BURGER BUTTON ////////////////////////////////
|
||||||
|
|
||||||
menuButton.addEventListener('click', toggleMenu);
|
menuButton.addEventListener('click', toggleMenu);
|
||||||
@ -557,28 +557,31 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const matchListBody = document.querySelector('#match-list tbody');
|
const matchListBody = document.querySelector('#match-list tbody');
|
||||||
matchListBody.innerHTML = '';
|
matchListBody.innerHTML = '';
|
||||||
|
|
||||||
if (matches.length === 0) {
|
if (matches.length != 0) {
|
||||||
console.log('No matches to display');
|
matches.forEach(match => {
|
||||||
}
|
const row = document.createElement('tr');
|
||||||
|
row.innerHTML = `
|
||||||
matches.forEach(match => {
|
<td>${match.id}</td>
|
||||||
const row = document.createElement('tr');
|
<td>${match.player1__name}</td>
|
||||||
row.innerHTML = `
|
<td>${match.player2__name}</td>
|
||||||
<td>${match.id}</td>
|
<td>${match.score_player1}</td>
|
||||||
<td>${match.player1__name}</td>
|
<td>${match.score_player2}</td>
|
||||||
<td>${match.player2__name}</td>
|
<td>${match.winner__name}</td>
|
||||||
<td>${match.score_player1}</td>
|
<td>${match.nbr_ball_touch_p1}</td>
|
||||||
<td>${match.score_player2}</td>
|
<td>${match.nbr_ball_touch_p2}</td>
|
||||||
<td>${match.winner__name}</td>
|
<td>${match.duration}</td>
|
||||||
<td>${match.nbr_ball_touch_p1}</td>
|
<td>${match.date}</td>
|
||||||
<td>${match.nbr_ball_touch_p2}</td>
|
<td>${match.is_tournoi}</td>
|
||||||
<td>${match.duration}</td>
|
<td>${match.tournoi__name}</td>
|
||||||
<td>${match.date}</td>
|
`;
|
||||||
<td>${match.is_tournoi}</td>
|
matchListBody.appendChild(row);
|
||||||
<td>${match.tournoi__name}</td>
|
});
|
||||||
`;
|
} else {
|
||||||
matchListBody.appendChild(row);
|
row.innerHTML = `
|
||||||
});
|
<td colspan="12">No matches found.</td>
|
||||||
|
`;
|
||||||
|
matchListBody.appendChild(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayPlayers(players) {
|
function displayPlayers(players) {
|
||||||
@ -586,51 +589,58 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const playersListBody = document.querySelector('#player-list tbody');
|
const playersListBody = document.querySelector('#player-list tbody');
|
||||||
playersListBody.innerHTML = '';
|
playersListBody.innerHTML = '';
|
||||||
|
|
||||||
if (players.length === 0) {
|
if (players.length != 0) {
|
||||||
console.log('No players to display');
|
players.forEach(player => {
|
||||||
}
|
const row = document.createElement('tr');
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${player.id}</td>
|
||||||
|
<td>${player.name}</td>
|
||||||
|
<td>${player.total_match}</td>
|
||||||
|
<td>${player.total_win}</td>
|
||||||
|
<td>${player.p_win}</td>
|
||||||
|
<td>${player.m_score_match}</td>
|
||||||
|
<td>${player.m_score_adv_match}</td>
|
||||||
|
<td>${player.best_score}</td>
|
||||||
|
<td>${player.m_nbr_ball_touch}</td>
|
||||||
|
<td>${player.total_duration}</td>
|
||||||
|
<td>${player.m_duration}</td>
|
||||||
|
<td>${player.num_participated_tournaments}</td>
|
||||||
|
<td>${player.num_won_tournaments}</td>
|
||||||
|
`;
|
||||||
|
playersListBody.appendChild(row);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
row.innerHTML = `
|
||||||
|
<td colspan="12">No matches found.</td>
|
||||||
|
`
|
||||||
|
playersListBody.appendChild(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
players.forEach(player => {
|
function displayTournois(tournois) {
|
||||||
const row = document.createElement('tr');
|
console.log('Displaying tournois:');
|
||||||
row.innerHTML = `
|
const tournoisListBody = document.querySelector('#tournoi-list tbody');
|
||||||
<td>${player.id}</td>
|
tournoisListBody.innerHTML = '';
|
||||||
<td>${player.name}</td>
|
|
||||||
<td>${player.total_match}</td>
|
|
||||||
<td>${player.total_win}</td>
|
|
||||||
<td>${player.p_win}</td>
|
|
||||||
<td>${player.m_score_match}</td>
|
|
||||||
<td>${player.m_score_adv_match}</td>
|
|
||||||
<td>${player.best_score}</td>
|
|
||||||
<td>${player.m_nbr_ball_touch}</td>
|
|
||||||
<td>${player.total_duration}</td>
|
|
||||||
<td>${player.m_duration}</td>
|
|
||||||
<td>${player.num_participated_tournaments}</td>
|
|
||||||
<td>${player.num_won_tournaments}</td>
|
|
||||||
`;
|
|
||||||
playersListBody.appendChild(row);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayTournois(tournois) {
|
if (tournois.length != 0) {
|
||||||
console.log('Displaying tournois:');
|
tournois.forEach(tournoi => {
|
||||||
const tournoisListBody = document.querySelector('#tournoi-list tbody');
|
const row = document.createElement('tr');
|
||||||
tournoisListBody.innerHTML = '';
|
row.innerHTML = `
|
||||||
|
<td>${tournoi.id}</td>
|
||||||
|
<td>${tournoi.name}</td>
|
||||||
|
<td>${tournoi.nbr_player}</td>
|
||||||
|
<td>${tournoi.date}</td>
|
||||||
|
<td>${tournoi.winner.name}</td>
|
||||||
|
`;
|
||||||
|
tournoisListBody.appendChild(row);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
row.innerHTML = `
|
||||||
|
<td colspan="12">No matches found.</td>
|
||||||
|
`
|
||||||
|
tournoisListBody.appendChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
if (tournois.length === 0) {
|
|
||||||
console.log('No tournois to display');
|
|
||||||
}
|
|
||||||
|
|
||||||
tournois.forEach(tournoi => {
|
|
||||||
const row = document.createElement('tr');
|
|
||||||
row.innerHTML = `
|
|
||||||
<td>${tournoi.id}</td>
|
|
||||||
<td>${tournoi.name}</td>
|
|
||||||
<td>${tournoi.nbr_player}</td>
|
|
||||||
<td>${tournoi.date}</td>
|
|
||||||
<td>${tournoi.winner.name}</td>
|
|
||||||
`;
|
|
||||||
tournoisListBody.appendChild(row);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////// END BURGER BUTTON ////////////////////////////////
|
////////////////////////////// END BURGER BUTTON ////////////////////////////////
|
||||||
|
|||||||
@ -111,8 +111,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="tournament-bracket" style="display: none;"></div>
|
||||||
|
|
||||||
<div id="game1" style="display: none;">
|
<div id="game1" style="display: none;">
|
||||||
<div id="gameCode" class="game-code">Game Code : </div>
|
|
||||||
<div id="player1-name" class="name">Player 1</div>
|
<div id="player1-name" class="name">Player 1</div>
|
||||||
<div id="player2-name" class="name">Player 2</div>
|
<div id="player2-name" class="name">Player 2</div>
|
||||||
<div id="game2">
|
<div id="game2">
|
||||||
@ -121,6 +122,7 @@
|
|||||||
<div id="player1-pad" class="pad"></div>
|
<div id="player1-pad" class="pad"></div>
|
||||||
<div id="player2-pad" class="pad"></div>
|
<div id="player2-pad" class="pad"></div>
|
||||||
<div id="ball"></div>
|
<div id="ball"></div>
|
||||||
|
<div id="game-text" class="gameText"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -144,27 +146,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for match in matches %}
|
</tbody>
|
||||||
<tr>
|
|
||||||
<td>{{ match.id }}</td>
|
|
||||||
<td>{{ match.player1.name }}</td>
|
|
||||||
<td>{{ match.player2.name }}</td>
|
|
||||||
<td>{{ match.score_player1 }}</td>
|
|
||||||
<td>{{ match.score_player2 }}</td>
|
|
||||||
<td>{{ match.winner.name }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p1 }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p2 }}</td>
|
|
||||||
<td>{{ match.duration }}</td>
|
|
||||||
<td>{{ match.date }}</td>
|
|
||||||
<td>{{ match.is_tournoi }}</td>
|
|
||||||
<td>{{ match.tournoi.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="12">No matches found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -189,28 +171,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for player in players %}
|
</tbody>
|
||||||
<tr>
|
|
||||||
<td>{{ player.id }}</td>
|
|
||||||
<td>{{ player.name }}</td>
|
|
||||||
<td>{{ player.total_match }}</td>
|
|
||||||
<td>{{ player.total_win }}</td>
|
|
||||||
<td>{{ player.p_win }}</td>
|
|
||||||
<td>{{ player.m_score_match }}</td>
|
|
||||||
<td>{{ player.m_score_adv_match }}</td>
|
|
||||||
<td>{{ player.best_score }}</td>
|
|
||||||
<td>{{ player.m_nbr_ball_touch }}</td>
|
|
||||||
<td>{{ player.total_duration }}</td>
|
|
||||||
<td>{{ player.m_duration }}</td>
|
|
||||||
<td>{{ player.num_participated_tournaments }}</td>
|
|
||||||
<td>{{ player.num_won_tournaments }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="13">No players found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -226,21 +187,8 @@
|
|||||||
<th>Winner</th>
|
<th>Winner</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for tournoi in tournois %}
|
</tbody>
|
||||||
<tr>
|
|
||||||
<td>{{ tournoi.id }}</td>
|
|
||||||
<td>{{ tournoi.name }}</td>
|
|
||||||
<td>{{ tournoi.nbr_player }}</td>
|
|
||||||
<td>{{ tournoi.date }}</td>
|
|
||||||
<td>{{ tournoi.winner.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="14">No tournois found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -59,20 +59,10 @@ button:hover {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-code {
|
|
||||||
font-size: 24px;
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gameCode {
|
|
||||||
left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 30px;
|
top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#player1-name {
|
#player1-name {
|
||||||
@ -144,6 +134,13 @@ button:hover {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#game-text {
|
||||||
|
font-size: 64px;
|
||||||
|
color: #00ffff;
|
||||||
|
position: absolute;
|
||||||
|
top: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
Django
|
django
|
||||||
psycopg2
|
psycopg2
|
||||||
python-dotenv
|
python-dotenv
|
||||||
channels
|
channels
|
||||||
daphne
|
daphne
|
||||||
djangorestframework
|
djangorestframework
|
||||||
web3
|
web3
|
||||||
|
python-json-logger==2.0.7
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user