fresh start

This commit is contained in:
Theouche 2024-08-28 16:38:39 +02:00
parent c2e55cc504
commit a8103c122d
12 changed files with 382 additions and 489 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os import os
import sys import sys

View File

@ -18,7 +18,7 @@ django.setup()
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack from channels.auth import AuthMiddlewareStack
import pong.game.routing # Import your routing module import pong.game.routing
application = ProtocolTypeRouter({ application = ProtocolTypeRouter({
"http": get_asgi_application(), "http": get_asgi_application(),

View File

@ -4,7 +4,7 @@ import json
import asyncio import asyncio
import random import random
from datetime import datetime from datetime import datetime
from .utils import endfortheouche from .utils import handle_game_data
from asgiref.sync import sync_to_async from asgiref.sync import sync_to_async
@ -75,9 +75,9 @@ class Game:
target_y = future_ball_position['y'] target_y = future_ball_position['y']
player2_position = self.game_state['player2_position'] player2_position = self.game_state['player2_position']
# Ajuste la position du bot en fonction de la position prévue de la balle # Adjusts bot position based on expected ball position
if player2_position < target_y < player2_position + 80: if player2_position < target_y < player2_position + 80:
pass # Pas besoin de bouger, le bot est déjà bien placé pass #bot already placed
elif player2_position < target_y: elif player2_position < target_y:
self.game_state['player2_position'] = min(player2_position + (50 * self.speed), 300) self.game_state['player2_position'] = min(player2_position + (50 * self.speed), 300)
elif player2_position + 80 > target_y: elif player2_position + 80 > target_y:
@ -94,9 +94,9 @@ class Game:
future_x += velocity_x future_x += velocity_x
future_y += velocity_y future_y += velocity_y
# Gérer les rebonds sur les murs # Dealing with bounces off walls
if future_y <= 0 or future_y >= 300: if future_y <= 0 or future_y >= 300:
velocity_y = -velocity_y # Inverser la direction du mouvement vertical velocity_y = -velocity_y # Reverse the direction of vertical movement
return {'x': future_x, 'y': future_y} return {'x': future_x, 'y': future_y}
@ -206,9 +206,7 @@ class Game:
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'] + (5 * self.speed), 300)
async def end_game(self, disconnected_player=None): async def end_game(self, disconnected_player=None):
print("end GAME CALLED")
if not self.ended: if not self.ended:
print("Game ended !!!!! ")
self.ended = True self.ended = True
if self.game_loop_task: if self.game_loop_task:
self.game_loop_task.cancel() self.game_loop_task.cancel()
@ -237,7 +235,6 @@ class Game:
if not self.botgame: if not self.botgame:
if not self.localgame: if not self.localgame:
await self.player2.send(end_message) await self.player2.send(end_message)
print("save data") await sync_to_async(handle_game_data)(self.game_state['player1_name'], self.game_state['player2_name'],
await sync_to_async(endfortheouche)(self.game_state['player1_name'], self.game_state['player2_name'],
self.game_state['player1_score'], self.game_state['player2_score'], self.game_state['player1_score'], self.game_state['player2_score'],
self.bt1, self.bt2, duration, False, None) self.bt1, self.bt2, duration, False, None)

View File

@ -4,7 +4,6 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
User.add_to_class('auth_token', models.CharField(max_length=100, null=True, blank=True, unique=True)) User.add_to_class('auth_token', models.CharField(max_length=100, null=True, blank=True, unique=True))
# Create your models here.
class Player(models.Model): class Player(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
@ -55,7 +54,7 @@ class Match(models.Model):
super().clean() super().clean()
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.clean() # Appel de la méthode clean() avant d'enregistrer self.clean()
super().save(*args, **kwargs) super().save(*args, **kwargs)
def __str__(self): def __str__(self):

View File

@ -4,34 +4,22 @@ from django.shortcuts import get_object_or_404
from django.db.models import Max, Sum, F from django.db.models import Max, Sum, F
from datetime import timedelta from datetime import timedelta
from channels.db import database_sync_to_async from channels.db import database_sync_to_async
#from asgiref.sync import database_sync_to_async
######## try synchrone version ######## def handle_game_data(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament):
def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament):
try: try:
print("Debut de endfortheouche")
print(f"Paramètres : p1={p1}, p2={p2}, s_p1={s_p1}, s_p2={s_p2}")
# Vérification de l'existence des joueurs et création si nécessaire
player_1 = get_or_create_player(p1) player_1 = get_or_create_player(p1)
player_2 = get_or_create_player(p2) player_2 = get_or_create_player(p2)
print("ok")
print("############# BEFORE MATCH")
create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament)
print("############# AFTER DONE")
update_player_statistics(p1) update_player_statistics(p1)
print("############# END STAT P1")
update_player_statistics(p2) update_player_statistics(p2)
except Exception as e: except Exception as e:
print(f"Error in endfortheouche: {e}") print(f"Error in endfortheouche: {e}")
def get_player_by_name(name): def get_player_by_name(name):
print(f"Checking if player '{name}' exists")
exists = Player.objects.filter(name=name).exists() exists = Player.objects.filter(name=name).exists()
print(f"Player exists: {exists}")
return exists return exists
@ -40,19 +28,12 @@ def get_player(name):
def get_or_create_player(name): def get_or_create_player(name):
print("here !!")
print(f"Checking existence for player: {name}")
player_exists = get_player_by_name(name) player_exists = get_player_by_name(name)
print(f"END search in database!! (Player exists: {player_exists})")
if not player_exists: if not player_exists:
print("Player does not exist, creating player...")
player = create_player(name) player = create_player(name)
print(f"Player created: {player}")
return player return player
else: else:
print("Player exists, fetching player...")
player = get_player(name) player = get_player(name)
print(f"Player fetched: {player}")
return player return player
@ -70,7 +51,6 @@ def create_player(
num_participated_tournaments=0, num_participated_tournaments=0,
num_won_tournaments=0 num_won_tournaments=0
): ):
print("create player !!!")
player = Player( player = Player(
name=name, name=name,
@ -118,20 +98,15 @@ def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_
return match return match
def update_player_statistics(player_name): def update_player_statistics(player_name):
print("############# BEG STAT P")
player = get_object_or_404(Player, name=player_name) player = get_object_or_404(Player, name=player_name)
# Filtrer les matchs où le joueur est joueur 1 ou joueur 2
print("############# HERE")
matches_as_player1 = Match.objects.filter(player1=player) matches_as_player1 = Match.objects.filter(player1=player)
matches_as_player2 = Match.objects.filter(player2=player) matches_as_player2 = Match.objects.filter(player2=player)
print("############# ACTUALLY, IT'S GOOD")
# Calculer les statistiques
total_match = matches_as_player1.count() + matches_as_player2.count() total_match = matches_as_player1.count() + matches_as_player2.count()
# avoid dividing by 0
if total_match == 0: if total_match == 0:
# Eviter la division par zéro
player.total_match = total_match player.total_match = total_match
player.total_win = 0 player.total_win = 0
player.p_win = 0 player.p_win = 0
@ -179,7 +154,6 @@ def update_player_statistics(player_name):
best_score_as_player2 = matches_as_player2.aggregate(Max('score_player2'))['score_player2__max'] or 0 best_score_as_player2 = matches_as_player2.aggregate(Max('score_player2'))['score_player2__max'] or 0
best_score = max(best_score_as_player1, best_score_as_player2) best_score = max(best_score_as_player1, best_score_as_player2)
# Mettre à jour les champs du joueur
player.total_match = total_match player.total_match = total_match
player.total_win = total_win player.total_win = total_win
player.p_win = p_win player.p_win = p_win
@ -193,11 +167,8 @@ def update_player_statistics(player_name):
#player.num_won_tournaments = total_win_tourn #player.num_won_tournaments = total_win_tourn
player.save() player.save()
print("CHAKU IS THE BEST")
def get_player_p_win(player_name): def get_player_p_win(player_name):
# Rechercher le joueur par son nom
player = get_object_or_404(Player, name=player_name) player = get_object_or_404(Player, name=player_name)
# Retourner la valeur de p_win
return player.p_win return player.p_win

View File

@ -1,10 +1,6 @@
# /pong/game/views.py # /pong/game/views.py
from django.shortcuts import render from django.shortcuts import render
def index(request):
return render(request, 'index.html')
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from .models import Player, Tournoi, Match from .models import Player, Tournoi, Match
from .utils import create_player, create_tournoi, create_match from .utils import create_player, create_tournoi, create_match
@ -12,12 +8,14 @@ from django.http import JsonResponse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
""" from .serializers import MatchSerializer """
from rest_framework import viewsets from rest_framework import viewsets
import json import json
import uuid import uuid
def index(request):
return render(request, 'index.html')
@csrf_exempt @csrf_exempt
def check_user_exists(request): def check_user_exists(request):
if request.method == 'POST': if request.method == 'POST':
@ -69,11 +67,6 @@ def get_or_create_token(user):
break break
return user.auth_token return user.auth_token
####################### THEOUCHE PART ############################
from django.http import JsonResponse
def match_list_json(request): def match_list_json(request):
matches = Match.objects.all() matches = Match.objects.all()
data = { data = {
@ -86,10 +79,8 @@ def match_list_json(request):
return JsonResponse(data) return JsonResponse(data)
def player_list_json(request): def player_list_json(request):
# Récupère tous les joueurs
players = Player.objects.all() players = Player.objects.all()
# Crée un dictionnaire avec les informations des joueurs
data = { data = {
'players': list(players.values( 'players': list(players.values(
'id', 'name', 'total_match', 'total_win', 'p_win', 'id', 'name', 'total_match', 'total_win', 'p_win',
@ -98,31 +89,19 @@ def player_list_json(request):
'num_participated_tournaments', 'num_won_tournaments' 'num_participated_tournaments', 'num_won_tournaments'
)) ))
} }
# Renvoie les données en JSON
return JsonResponse(data) return JsonResponse(data)
def tournoi_list_json(request): def tournoi_list_json(request):
# Récupère tous les joueurs
tournois = Tournoi.objects.all() tournois = Tournoi.objects.all()
# Crée un dictionnaire avec les informations des joueurs
data = { data = {
'tournois': list(tournois.values( 'tournois': list(tournois.values(
'id', 'name', 'nbr_player', 'date', 'winner' 'id', 'name', 'nbr_player', 'date', 'winner'
)) ))
} }
# Renvoie les données en JSON
return JsonResponse(data) return JsonResponse(data)
####################### THEOUCHE PART ############################
####################### jcheca PART ############################
from web3 import Web3 from web3 import Web3
provider = Web3.HTTPProvider("https://sepolia.infura.io/v3/60e51df7c97c4f4c8ab41605a4eb9907") provider = Web3.HTTPProvider("https://sepolia.infura.io/v3/60e51df7c97c4f4c8ab41605a4eb9907")

View File

@ -35,8 +35,8 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'channels', # Add Django Channels 'channels',
'pong.game', # Your game app 'pong.game',
'rest_framework' 'rest_framework'
] ]
@ -68,7 +68,7 @@ TEMPLATES = [
}, },
] ]
ASGI_APPLICATION = 'pong.asgi.application' # Add ASGI application ASGI_APPLICATION = 'pong.asgi.application'
# Database # Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases # https://docs.djangoproject.com/en/3.2/ref/settings/#databases

244
pong/static/burger.js Normal file
View File

@ -0,0 +1,244 @@
document.addEventListener('DOMContentLoaded', () => {
const menuButton = document.querySelector('.burger-menu');
const dropdownMenu = document.getElementById('dropdown-menu');
const playerList = document.getElementById('player-list');
const matchList = document.getElementById('match-list');
const tournoiList = document.getElementById('tournoi-list');
const blockchainList = document.getElementById('blockchain-list');
menuButton.addEventListener('click', toggleMenu);
function toggleMenu() {
console.log('Menu toggled');
if (dropdownMenu.style.display === "block") {
dropdownMenu.style.display = "none";
hideAllTables();
} else {
dropdownMenu.style.display = "block";
}
}
function hideAllTables(){
if (playerList) playerList.style.display = 'none';
if (matchList) matchList.style.display = 'none';
if (tournoiList) tournoiList.style.display = 'none';
if (blockchainList) blockchainList.style.display = 'none';
}
const links = document.querySelectorAll('#dropdown-menu a');
links.forEach(link => {
link.addEventListener('click', (event) => {
event.preventDefault();
const tableId = link.getAttribute('data-table');
showTable(tableId);
});
});
function showTable(tableId) {
hideAllTables();
if (tableId === 'player-list') {
playerList.style.display = 'block';
fetchPlayers();
} else if (tableId === 'match-list') {
matchList.style.display = 'block';
fetchMatches();
} else if (tableId === 'tournoi-list') {
tournoiList.style.display = 'block';
fetchTournois();
} else if (tableId === 'blockchain-list') {
console.log('Opening external page in a new tab');
window.open('https://sepolia.etherscan.io/address/0x078d04eb6fb97cd863361fc86000647dc876441b', '_blank');
}
if (dropdownMenu) {
dropdownMenu.style.display = 'none';
}
}
function fetchMatches() {
console.log('Fetching matches...');
fetch('/api/match_list/')
.then(response => response.json())
.then(data => {
if (data.matches) {
displayMatches(data.matches);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function fetchPlayers(){
console.log('Fetching players...');
fetch('/api/player_list/')
.then(response => response.json())
.then(data => {
if (data.players) {
displayPlayers(data.players);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function fetchTournois(){
console.log('Fetching tournois...');
fetch('/api/tournoi_list/')
.then(response => response.json())
.then(data => {
if (data.tournois) {
displayTournois(data.tournois);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function displayMatches(matches) {
console.log('Displaying matches:');
const matchListBody = document.querySelector('#match-list tbody');
matchListBody.innerHTML = '';
if (matches.length != 0) {
matches.forEach(match => {
const row = document.createElement('tr');
row.innerHTML = `
<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>
`;
matchListBody.appendChild(row);
});
} else {
row.innerHTML = `
<td colspan="12">No matches found.</td>
`;
matchListBody.appendChild(row);
}
}
function displayPlayers(players) {
console.log('Displaying players:');
const playersListBody = document.querySelector('#player-list tbody');
playersListBody.innerHTML = '';
if (players.length != 0) {
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);
}
}
function displayTournois(tournois) {
console.log('Displaying tournois:');
const tournoisListBody = document.querySelector('#tournoi-list tbody');
tournoisListBody.innerHTML = '';
if (tournois.length != 0) {
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);
});
} else {
row.innerHTML = `
<td colspan="12">No matches found.</td>
`
tournoisListBody.appendChild(row);
}
}
document.getElementById('search-player').addEventListener('input', filterPlayers);
document.getElementById('search-match-player').addEventListener('input', filterMatches);
document.getElementById('search-match-date').addEventListener('input', filterMatches);
function filterPlayers() {
const searchValue = document.getElementById('search-player').value.toLowerCase();
const playersListBody = document.querySelector('#player-list tbody');
const rows = playersListBody.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const nameCell = rows[i].getElementsByTagName('td')[1];
if (nameCell) {
const nameValue = nameCell.textContent || nameCell.innerText;
if (nameValue.toLowerCase().indexof(searchValue) > -1 ) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
}
function filterMatches() {
const playerSearchValue = document.getElementById('search-match-player').value.toLowerCase();
const dateSearchValue = document.getElementById('search-match-date').value;
const matchListBody = document.querySelector('#match-list tbody');
const rows = matchListBody.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const player1Cell = rows[i].getElementsByTagName('td')[1];
const player2Cell = rows[i].getElementsByTagName('td')[2];
const dateCell = rows[i].getElementsByTagName('td')[9];
let playerMatch = true;
if (playerSearchValue) {
const player1Value = player1Cell.textContent || player1Cell.innerText;
const player2Value = player2Cell.textContent || player2Cell.innerText;
playerMatch = player1Value.toLowerCase().indexOf(playerSearchValue) > -1 ||
player2Value.toLowerCase().indexOf(playerSearchValue) > -1;
}
let dateMatch = true;
if (dateSearchValue) {
const dateValue = dateCell.textContent || dateCell.innerText;
dateMatch = dateValue.startsWith(dateSearchValue);
}
if (playerMatch && dateMatch) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
});

View File

@ -30,14 +30,6 @@ document.addEventListener('DOMContentLoaded', () => {
const gameContainer = document.getElementById('game1'); const gameContainer = document.getElementById('game1');
const tournamentContainer = document.getElementById('tournament-bracket'); const tournamentContainer = document.getElementById('tournament-bracket');
const menuButton = document.querySelector('.burger-menu');
const dropdownMenu = document.getElementById('dropdown-menu');
const playerList = document.getElementById('player-list');
const matchList = document.getElementById('match-list');
const tournoiList = document.getElementById('tournoi-list');
const blockchainList = document.getElementById('blockchain-list');
const pongElements = document.getElementById('pong-elements'); const pongElements = document.getElementById('pong-elements');
const logo = document.querySelector('.logo'); const logo = document.querySelector('.logo');
@ -79,7 +71,6 @@ document.addEventListener('DOMContentLoaded', () => {
if (exists) { if (exists) {
authForm.style.display = 'none'; authForm.style.display = 'none';
loginForm.style.display = 'block'; loginForm.style.display = 'block';
// Auto-focus and key handling for LOGIN-FORM
loginPasswordInput.focus(); loginPasswordInput.focus();
loginPasswordInput.addEventListener('keypress', function (event) { loginPasswordInput.addEventListener('keypress', function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -90,7 +81,6 @@ document.addEventListener('DOMContentLoaded', () => {
} else { } else {
authForm.style.display = 'none'; authForm.style.display = 'none';
registerForm.style.display = 'block'; registerForm.style.display = 'block';
// Auto-focus and key handling for REGISTER-FORM
passwordInput.focus(); passwordInput.focus();
passwordInput.addEventListener('keypress', function (event) { passwordInput.addEventListener('keypress', function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -192,7 +182,6 @@ document.addEventListener('DOMContentLoaded', () => {
return data.authenticated; return data.authenticated;
} }
// functions to handle the second player
async function handleCheckNickname2() { async function handleCheckNickname2() {
const nickname2 = nicknameInput2.value.trim(); const nickname2 = nicknameInput2.value.trim();
@ -202,7 +191,6 @@ document.addEventListener('DOMContentLoaded', () => {
if (exists) { if (exists) {
authForm2.style.display = 'none'; authForm2.style.display = 'none';
loginForm2.style.display = 'block'; loginForm2.style.display = 'block';
// Auto-focus and key handling for LOGIN-FORM2
loginPasswordInput2.focus(); loginPasswordInput2.focus();
loginPasswordInput2.addEventListener('keypress', function (event) { loginPasswordInput2.addEventListener('keypress', function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -213,7 +201,6 @@ document.addEventListener('DOMContentLoaded', () => {
} else { } else {
authForm2.style.display = 'none'; authForm2.style.display = 'none';
registerForm2.style.display = 'block'; registerForm2.style.display = 'block';
// Auto-focus and key handling for REGISTER-FORM2
passwordInput2.focus(); passwordInput2.focus();
passwordInput2.addEventListener('keypress', function (event) { passwordInput2.addEventListener('keypress', function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -332,7 +319,6 @@ document.addEventListener('DOMContentLoaded', () => {
gameContainer.style.display = 'flex'; gameContainer.style.display = 'flex';
logo.style.display = 'none'; logo.style.display = 'none';
pongElements.style.display = 'none'; pongElements.style.display = 'none';
//menuButton.style.display = 'none';
formBlock.style.display = 'none'; formBlock.style.display = 'none';
startWebSocketConnection(token, 2); startWebSocketConnection(token, 2);
} }
@ -341,7 +327,6 @@ document.addEventListener('DOMContentLoaded', () => {
gameContainer.style.display = 'flex'; gameContainer.style.display = 'flex';
logo.style.display = 'none'; logo.style.display = 'none';
pongElements.style.display = 'none'; pongElements.style.display = 'none';
//menuButton.style.display = 'none';
formBlock.style.display = 'none'; formBlock.style.display = 'none';
startWebSocketConnection(token, 1); startWebSocketConnection(token, 1);
} }
@ -350,7 +335,6 @@ document.addEventListener('DOMContentLoaded', () => {
tournamentContainer.style.display = 'flex'; tournamentContainer.style.display = 'flex';
logo.style.display = 'none'; logo.style.display = 'none';
pongElements.style.display = 'none'; pongElements.style.display = 'none';
//menuButton.style.display = 'none';
formBlock.style.display = 'none'; formBlock.style.display = 'none';
startWebSocketConnection(token, 42); startWebSocketConnection(token, 42);
} }
@ -407,14 +391,12 @@ document.addEventListener('DOMContentLoaded', () => {
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);
sendKeyPress(event.key.toLowerCase()); sendKeyPress(event.key.toLowerCase());
} }
} }
function sendKeyPress(key) { function sendKeyPress(key) {
if (socket.readyState === WebSocket.OPEN) { if (socket.readyState === WebSocket.OPEN) {
//console.log('Key sent: ', key);
socket.send(JSON.stringify({ type: 'key_press', key })); socket.send(JSON.stringify({ type: 'key_press', key }));
} }
} }
@ -440,270 +422,6 @@ document.addEventListener('DOMContentLoaded', () => {
document.getElementById('game-text').textContent = gameState.game_text; document.getElementById('game-text').textContent = gameState.game_text;
} }
////////////////////////////// BEG BURGER BUTTON ////////////////////////////////
menuButton.addEventListener('click', toggleMenu);
function toggleMenu() {
console.log('Menu toggled');
if (dropdownMenu.style.display === "block") {
dropdownMenu.style.display = "none";
hideAllTables();
} else {
dropdownMenu.style.display = "block";
}
}
function hideAllTables(){
if (playerList) playerList.style.display = 'none';
if (matchList) matchList.style.display = 'none';
if (tournoiList) tournoiList.style.display = 'none';
if (blockchainList) blockchainList.style.display = 'none';
}
const links = document.querySelectorAll('#dropdown-menu a');
links.forEach(link => {
link.addEventListener('click', (event) => {
event.preventDefault(); // Empêche le comportement par défaut du lien
const tableId = link.getAttribute('data-table');
//console.log("Here !!!!!!!!!!!! NNNNNNNN");
showTable(tableId);
});
});
function showTable(tableId) {
// Masquer tous les tableaux
console.log('Entering showTable', tableId);
hideAllTables();
// Afficher le tableau sélectionné
if (tableId === 'player-list') {
console.log('Showing player list 2');
//if (playerList) {
playerList.style.display = 'block';
fetchPlayers();
//}
} else if (tableId === 'match-list') {
console.log('Showing match list 2');
//if (matchList)
matchList.style.display = 'block';
fetchMatches();
} else if (tableId === 'tournoi-list') {
console.log('Showing tournoi list 2');
//if (tournoiList)
tournoiList.style.display = 'block';
fetchTournois();
} else if (tableId === 'blockchain-list') {
console.log('Opening external page in a new tab');
window.open('https://sepolia.etherscan.io/address/0x078d04eb6fb97cd863361fc86000647dc876441b', '_blank');
/* fetch('/web3/')
.then(response => response.json())
.then(data => {
console.log('ok here !!');
jsonContent.textContent = JSON.stringify(data, null, 2);
}); */
}
// Masquer le menu après la sélection
if (dropdownMenu) {
dropdownMenu.style.display = 'none';
}
}
function fetchMatches() {
console.log('Fetching matches...');
fetch('/api/match_list/')
.then(response => response.json())
.then(data => {
if (data.matches) {
displayMatches(data.matches);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function fetchPlayers(){
console.log('Fetching players...');
fetch('/api/player_list/')
.then(response => response.json())
.then(data => {
if (data.players) {
displayPlayers(data.players);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function fetchTournois(){
console.log('Fetching tournois...');
fetch('/api/tournoi_list/')
.then(response => response.json())
.then(data => {
if (data.tournois) {
displayTournois(data.tournois);
}
})
.catch(error => console.error('Error fetching match data:', error));
}
function displayMatches(matches) {
console.log('Displaying matches:');
const matchListBody = document.querySelector('#match-list tbody');
matchListBody.innerHTML = '';
if (matches.length != 0) {
matches.forEach(match => {
const row = document.createElement('tr');
row.innerHTML = `
<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>
`;
matchListBody.appendChild(row);
});
} else {
row.innerHTML = `
<td colspan="12">No matches found.</td>
`;
matchListBody.appendChild(row);
}
}
function displayPlayers(players) {
console.log('Displaying players:');
const playersListBody = document.querySelector('#player-list tbody');
playersListBody.innerHTML = '';
if (players.length != 0) {
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);
}
}
function displayTournois(tournois) {
console.log('Displaying tournois:');
const tournoisListBody = document.querySelector('#tournoi-list tbody');
tournoisListBody.innerHTML = '';
if (tournois.length != 0) {
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);
});
} else {
row.innerHTML = `
<td colspan="12">No matches found.</td>
`
tournoisListBody.appendChild(row);
}
}
////////////////////////////// END BURGER BUTTON ////////////////////////////////
////////////////////////////// BEG STAT SPE ////////////////////////////////
document.getElementById('search-player').addEventListener('input', filterPlayers);
document.getElementById('search-match-player').addEventListener('input', filterMatches);
document.getElementById('search-match-date').addEventListener('input', filterMatches);
function filterPlayers() {
const searchValue = document.getElementById('search-player').value.toLowerCase();
const playersListBody = document.querySelector('#player-list tbody');
const rows = playersListBody.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const nameCell = rows[i].getElementsByTagName('td')[1]; // The 'Name' column
if (nameCell) {
const nameValue = nameCell.textContent || nameCell.innerText;
if (nameValue.toLowerCase().indexof(searchValue) > -1 ) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
}
function filterMatches() {
const playerSearchValue = document.getElementById('search-match-player').value.toLowerCase();
const dateSearchValue = document.getElementById('search-match-date').value;
const matchListBody = document.querySelector('#match-list tbody');
const rows = matchListBody.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const player1Cell = rows[i].getElementsByTagName('td')[1]; // The 'Player 1' column
const player2Cell = rows[i].getElementsByTagName('td')[2]; // The 'Player 2' column
const dateCell = rows[i].getElementsByTagName('td')[9]; // The 'Date' column
let playerMatch = true;
if (playerSearchValue) {
const player1Value = player1Cell.textContent || player1Cell.innerText;
const player2Value = player2Cell.textContent || player2Cell.innerText;
playerMatch = player1Value.toLowerCase().indexOf(playerSearchValue) > -1 ||
player2Value.toLowerCase().indexOf(playerSearchValue) > -1;
}
let dateMatch = true;
if (dateSearchValue) {
const dateValue = dateCell.textContent || dateCell.innerText;
dateMatch = dateValue.startsWith(dateSearchValue);
}
if (playerMatch && dateMatch) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
////////////////////////////// END STAT SPE ////////////////////////////////
////////////////////////////// BEG STARS ////////////////////////////////
const starsContainer = document.getElementById('stars'); const starsContainer = document.getElementById('stars');
for (let i = 0; i < 500; i++) { for (let i = 0; i < 500; i++) {
const star = document.createElement('div'); const star = document.createElement('div');
@ -716,129 +434,4 @@ document.addEventListener('DOMContentLoaded', () => {
starsContainer.appendChild(star); starsContainer.appendChild(star);
} }
////////////////////////////// END STARS ////////////////////////////////
////////////////////////////// BEG LANGAGE ////////////////////////////////
const translations = {
fr: {
welcome: "BIENVENUE DANS LE PONG 42",
labelNickname: "Entrez votre surnom:",
labelPassword: "Entrez votre mot de passe:",
labelConfirmPassword: "Confirmez votre mot de passe:",
labelLoginPassword: "Entrez votre mot de passe:"
},
en: {
welcome: "WELCOME TO PONG 42",
labelNickname: "Enter your nickname:",
labelPassword: "Enter your password:",
labelConfirmPassword: "Confirm your password:",
labelLoginPassword: "Enter your password:"
},
it: {
welcome: "BENVENUTO A PONG 42",
labelNickname: "Inserisci il tuo soprannome:",
labelPassword: "Inserisci la tua password:",
labelConfirmPassword: "Conferma la tua password:",
labelLoginPassword: "Inserisci la tua password:"
},
es: {
welcome: "BIENVENIDO A PONG 42",
labelNickname: "Introduce tu apodo:",
labelPassword: "Introduce tu contraseña:",
labelConfirmPassword: "Confirma tu contraseña:",
labelLoginPassword: "Introduce tu contraseña:"
},
de: {
welcome: "WILLKOMMEN BEI PONG 42",
labelNickname: "Geben Sie Ihren Spitznamen ein:",
labelPassword: "Geben Sie Ihr Passwort ein:",
labelConfirmPassword: "Bestätigen Sie Ihr Passwort:",
labelLoginPassword: "Geben Sie Ihr Passwort ein:"
}
};
function setCookie(name, value, days) {
const d = new Date();
d.setTime(d.getTime() + (days*24*60*60*1000));
const expires = "expires=" + d.toUTCString();
document.cookie = name + "=" + value + ";" + expires + ";path=/";
}
function getCookie(name) {
const cname = name + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const ca = decodedCookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(cname) === 0) {
return c.substring(cname.length, c.length);
}
}
return "";
}
function changeLanguage(lang) {
setCookie('preferredLanguage', lang, 365); // Store the language preference for 1 year
document.getElementById('welcome').innerText = translations[lang].welcome;
document.getElementById('label-nickname').innerText = translations[lang].labelNickname;
document.getElementById('label-password').innerText = translations[lang].labelPassword;
document.getElementById('label-confirm-password').innerText = translations[lang].labelConfirmPassword;
document.getElementById('label-login-password').innerText = translations[lang].labelLoginPassword;
}
// Function to set the language based on the cookie
function setLanguageFromCookie() {
const preferredLanguage = getCookie('preferredLanguage');
if (preferredLanguage && translations[preferredLanguage]) {
changeLanguage(preferredLanguage);
} else {
changeLanguage('fr'); // Default to French if no cookie is found
}
}
document.getElementById('lang-fr').addEventListener('click', () => changeLanguage('fr'));
document.getElementById('lang-en').addEventListener('click', () => changeLanguage('en'));
document.getElementById('lang-it').addEventListener('click', () => changeLanguage('it'));
document.getElementById('lang-es').addEventListener('click', () => changeLanguage('es'));
document.getElementById('lang-de').addEventListener('click', () => changeLanguage('de'));
// Set the language when the page loads
window.onload = setLanguageFromCookie;
////////////////////////////// END LANGAGE ////////////////////////////////
////////////////////////////// BEG SETTING ////////////////////////////////
document.getElementById('settings-btn').addEventListener('click', function() {
document.getElementById('settings-menu').style.display = 'block';
});
document.getElementById('close-settings').addEventListener('click', function() {
document.getElementById('settings-menu').style.display = 'none';
});
// Change the color of the text
document.getElementById('color-picker').addEventListener('input', function() {
document.body.style.color = this.value;
document.querySelectorAll('button').forEach(function(button) {
button.style.backgroundColor = this.value; // Change la couleur de fond des boutons
}, this);
});
document.getElementById('font-selector').addEventListener('change', function() {
document.body.style.fontFamily = this.value;
});
document.getElementById('font-size-slider').addEventListener('input', function() {
document.body.style.fontSize = this.value + 'px';
});
////////////////////////////// END SETTING ////////////////////////////////
}); });

View File

@ -9,16 +9,7 @@
<link rel="stylesheet" type="text/css" href="{% static 'styles.css' %}?v=3"> <link rel="stylesheet" type="text/css" href="{% static 'styles.css' %}?v=3">
<div class="logo"> <div class="logo">
<img src="{% static 'logo-42-perpignan.png' %}" alt="Logo"> <img src="{% static 'logo-42-perpignan.png' %}" alt="Logo">
</div> </div>
<style>
body {
color: rgb(0, 255, 255); /* Valeur par défaut */
font-family: Arial, sans-serif;
font-size: 16px;
}
</style>
</head> </head>
<body> <body>
<div class="language-switcher"> <div class="language-switcher">
@ -196,6 +187,8 @@
</div> </div>
<script src="{% static 'game.js' %}"></script> <script src="{% static 'game.js' %}"></script>
<script src="{% static 'burger.js' %}"></script>
<script src="{% static 'language.js' %}"></script>
</body> </body>
</html> </html>

113
pong/static/language.js Normal file
View File

@ -0,0 +1,113 @@
document.addEventListener('DOMContentLoaded', () => {
const translations = {
fr: {
welcome: "BIENVENUE DANS LE PONG 42",
labelNickname: "Entrez votre surnom:",
labelPassword: "Entrez votre mot de passe:",
labelConfirmPassword: "Confirmez votre mot de passe:",
labelLoginPassword: "Entrez votre mot de passe:"
},
en: {
welcome: "WELCOME TO PONG 42",
labelNickname: "Enter your nickname:",
labelPassword: "Enter your password:",
labelConfirmPassword: "Confirm your password:",
labelLoginPassword: "Enter your password:"
},
it: {
welcome: "BENVENUTO A PONG 42",
labelNickname: "Inserisci il tuo soprannome:",
labelPassword: "Inserisci la tua password:",
labelConfirmPassword: "Conferma la tua password:",
labelLoginPassword: "Inserisci la tua password:"
},
es: {
welcome: "BIENVENIDO A PONG 42",
labelNickname: "Introduce tu apodo:",
labelPassword: "Introduce tu contraseña:",
labelConfirmPassword: "Confirma tu contraseña:",
labelLoginPassword: "Introduce tu contraseña:"
},
de: {
welcome: "WILLKOMMEN BEI PONG 42",
labelNickname: "Geben Sie Ihren Spitznamen ein:",
labelPassword: "Geben Sie Ihr Passwort ein:",
labelConfirmPassword: "Bestätigen Sie Ihr Passwort:",
labelLoginPassword: "Geben Sie Ihr Passwort ein:"
}
};
function setCookie(name, value, days) {
const d = new Date();
d.setTime(d.getTime() + (days*24*60*60*1000));
const expires = "expires=" + d.toUTCString();
document.cookie = name + "=" + value + ";" + expires + ";path=/";
}
function getCookie(name) {
const cname = name + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const ca = decodedCookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(cname) === 0) {
return c.substring(cname.length, c.length);
}
}
return "";
}
function changeLanguage(lang) {
setCookie('preferredLanguage', lang, 365);
document.getElementById('welcome').innerText = translations[lang].welcome;
document.getElementById('label-nickname').innerText = translations[lang].labelNickname;
document.getElementById('label-password').innerText = translations[lang].labelPassword;
document.getElementById('label-confirm-password').innerText = translations[lang].labelConfirmPassword;
document.getElementById('label-login-password').innerText = translations[lang].labelLoginPassword;
}
function setLanguageFromCookie() {
const preferredLanguage = getCookie('preferredLanguage');
if (preferredLanguage && translations[preferredLanguage]) {
changeLanguage(preferredLanguage);
} else {
changeLanguage('fr'); // Default to French if no cookie is found
}
}
document.getElementById('lang-fr').addEventListener('click', () => changeLanguage('fr'));
document.getElementById('lang-en').addEventListener('click', () => changeLanguage('en'));
document.getElementById('lang-it').addEventListener('click', () => changeLanguage('it'));
document.getElementById('lang-es').addEventListener('click', () => changeLanguage('es'));
document.getElementById('lang-de').addEventListener('click', () => changeLanguage('de'));
window.onload = setLanguageFromCookie;
document.getElementById('settings-btn').addEventListener('click', function() {
document.getElementById('settings-menu').style.display = 'block';
});
document.getElementById('close-settings').addEventListener('click', function() {
document.getElementById('settings-menu').style.display = 'none';
});
document.getElementById('color-picker').addEventListener('input', function() {
document.body.style.color = this.value;
document.querySelectorAll('button').forEach(function(button) {
button.style.backgroundColor = this.value;
}, this);
});
document.getElementById('font-selector').addEventListener('change', function() {
document.body.style.fontFamily = this.value;
});
document.getElementById('font-size-slider').addEventListener('input', function() {
document.body.style.fontSize = this.value + 'px';
});
});

View File

@ -1,5 +1,4 @@
/* General styles */ /* General styles */
body,
html { html {
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
@ -434,4 +433,10 @@ pre {
.tournament-waiting-room ul { .tournament-waiting-room ul {
list-style-type: none; list-style-type: none;
padding: 0; padding: 0;
}
body {
color: rgb(0, 255, 255); /* Valeur par défaut */
font-family: Arial, sans-serif;
font-size: 16px;
} }