From fbcd9f8e5a45d753bf117743dc7d2e638040386f Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Mon, 29 Jul 2024 15:23:26 +0200 Subject: [PATCH 01/81] add .env var --- .env | 9 +++++++++ pong/static/index.html | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.env b/.env index 224e164..df357f6 100644 --- a/.env +++ b/.env @@ -13,3 +13,12 @@ DB_PORT=5432 PROJECT_PATH=${PWD}/pong POSTGRES_DATA_PATH=${PWD}/data/db + +ELASTIC_PASSWORD=qwerty42 +STACK_VERSION=8.14.3 +ES_PORT=127.0.0.1:9200 +CLUSTER_NAME=docker-cluster +LICENSE=basic + +KIBANA_PASSWORD=qwerty42 +KIBANA_PORT=5601 diff --git a/pong/static/index.html b/pong/static/index.html index 1aad5b6..0ffc170 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -37,6 +37,6 @@
- + From 86102dab20ff1614bd9826d942e3018c25f91e09 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Tue, 30 Jul 2024 18:52:34 +0200 Subject: [PATCH 02/81] elk in progress --- .env | 18 +++++-- docker-compose.yaml | 121 ++++++++++++++++++++++++++++++-------------- logstash.conf | 23 +++++++++ makefile | 4 +- 4 files changed, 123 insertions(+), 43 deletions(-) create mode 100644 logstash.conf diff --git a/.env b/.env index df357f6..8abdf3a 100644 --- a/.env +++ b/.env @@ -11,14 +11,24 @@ POSTGRES_PASSWORD=qwerty DB_HOST=db DB_PORT=5432 -PROJECT_PATH=${PWD}/pong -POSTGRES_DATA_PATH=${PWD}/data/db +#PROJECT_PATH=${PWD}/pong +#POSTGRES_DATA_PATH=${PWD}/data/db +#ES_DATA_PATH=${PWD}/data/es +#KIBA_DATA_PATH=${PWD}/data/kiba +#LSTASH_DATA_PATH=${PWD}/data/lstash -ELASTIC_PASSWORD=qwerty42 +# ElasticSearch settings STACK_VERSION=8.14.3 -ES_PORT=127.0.0.1:9200 CLUSTER_NAME=docker-cluster LICENSE=basic +ELASTIC_PASSWORD=qwerty42 +ES_PORT=127.0.0.1:9200 + +# Kibana settings KIBANA_PASSWORD=qwerty42 KIBANA_PORT=5601 + +ES_MEM_LIMIT=1073741824 +KB_MEM_LIMIT=1073741824 +LS_MEM_LIMIT=1073741824 diff --git a/docker-compose.yaml b/docker-compose.yaml index 351dbe4..e317179 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,25 +1,7 @@ services: - db: - image: postgres:latest - container_name: postgres - restart: always - volumes: - - postgres_data:/var/lib/postgresql/data - ports: - - "5432:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 - networks: - - app-network - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - backend: + depends_on: + - db build: context: . dockerfile: Dockerfile @@ -27,16 +9,14 @@ services: container_name: backend restart: always command: /bin/sh -c "sleep 5 && - venv/bin/python manage.py makemigrations --noinput && - venv/bin/python manage.py migrate --noinput && - venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" + venv/bin/python manage.py makemigrations --noinput && + venv/bin/python manage.py migrate --noinput && + venv/bin/python manage.py collectstatic --noinput && + venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" volumes: - pong:/transcendence/pong ports: - "80:80" - depends_on: - - db networks: - app-network environment: @@ -45,25 +25,92 @@ services: DB_NAME: ${POSTGRES_DB} DB_USER: ${POSTGRES_USER} DB_PASSWORD: ${POSTGRES_PASSWORD} + #healthcheck: + #test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"] + #interval: 20s + #timeout: 5s + #retries: 5 + + db: + image: postgres:latest + container_name: postgres + restart: always + volumes: + - pong_pg_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - app-network + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"] + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 + es01: + image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + volumes: + - pong_logstash_data_01:/usr/share/elasticsearch/data + ports: + - ${ES_PORT}:9200 + environment: + - node.name=es01 + - cluster.name=${CLUSTER_NAME} + - discovery.type=single-node + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + mem_limit: ${ES_MEM_LIMIT} + ulimits: + memlock: + soft: -1 + hard: -1 + + logstash01: + depends_on: + - es01 + - kibana + image: docker.elastic.co/logstash/logstash:${STACK_VERSION} + container_name: logstash + volumes: + - pong_logstash_data_01:/usr/share/logstash/data/logstash.conf + ports: + - "5044:5044" + + kibana: + image: docker.elastic.co/kibana/kibana:${STACK_VERSION} + container_name: kibana + volumes: + - pong_kibana:/usr/share/kibana/data + - pong_logstash_data_01:/usr/share/logstash/data + user: root + ports: + - 5601:5601 + environment: + - SERVERNAME=kibana + - ELASTICSEARCH_HOSTS=https://es01:9200 + - ELASTICSEARCH_USERNAME=kibana_system + - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} + mem_limit: ${KB_MEM_LIMIT} + #healthcheck: + #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] + #interval: 20s + #timeout: 10s + #retries: 120 + volumes: - postgres_data: - driver: local - driver_opts: - type: none - device: ${POSTGRES_DATA_PATH} - o: bind pong: driver: local - driver_opts: - type: none - device: ${PROJECT_PATH} - o: bind + pong_pg_data: + driver: local + pong_es_data_01: + driver: local + pong_kibana: + driver: local + pong_logstash_data_01: + driver: local networks: app-network: diff --git a/logstash.conf b/logstash.conf new file mode 100644 index 0000000..88ba485 --- /dev/null +++ b/logstash.conf @@ -0,0 +1,23 @@ +input { + stdin { } +} + +filter { + # Adjust the grok pattern according to the PostgreSQL log format + # Example log format: "2024-07-30 10:20:30 UTC LOG: statement: SELECT * FROM table" + grok { + match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA:log_message}" } + } + + # Optionally, parse and format the extracted timestamp field + date { + match => [ "timestamp", "ISO8601" ] + target => "@timestamp" + # Optional: specify timezone if needed + # timezone => "UTC" + } +} + +output { + stdout { codec => rubydebug } +} diff --git a/makefile b/makefile index 30c4fcb..f62a24f 100644 --- a/makefile +++ b/makefile @@ -22,8 +22,8 @@ down: destroy: $(COMPOSE) down -v --rmi all sudo rm -rf $$PWD/data/db - #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 :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 logs: $(COMPOSE) logs -f $(CONTAINER) From 5f22737bf27427fe759d3aac34061ad463781067 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Wed, 31 Jul 2024 13:46:39 +0200 Subject: [PATCH 03/81] env_template update --- env_template | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/env_template b/env_template index ffa026a..991d475 100644 --- a/env_template +++ b/env_template @@ -1,10 +1,10 @@ # Django settings -SECRET_KEY= +SECRET_KEY="FollowTheWhiteRabbit" DEBUG=True DJANGO_ALLOWED_HOSTS=['*'] # PostgreSQL settings -POSTGRES_DB= +POSTGRES_DB= POSTGRES_USER= POSTGRES_PASSWORD= @@ -13,3 +13,23 @@ DB_PORT=5432 PROJECT_PATH=${PWD}/pong POSTGRES_DATA_PATH=${PWD}/data/db +ES_DATA_PATH=${PWD}/data/es +KIBA_DATA_PATH=${PWD}/data/kiba +LSTASH_DATA_PATH=${PWD}/data/lstash + +# ElasticSearch settings +STACK_VERSION=8.14.3 +CLUSTER_NAME=docker-cluster +LICENSE=basic + +ELASTIC_PASSWORD= +ES_PORT=9200 + +# Kibana settings +KIBANA_PASSWORD= +KIBANA_PORT=5601 + +ES_MEM_LIMIT=1073741824 +KB_MEM_LIMIT=1073741824 +LS_MEM_LIMIT=1073741824 + From b3b2bdf18cc1aade24d4ad98998c7d293375e77e Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Mon, 5 Aug 2024 13:49:25 +0200 Subject: [PATCH 04/81] update --- .env | 6 +----- docker-compose.yaml | 50 ++++++++++++++++++++------------------------- logstash.conf | 44 +++++++++++++++++++++++++-------------- makefile | 6 ++---- 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/.env b/.env index cab57c9..afb0168 100644 --- a/.env +++ b/.env @@ -12,18 +12,14 @@ DB_HOST=db DB_PORT=5432 PROJECT_PATH=${PWD}/pong -POSTGRES_DATA_PATH=${PWD}/data/db -ES_DATA_PATH=${PWD}/data/es -KIBA_DATA_PATH=${PWD}/data/kiba -LSTASH_DATA_PATH=${PWD}/data/lstash # ElasticSearch settings STACK_VERSION=8.14.3 CLUSTER_NAME=docker-cluster LICENSE=basic +ELASTIC_USERNAME=adrien ELASTIC_PASSWORD=qwerty42 -ES_PORT=9200 # Kibana settings KIBANA_PASSWORD=qwerty42 diff --git a/docker-compose.yaml b/docker-compose.yaml index ddc7844..d35c128 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -40,13 +40,19 @@ services: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + container_name: es01 volumes: - pong_logstash_data_01:/usr/share/elasticsearch/data ports: - - ${ES_PORT}:9200 + - "127.0.0.1:9200:9200" networks: - app-network environment: @@ -54,6 +60,8 @@ services: - cluster.name=${CLUSTER_NAME} - discovery.type=single-node - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.security.enabled=false + - xpack.license.self_generated.type=trial mem_limit: ${ES_MEM_LIMIT} ulimits: memlock: @@ -65,34 +73,36 @@ services: - es01 - kibana image: docker.elastic.co/logstash/logstash:${STACK_VERSION} - container_name: logstash + container_name: logstash01 volumes: - - pong_logstash_data_01:/usr/share/logstash/data/logstash.conf + - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf ports: - "5044:5044" networks: - app-network environment: - - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 - - ELASTICSEARCH_USERNAME=kibana_system - - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} + - ELASTIC_HOSTS=http://es01:9200 + - ELASTIC_USER=${ELASTIC_USERNAME} + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.monitoring.enabled=false kibana: image: docker.elastic.co/kibana/kibana:${STACK_VERSION} + depends_on: + - es01 container_name: kibana volumes: - pong_kibana:/usr/share/kibana/data - - pong_logstash_data_01:/usr/share/logstash/data - user: root + user: "1000:1000" ports: - 5601:5601 networks: - app-network environment: - - SERVERNAME=kibana - - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 - - ELASTICSEARCH_USERNAME=kibana_system - - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} + - SERVERNAME=pong.kibana.org + - ELASTICSEARCH_HOSTS=http://es01:9200 + - ELASTICSEARCH_USERNAME=${ELASTIC_USERNAME} + - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} mem_limit: ${KB_MEM_LIMIT} #healthcheck: #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] @@ -109,28 +119,12 @@ volumes: o: bind pong_pg_data: driver: local - driver_opts: - type: none - device: ${POSTGRES_DATA_PATH} - o: bind pong_es_data_01: driver: local - driver_opts: - type: none - device: ${ES_DATA_PATH} - o: bind pong_kibana: driver: local - driver_opts: - type: none - device: ${KIBA_DATA_PATH} - o: bind pong_logstash_data_01: driver: local - driver_opts: - type: none - device: ${LSTASH_DATA_PATH} - o: bind networks: app-network: diff --git a/logstash.conf b/logstash.conf index beca20b..6ee59a8 100644 --- a/logstash.conf +++ b/logstash.conf @@ -1,26 +1,40 @@ input { - stdin { } -} - -filter { - grok { - match => { - "message" => '%{IP:client_ip} - - \[%{HTTPDATE:timestamp}\] "%{WORD:http_method} %{URIPATH:request_path}" %{NUMBER:http_status_code} %{NUMBER:response_size}' - } - # Optional: add a tag to the event for easier identification - add_tag => ["parsed_log"] + # Input from Docker container's stdout + beats { + port => 5044 + } } - # Optionally, convert the timestamp to the Logstash @timestamp +filter { + # Grok filter to parse the log lines + grok { + match => { + "message" => [ + "%{DATA:container_name}\s*\|\s*%{IP:client_ip}:%{NUMBER:client_port} - - \[%{HTTPDATE:timestamp}\] \"%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}\" %{NUMBER:status} %{NUMBER:bytes}" + ] + } + } + + # Date filter to convert timestamp to a proper date format date { - match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] + match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"] target => "@timestamp" + remove_field => ["timestamp"] } } output { - elasticsearch { - hosts => ["http://es01:9200"] - index => "logstash-%{+YYYY.MM.dd}" + # Output to stdout for testing purposes + stdout { + codec => rubydebug } + + # Optionally, output to Elasticsearch +elasticsearch { + hosts => ["localhost:9200"] + index => "docker-logs-%{+YYYY.MM.dd}" + user=> "${ELASTIC_USER}" + password=> "${ELASTIC_PASSWORD}" + } + } diff --git a/makefile b/makefile index 9b3edb8..754f563 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,6 @@ COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) up: - sudo mkdir -p $$PWD/data/db $(COMPOSE) build $(COMPOSE) up $(CONTAINER) @@ -21,9 +20,8 @@ down: destroy: $(COMPOSE) down -v --rmi all - #sudo rm -rf $$PWD/data/db - #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 :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 logs: $(COMPOSE) logs -f $(CONTAINER) From 0e8d76ea2553593d18a91a102b9dac67831ce1a8 Mon Sep 17 00:00:00 2001 From: Theouche Date: Mon, 5 Aug 2024 17:54:21 +0200 Subject: [PATCH 05/81] better css for burger buton --- pong/game/views.py | 2 +- pong/static/styles.css | 49 ++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/pong/game/views.py b/pong/game/views.py index a6cc709..67fe699 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -87,7 +87,7 @@ def tournoi_list(request): from django.http import JsonResponse def match_list_json(request): - matches = Match.objects.select_related('player1', 'player2', 'winner', 'tournoi').all() + matches = Match.objects.all() data = { 'matches': list(matches.values( 'id', 'player1__name', 'player2__name', 'score_player1', 'score_player2', diff --git a/pong/static/styles.css b/pong/static/styles.css index 8931418..2674013 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -253,39 +253,60 @@ button:hover { max-width: 80%; } +/* Styles pour la barre de navigation */ .navbar { - position: absolute; - top: 0; - right: 0; + position: absolute; /* Positionne la barre de navigation relativement à son conteneur */ + top: 10px; /* Ajuste la position du menu déroulant par rapport au haut */ + right: 10px; /* Ajuste la position du menu déroulant par rapport à la droite */ padding: 10px; } +/* Styles pour le bouton du menu burger */ .burger-menu { font-size: 24px; background: none; border: none; - color: white; + color: #00ffff; /* Couleur du texte du bouton */ cursor: pointer; + transition: color 0.3s ease; } +.burger-menu:hover { + color: #ffffff; /* Couleur du texte au survol */ +} + +/* Styles pour le menu déroulant */ .dropdown-content { display: none; position: absolute; - right: 0; - background-color: #f9f9f9; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + top: 100%; /* Positionne le menu directement sous le bouton */ + right: 0; /* Aligne le menu avec le bouton */ + margin-top: 10px; /* Espace entre le bouton et le menu */ + background-color: #1a1a2e; /* Couleur de fond du menu */ + color: #ffffff; /* Couleur du texte du menu */ + box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.3); + border-radius: 5px; z-index: 1; + width: max-content; /* Ajuste la largeur du menu en fonction du contenu */ } -.dropdown-content a { - color: black; - padding: 12px 16px; - text-decoration: none; +/* Affiche le menu déroulant lorsqu'il est actif */ +.dropdown-content.show { display: block; } -.dropdown-content a:hover { - background-color: #f1f1f1; +/* Styles pour les liens du menu déroulant */ +.dropdown-content a { + color: #ffffff; /* Couleur du texte des liens */ + padding: 12px 16px; + text-decoration: none; + display: block; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); /* Ligne de séparation entre les éléments */ + transition: background-color 0.3s ease; /* Transition pour le fond au survol */ } -.show {display: block;} \ No newline at end of file +/* Styles pour les liens au survol */ +.dropdown-content a:hover { + background-color: #333; /* Couleur de fond au survol */ + color: #00ffff; /* Couleur du texte au survol */ +} From f2b558abe57fc6c19a5ab8973e4c4d1eb63bb03c Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Wed, 7 Aug 2024 14:12:59 +0200 Subject: [PATCH 06/81] filebeat in progress --- .env | 4 -- .gitignore | 1 + docker-compose.yaml | 53 ++++++++++------ docker-compose.yml | 144 ++++++++++++++++++++++++++++++++++++++++++++ filebeat.yml | 32 ++++++++++ logstash.conf | 39 +++--------- makefile | 3 +- 7 files changed, 219 insertions(+), 57 deletions(-) create mode 100644 docker-compose.yml create mode 100644 filebeat.yml diff --git a/.env b/.env index afb0168..d87bad8 100644 --- a/.env +++ b/.env @@ -24,7 +24,3 @@ ELASTIC_PASSWORD=qwerty42 # Kibana settings KIBANA_PASSWORD=qwerty42 KIBANA_PORT=5601 - -ES_MEM_LIMIT=1073741824 -KB_MEM_LIMIT=1073741824 -LS_MEM_LIMIT=1073741824 diff --git a/.gitignore b/.gitignore index 3adaaf8..b798a44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ venv/ __pycache__/ data/ +.env diff --git a/docker-compose.yaml b/docker-compose.yaml index d35c128..6eb4002 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,5 @@ services: backend: - depends_on: - - db build: context: . dockerfile: Dockerfile @@ -25,6 +23,8 @@ services: DB_NAME: ${POSTGRES_DB} DB_USER: ${POSTGRES_USER} DB_PASSWORD: ${POSTGRES_PASSWORD} + depends_on: + - db db: image: postgres:latest @@ -40,11 +40,11 @@ services: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 + #healthcheck: + #test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + #interval: 10s + #timeout: 5s + #retries: 5 es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} @@ -62,20 +62,14 @@ services: - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - xpack.security.enabled=false - xpack.license.self_generated.type=trial - mem_limit: ${ES_MEM_LIMIT} - ulimits: - memlock: - soft: -1 - hard: -1 + depends_on: + - logstash01 logstash01: - depends_on: - - es01 - - kibana image: docker.elastic.co/logstash/logstash:${STACK_VERSION} container_name: logstash01 volumes: - - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf + - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro ports: - "5044:5044" networks: @@ -88,8 +82,6 @@ services: kibana: image: docker.elastic.co/kibana/kibana:${STACK_VERSION} - depends_on: - - es01 container_name: kibana volumes: - pong_kibana:/usr/share/kibana/data @@ -103,13 +95,32 @@ services: - ELASTICSEARCH_HOSTS=http://es01:9200 - ELASTICSEARCH_USERNAME=${ELASTIC_USERNAME} - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} - mem_limit: ${KB_MEM_LIMIT} - #healthcheck: + depends_on: + - es01 + #healthcheck: #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] #interval: 20s #timeout: 10s #retries: 120 + filebeat01: + depends_on: + - es01 + image: docker.elastic.co/beats/filebeat:${STACK_VERSION} + volumes: + - pong_filebeat_data_01:/usr/share/filebeat/data + - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro + - /var/lib/docker/containers:/var/lib/docker/containers:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + - ELASTIC_USER=elastic + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - ELASTIC_HOSTS=https://es01:9200 + - KIBANA_HOSTS=http://kibana:5601 + - LOGSTASH_HOSTS=http://logstash01:9600 + networks: + - app-network + volumes: pong: driver: local @@ -125,6 +136,8 @@ volumes: driver: local pong_logstash_data_01: driver: local + pong_filebeat_data_01: + driver: local networks: app-network: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5f5beee --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,144 @@ +services: + backend: + build: + context: . + dockerfile: Dockerfile + image: backend + container_name: backend + restart: always + command: /bin/sh -c "sleep 5 && + venv/bin/python manage.py makemigrations --noinput && + venv/bin/python manage.py migrate --noinput && + venv/bin/python manage.py collectstatic --noinput && + venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" + volumes: + - pong:/transcendence/pong + ports: + - "8080:8080" + networks: + - app-network + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: ${POSTGRES_DB} + DB_USER: ${POSTGRES_USER} + DB_PASSWORD: ${POSTGRES_PASSWORD} + depends_on: + - db + + db: + image: postgres:latest + container_name: postgres + restart: always + volumes: + - pong_pg_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - app-network + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + #healthcheck: + #test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + #interval: 10s + #timeout: 5s + #retries: 5 + + es01: + image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + container_name: es01 + volumes: + - pong_logstash_data_01:/usr/share/elasticsearch/data + ports: + - "127.0.0.1:9200:9200" + networks: + - app-network + environment: + - node.name=es01 + - cluster.name=${CLUSTER_NAME} + - discovery.type=single-node + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.security.enabled=false + - xpack.license.self_generated.type=trial + depends_on: + - logstash01 + + logstash01: + image: docker.elastic.co/logstash/logstash:${STACK_VERSION} + container_name: logstash01 + volumes: + - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + ports: + - "5044:5044" + networks: + - app-network + environment: + - ELASTIC_HOSTS=http://es01:9200 + - ELASTIC_USER=${ELASTIC_USERNAME} + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.monitoring.enabled=false + + kibana: + image: docker.elastic.co/kibana/kibana:${STACK_VERSION} + container_name: kibana + volumes: + - pong_kibana:/usr/share/kibana/data + user: "1000:1000" + ports: + - 5601:5601 + networks: + - app-network + environment: + - SERVERNAME=pong.kibana.org + - ELASTICSEARCH_HOSTS=http://es01:9200 + - ELASTICSEARCH_USERNAME=${ELASTIC_USERNAME} + - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} + depends_on: + - es01 + #healthcheck: + #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] + #interval: 20s + #timeout: 10s + #retries: 120 + + filebeat01: + depends_on: + - es01 + image: docker.elastic.co/beats/filebeat:${STACK_VERSION} + volumes: + - pong_filebeat_data_01:/usr/share/filebeat/data + - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro + - /var/lib/docker/containers:/var/lib/docker/containers:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + - ELASTIC_USER=elastic + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - ELASTIC_HOSTS=https://es01:9200 + - KIBANA_HOSTS=http://kibana:5601 + - LOGSTASH_HOSTS=http://logstash01:9600 + networks: + - app-network + +volumes: + pong: + driver: local + driver_opts: + type: none + device: ${PROJECT_PATH} + o: bind + pong_pg_data: + driver: local + pong_es_data_01: + driver: local + pong_kibana: + driver: local + pong_logstash_data_01: + driver: local + pong_filebeat_data_01: + driver: local + +networks: + app-network: + driver: bridge diff --git a/filebeat.yml b/filebeat.yml new file mode 100644 index 0000000..f5be95b --- /dev/null +++ b/filebeat.yml @@ -0,0 +1,32 @@ +filebeat.inputs: +#- type: docker + #containers.ids: + # - "*" +- type: filestream + id: default-filestream + paths: + - ingest_data/*.log + +filebeat.autodiscover: + providers: + - type: docker + hints.enabled: true + +processors: +- add_docker_metadata: ~ + + +setup.kibana: + host: ${KIBANA_HOSTS} + username: ${ELASTIC_USER} + password: ${ELASTIC_PASSWORD} + + +output.elasticsearch: + hosts: ${ELASTIC_HOSTS} + username: ${ELASTIC_USER} + password: ${ELASTIC_PASSWORD} + ssl.enabled: false + +#output.logstash: + #hosts: ["http://logstash01:9600"] diff --git a/logstash.conf b/logstash.conf index 6ee59a8..9236eb1 100644 --- a/logstash.conf +++ b/logstash.conf @@ -1,40 +1,17 @@ input { - # Input from Docker container's stdout - beats { + beat { port => 5044 } - } +} filter { - # Grok filter to parse the log lines - grok { - match => { - "message" => [ - "%{DATA:container_name}\s*\|\s*%{IP:client_ip}:%{NUMBER:client_port} - - \[%{HTTPDATE:timestamp}\] \"%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}\" %{NUMBER:status} %{NUMBER:bytes}" - ] - } - } - - # Date filter to convert timestamp to a proper date format - date { - match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"] - target => "@timestamp" - remove_field => ["timestamp"] - } } output { - # Output to stdout for testing purposes - stdout { - codec => rubydebug - } - - # Optionally, output to Elasticsearch -elasticsearch { - hosts => ["localhost:9200"] - index => "docker-logs-%{+YYYY.MM.dd}" - user=> "${ELASTIC_USER}" - password=> "${ELASTIC_PASSWORD}" - } - + elasticsearch { + hosts => ["http://es01:9200"] + index => "docker-logs-%{+YYYY.MM.dd}" + user=> "${ELASTIC_USER}" + password=> "${ELASTIC_PASSWORD}" + } } diff --git a/makefile b/makefile index 754f563..169500b 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -COMPOSE_FILE=docker-compose.yaml +COMPOSE_FILE=docker-compose.yml COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) @@ -44,4 +44,3 @@ help: @echo " make logs [c=service] # Tail logs of containers" @echo " make ps # List containers" @echo " make help # Show this help" - From 67dbd4b583de7b07ec490eb50cbd3533c2c2e77e Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 7 Aug 2024 15:15:20 +0200 Subject: [PATCH 07/81] pb bot --- .env | 4 +- pong/game/game.py | 98 ++++++++++++++++------------------------------- 2 files changed, 35 insertions(+), 67 deletions(-) diff --git a/.env b/.env index 41d604b..4ecdb09 100644 --- a/.env +++ b/.env @@ -11,5 +11,5 @@ POSTGRES_PASSWORD=qwerty DB_HOST=db DB_PORT=5432 -PROJECT_PATH=/home/mchiboub/42cursus/transcendence/pong -POSTGRES_DATA_PATH=/home/mchiboub/42cursus/transcendence/data/db \ No newline at end of file +PROJECT_PATH=${PWD}/pong +POSTGRES_DATA_PATH=${PWD}/data/db \ No newline at end of file diff --git a/pong/game/game.py b/pong/game/game.py index 5ceecb8..1b3c23b 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -5,50 +5,6 @@ import asyncio import random from .utils import endfortheouche -class BotPlayer: - def __init__(self, game_state, speed): - self.game_state = game_state - self.speed = speed - - async def update_bot_position(self): - print("Update bot position started") - try: - target_y = self.predict_ball_position() - #print(f"Target Y: {target_y}") - player2_position = self.game_state['player2_position'] - #print(f"Player2 Position: {player2_position}") - - if player2_position < target_y < player2_position + 80: - print("Bot is already aligned with the ball, no move needed.") - elif player2_position < target_y: - new_position = min(player2_position + (5 * self.speed), 300) - print(f"Moving bot down to {new_position}") - self.game_state['player2_position'] = new_position - elif player2_position + 80 > target_y: - new_position = max(player2_position - (5 * self.speed), 0) - print(f"Moving bot up to {new_position}") - self.game_state['player2_position'] = new_position - - #await asyncio.sleep(1) # Rafraîchir toutes les secondes - except Exception as e: - print(f"Error in BotPlayer.update_bot_position: {e}") - - - def predict_ball_position(self): - # Prédire la future position de la balle en tenant compte de sa vitesse - ball_y = self.game_state['ball_position']['y'] - ball_speed_y = self.game_state['ball_velocity']['y'] - # Prédiction simple, peut être améliorée pour plus de précision - future_ball_y = ball_y + ball_speed_y * 1 # prédire pour la prochaine seconde - - # Gérer les rebonds sur les limites - if future_ball_y < 0: - future_ball_y = -future_ball_y - elif future_ball_y > 300: - future_ball_y = 600 - future_ball_y - - return future_ball_y - class Game: def __init__(self, game_id, player1, player2): @@ -73,6 +29,8 @@ class Game: self.p2_mov = 0 self.bt1 = 0 self.bt2 = 0 + self.last_update_time = 0 + self.update_interval = 1 if self.botgame: self.bot_player = BotPlayer(self.game_state, self.speed) @@ -82,13 +40,14 @@ class Game: self.game_loop_task = asyncio.create_task(self.game_loop()) async def game_loop(self): - #print("Here, ok") while True: if self.botgame: - #print('still ok') - #await self.bot_player.update_bot_position() - await self.update_bot_position() - #print('is it ok ?? ') + current_time = asyncio.get_event_loop().time() + if current_time - self.last_update_time >= self.update_interval: + await self.update_bot_position() + self.last_update_time = current_time + #await self.update_bot_position() + await self.handle_pad_movement() self.update_game_state() await self.send_game_state() @@ -103,6 +62,31 @@ class Game: elif self.game_state['player2_position'] + 80 > target_y: self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0) + """ async def update_bot_position(self): + target_y = self.predict_ball_position() + current_pos = self.game_state['player2_position'] + + if abs(current_pos - target_y) < 5: # Add some randomness to mimic human error + return + + if current_pos < target_y: + self.game_state['player2_position'] = min(current_pos + (5 * self.speed), 300) + else: + self.game_state['player2_position'] = max(current_pos - (5 * self.speed), 0) + + def predict_ball_position(self): + ball_pos = self.game_state['ball_position'] + ball_velocity = self.game_state['ball_velocity'] + + # Simple prediction of ball position in future, considering only current velocity + predicted_y = ball_pos['y'] + ball_velocity['y'] + + # Handle ball rebounding off the top or bottom of the game area + if predicted_y < 0 or predicted_y > 300: # Assuming game height is 300 + predicted_y = 300 - abs(predicted_y % 300) + + return predicted_y """ + def update_game_state(self): # Update ball position self.game_state['ball_position']['x'] += self.game_state['ball_velocity']['x'] @@ -224,19 +208,3 @@ class Game: await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], self.bt1, self.bt2, 42, False, None) - -### pour Theo ### -# nickname player1 -# nickname player2 -# score p1 -# score p2 -# winner -# ball touch p1 -# ball touch p2 -# match time -# match type: 'quick match' - -# match type: 'tournament' -# -> tournament id - -#endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_p2, dur, is_tournoi, name_tournament) From 4b82bbbfd185ab7fad2aedb8eb510e1a8a7e127c Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Wed, 7 Aug 2024 15:30:11 +0200 Subject: [PATCH 08/81] in progress --- .env | 4 ++- docker-compose.yaml | 24 +++---------- docker-compose.yaml-simle | 61 ++++++++++++++++++++++++++++++++ docker-compose.yml | 74 +++++++++++++++++++++++++++++++++++++-- filebeat.yml | 32 +++-------------- logstash.conf | 8 +++-- makefile | 4 +-- 7 files changed, 152 insertions(+), 55 deletions(-) create mode 100644 docker-compose.yaml-simle diff --git a/.env b/.env index d87bad8..78f2dda 100644 --- a/.env +++ b/.env @@ -16,7 +16,7 @@ PROJECT_PATH=${PWD}/pong # ElasticSearch settings STACK_VERSION=8.14.3 CLUSTER_NAME=docker-cluster -LICENSE=basic +LICENSE=trial ELASTIC_USERNAME=adrien ELASTIC_PASSWORD=qwerty42 @@ -24,3 +24,5 @@ ELASTIC_PASSWORD=qwerty42 # Kibana settings KIBANA_PASSWORD=qwerty42 KIBANA_PORT=5601 + +ENCRYPTION_KEY=c34d38b3a14956121ff2170e5030b471551370178f43e5626eec58b04a30fae2 diff --git a/docker-compose.yaml b/docker-compose.yaml index 6eb4002..8b2b3dd 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,11 +10,11 @@ services: venv/bin/python manage.py makemigrations --noinput && venv/bin/python manage.py migrate --noinput && venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" + venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" volumes: - pong:/transcendence/pong ports: - - "80:80" + - "8080:8080" networks: - app-network environment: @@ -70,6 +70,8 @@ services: container_name: logstash01 volumes: - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + - /var/lib/docker/containers:/var/lib/docker/containers:ro + - /var/run/docker.sock:/var/run/docker.sock:ro ports: - "5044:5044" networks: @@ -103,24 +105,6 @@ services: #timeout: 10s #retries: 120 - filebeat01: - depends_on: - - es01 - image: docker.elastic.co/beats/filebeat:${STACK_VERSION} - volumes: - - pong_filebeat_data_01:/usr/share/filebeat/data - - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - - /var/lib/docker/containers:/var/lib/docker/containers:ro - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - - ELASTIC_USER=elastic - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - ELASTIC_HOSTS=https://es01:9200 - - KIBANA_HOSTS=http://kibana:5601 - - LOGSTASH_HOSTS=http://logstash01:9600 - networks: - - app-network - volumes: pong: driver: local diff --git a/docker-compose.yaml-simle b/docker-compose.yaml-simle new file mode 100644 index 0000000..d11b2d0 --- /dev/null +++ b/docker-compose.yaml-simle @@ -0,0 +1,61 @@ +services: + backend: + build: + context: . + dockerfile: Dockerfile + image: backend + container_name: backend + restart: always + command: /bin/sh -c "sleep 5 && + venv/bin/python manage.py makemigrations --noinput && + venv/bin/python manage.py migrate --noinput && + venv/bin/python manage.py collectstatic --noinput && + venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" + volumes: + - pong:/transcendence/pong + ports: + - "8080:8080" + networks: + - app-network + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: ${POSTGRES_DB} + DB_USER: ${POSTGRES_USER} + DB_PASSWORD: ${POSTGRES_PASSWORD} + depends_on: + - db + + db: + image: postgres:latest + container_name: postgres + restart: always + volumes: + - pong_pg_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - app-network + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + pong: + driver: local + driver_opts: + type: none + device: ${PROJECT_PATH} + o: bind + pong_pg_data: + driver: local + +networks: + app-network: + driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index 5f5beee..944e595 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,59 @@ services: + setup: + image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + volumes: + - certs:/usr/share/elasticsearch/config/certs + user: "0" + command: > + bash -c ' + if [ x${ELASTIC_PASSWORD} == x ]; then + echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; + exit 1; + elif [ x${KIBANA_PASSWORD} == x ]; then + echo "Set the KIBANA_PASSWORD environment variable in the .env file"; + exit 1; + fi; + if [ ! -f config/certs/ca.zip ]; then + echo "Creating CA"; + bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; + unzip config/certs/ca.zip -d config/certs; + fi; + if [ ! -f config/certs/certs.zip ]; then + echo "Creating certs"; + echo -ne \ + "instances:\n"\ + " - name: es01\n"\ + " dns:\n"\ + " - es01\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ + " - name: kibana\n"\ + " dns:\n"\ + " - kibana\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ + > config/certs/instances.yml; + bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; + unzip config/certs/certs.zip -d config/certs; + fi; + echo "Setting file permissions" + chown -R root:root config/certs; + find . -type d -exec chmod 750 \{\} \;; + find . -type f -exec chmod 640 \{\} \;; + echo "Waiting for Elasticsearch availability"; + until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done; + echo "Setting kibana_system password"; + until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; + echo "All done!"; + ' + healthcheck: + test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"] + interval: 1s + timeout: 5s + retries: 120 + backend: build: context: . @@ -10,7 +65,7 @@ services: venv/bin/python manage.py makemigrations --noinput && venv/bin/python manage.py migrate --noinput && venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" + venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" volumes: - pong:/transcendence/pong ports: @@ -50,6 +105,7 @@ services: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 volumes: + - certs:/usr/share/elasticsearch/config/certs - pong_logstash_data_01:/usr/share/elasticsearch/data ports: - "127.0.0.1:9200:9200" @@ -60,8 +116,18 @@ services: - cluster.name=${CLUSTER_NAME} - discovery.type=single-node - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - xpack.security.enabled=false - - xpack.license.self_generated.type=trial + - bootstrap.memory_lock=true + - xpack.security.enabled=true + - xpack.security.http.ssl.enabled=true + - xpack.security.http.ssl.key=certs/es01/es01.key + - xpack.security.http.ssl.certificate=certs/es01/es01.crt + - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt + - xpack.security.transport.ssl.enabled=true + - xpack.security.transport.ssl.key=certs/es01/es01.key + - xpack.security.transport.ssl.certificate=certs/es01/es01.crt + - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt + - xpack.security.transport.ssl.verification_mode=certificate + - xpack.license.self_generated.type=${LICENSE} depends_on: - logstash01 @@ -122,6 +188,8 @@ services: - app-network volumes: + certs: + driver: local pong: driver: local driver_opts: diff --git a/filebeat.yml b/filebeat.yml index f5be95b..3082ccb 100644 --- a/filebeat.yml +++ b/filebeat.yml @@ -1,32 +1,10 @@ filebeat.inputs: -#- type: docker - #containers.ids: - # - "*" -- type: filestream - id: default-filestream - paths: - - ingest_data/*.log - -filebeat.autodiscover: - providers: - - type: docker - hints.enabled: true +- type: docker + containers.ids: + - "*" processors: - add_docker_metadata: ~ - -setup.kibana: - host: ${KIBANA_HOSTS} - username: ${ELASTIC_USER} - password: ${ELASTIC_PASSWORD} - - -output.elasticsearch: - hosts: ${ELASTIC_HOSTS} - username: ${ELASTIC_USER} - password: ${ELASTIC_PASSWORD} - ssl.enabled: false - -#output.logstash: - #hosts: ["http://logstash01:9600"] +output.logstash: + hosts: ["http://logstash01:5044"] diff --git a/logstash.conf b/logstash.conf index 9236eb1..4872c61 100644 --- a/logstash.conf +++ b/logstash.conf @@ -1,6 +1,10 @@ input { - beat { - port => 5044 + file { + path => "/var/lib/docker/containers/*/*.log" + start_position => "beginning" + sincedb_path => "/usr/share/logstash/data/sincedb" + type => "docker" + codec => "json" } } diff --git a/makefile b/makefile index 169500b..126ed39 100644 --- a/makefile +++ b/makefile @@ -1,10 +1,10 @@ -COMPOSE_FILE=docker-compose.yml +COMPOSE_FILE=docker-compose.yaml COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) up: $(COMPOSE) build - $(COMPOSE) up $(CONTAINER) + $(COMPOSE) up build: $(COMPOSE) build $(CONTAINER) From 9daf75b35e71e75157496a651666a454ab60e339 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 7 Aug 2024 17:26:16 +0200 Subject: [PATCH 09/81] pbl solved --- makefile | 2 ++ pong/game/game.py | 36 ++---------------------------------- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/makefile b/makefile index f84c03f..ecb19b5 100644 --- a/makefile +++ b/makefile @@ -34,6 +34,8 @@ ps: db-shell: $(COMPOSE) exec db psql -U 42student players_db +re : destroy down up + help: @echo "Usage:" @echo " make build [c=service] # Build images" diff --git a/pong/game/game.py b/pong/game/game.py index 1b3c23b..c69d601 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -29,11 +29,7 @@ class Game: self.p2_mov = 0 self.bt1 = 0 self.bt2 = 0 - self.last_update_time = 0 - self.update_interval = 1 - - if self.botgame: - self.bot_player = BotPlayer(self.game_state, self.speed) + async def start_game(self): print(f"- Game #{self.game_id} STARTED") @@ -42,11 +38,7 @@ class Game: async def game_loop(self): while True: if self.botgame: - current_time = asyncio.get_event_loop().time() - if current_time - self.last_update_time >= self.update_interval: - await self.update_bot_position() - self.last_update_time = current_time - #await self.update_bot_position() + await self.update_bot_position() await self.handle_pad_movement() self.update_game_state() @@ -62,30 +54,6 @@ class Game: elif self.game_state['player2_position'] + 80 > target_y: self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0) - """ async def update_bot_position(self): - target_y = self.predict_ball_position() - current_pos = self.game_state['player2_position'] - - if abs(current_pos - target_y) < 5: # Add some randomness to mimic human error - return - - if current_pos < target_y: - self.game_state['player2_position'] = min(current_pos + (5 * self.speed), 300) - else: - self.game_state['player2_position'] = max(current_pos - (5 * self.speed), 0) - - def predict_ball_position(self): - ball_pos = self.game_state['ball_position'] - ball_velocity = self.game_state['ball_velocity'] - - # Simple prediction of ball position in future, considering only current velocity - predicted_y = ball_pos['y'] + ball_velocity['y'] - - # Handle ball rebounding off the top or bottom of the game area - if predicted_y < 0 or predicted_y > 300: # Assuming game height is 300 - predicted_y = 300 - abs(predicted_y % 300) - - return predicted_y """ def update_game_state(self): # Update ball position From 473a62dde46b102301f2e75de04d2dce2c470d67 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 7 Aug 2024 18:03:34 +0200 Subject: [PATCH 10/81] Beg new ia --- pong/game/game.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pong/game/game.py b/pong/game/game.py index c69d601..db995b4 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -176,3 +176,7 @@ class Game: await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], self.bt1, self.bt2, 42, False, None) + + + +######################################################## Test amelioration IA ######################################################## From b4dfc443a7fa2fb3bd8905eaacc01b5f65084bf6 Mon Sep 17 00:00:00 2001 From: jcheca Date: Thu, 8 Aug 2024 15:54:58 +0200 Subject: [PATCH 11/81] update --- pong/static/flags/de.svg | 7 + pong/static/flags/es.svg | 712 +++++++++++++++++++++++++++++++++++++++ pong/static/flags/fr.svg | 7 + pong/static/flags/it.svg | 7 + pong/static/flags/us.svg | 57 ++++ pong/static/index.html | 215 +++++++++++- 6 files changed, 997 insertions(+), 8 deletions(-) create mode 100755 pong/static/flags/de.svg create mode 100755 pong/static/flags/es.svg create mode 100755 pong/static/flags/fr.svg create mode 100755 pong/static/flags/it.svg create mode 100755 pong/static/flags/us.svg diff --git a/pong/static/flags/de.svg b/pong/static/flags/de.svg new file mode 100755 index 0000000..61e64d0 --- /dev/null +++ b/pong/static/flags/de.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/pong/static/flags/es.svg b/pong/static/flags/es.svg new file mode 100755 index 0000000..ce2e1a8 --- /dev/null +++ b/pong/static/flags/es.svg @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pong/static/flags/fr.svg b/pong/static/flags/fr.svg new file mode 100755 index 0000000..240e789 --- /dev/null +++ b/pong/static/flags/fr.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/pong/static/flags/it.svg b/pong/static/flags/it.svg new file mode 100755 index 0000000..038afd9 --- /dev/null +++ b/pong/static/flags/it.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/pong/static/flags/us.svg b/pong/static/flags/us.svg new file mode 100755 index 0000000..8a8fb5c --- /dev/null +++ b/pong/static/flags/us.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pong/static/index.html b/pong/static/index.html index 9bfdf51..68b11bb 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -1,6 +1,6 @@ {% load static %} - + @@ -10,10 +10,73 @@ + + + + +
+ Français + English + Italiano + Español + Deutsch +
@@ -22,24 +85,43 @@
+ + +
-

BIENVENUE DANS LE PONG 42

+

BIENVENUE DANS LE PONG 42

- +
@@ -60,6 +142,52 @@
+ + - + \ No newline at end of file From 08361c4715ca9e5637d4342d43e50d3d5a2bdd34 Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 8 Aug 2024 16:27:40 +0200 Subject: [PATCH 12/81] Merge avec jcheca --- pong/game/game.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pong/game/game.py b/pong/game/game.py index db995b4..735daae 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -30,13 +30,14 @@ class Game: self.bt1 = 0 self.bt2 = 0 + async def start_game(self): print(f"- Game #{self.game_id} STARTED") self.game_loop_task = asyncio.create_task(self.game_loop()) async def game_loop(self): - while True: + while not self.ended: if self.botgame: await self.update_bot_position() @@ -56,6 +57,8 @@ class Game: def update_game_state(self): + if self.ended: + return # Update ball position self.game_state['ball_position']['x'] += self.game_state['ball_velocity']['x'] self.game_state['ball_position']['y'] += self.game_state['ball_velocity']['y'] @@ -140,6 +143,8 @@ class Game: async def handle_pad_movement(self): #print(f"P1 mov: {self.p1_mov}") #print(f"P2 mov: {self.p2_mov}") + if self.ended: + return if self.p1_mov == -1: self.game_state['player1_position'] = max(self.game_state['player1_position'] - (5 * self.speed), 0) elif self.p1_mov == 1: From ff50d6d054ffcd0a38263881ce3bef5cb76065b0 Mon Sep 17 00:00:00 2001 From: jcheca Date: Thu, 8 Aug 2024 16:28:16 +0200 Subject: [PATCH 13/81] add web3 --- pong/game/urls.py | 1 + pong/game/views.py | 70 +++++++++++++++++++++++++++++++++++++++ pong/static/index.html | 75 ++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +- 4 files changed, 148 insertions(+), 1 deletion(-) diff --git a/pong/game/urls.py b/pong/game/urls.py index 570f027..4375a95 100644 --- a/pong/game/urls.py +++ b/pong/game/urls.py @@ -9,6 +9,7 @@ urlpatterns = [ path('check_user_exists/', views.check_user_exists, name='check_user_exists'), path('register_user/', views.register_user, name='register_user'), path('authenticate_user/', views.authenticate_user, name='authenticate_user'), + path('web3/', views.read_data, name='read_data'), path('players/', player_list, name='player_list'), path('matches/', match_list, name='match_list'), path('tournois/', tournoi_list, name='tournoi_list'), diff --git a/pong/game/views.py b/pong/game/views.py index 298fa5b..66c8955 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -202,3 +202,73 @@ def tournoi_list(request): return render(request, 'pong/tournoi_list.html', {'tournois': tournois}) ####################### THEOUCHE PART ############################ + + + +####################### jcheca PART ############################ + +from web3 import Web3 + +provider = Web3.HTTPProvider("https://sepolia.infura.io/v3/60e51df7c97c4f4c8ab41605a4eb9907") +web3 = Web3(provider) +eth_gas_price = web3.eth.gas_price/1000000000 +print(eth_gas_price) + +contract_address = "0x078D04Eb6fb97Cd863361FC86000647DC876441B" +contract_abi = [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"uint256","name":"_timecode","type":"uint256"},{"internalType":"uint256","name":"_participantCount","type":"uint256"},{"internalType":"string[]","name":"_playerPseudonyms","type":"string[]"},{"internalType":"string[]","name":"_finalOrder","type":"string[]"}],"name":"addTournament","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllTournaments","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"timecode","type":"uint256"},{"internalType":"uint256","name":"participantCount","type":"uint256"},{"internalType":"string[]","name":"playerPseudonyms","type":"string[]"},{"internalType":"string[]","name":"finalOrder","type":"string[]"}],"internalType":"struct PongTournament.Tournament[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getTournament","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"timecode","type":"uint256"},{"internalType":"uint256","name":"participantCount","type":"uint256"},{"internalType":"string[]","name":"playerPseudonyms","type":"string[]"},{"internalType":"string[]","name":"finalOrder","type":"string[]"}],"internalType":"struct PongTournament.Tournament","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tournamentCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tournaments","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"timecode","type":"uint256"},{"internalType":"uint256","name":"participantCount","type":"uint256"}],"stateMutability":"view","type":"function"}] + +contract = web3.eth.contract(address=contract_address, abi=contract_abi) + +def read_data(request): + # Créer une instance du contrat + + # Appeler une fonction du contrat pour obtenir tous les tournois + tournaments = contract.functions.getAllTournaments().call() + + # Afficher les résultats + json_data = [] + for tournament in tournaments: + tournament_data = [] + for item in tournament: + print(f"{item}") + tournament_data.append(item) + json_data.append(tournament_data) + + # Retourner le JSON comme réponse HTTP + # print(f"Tournament ID: {tournament[0]}") + # print(f"Name: {tournament[1]}") + # print(f"Timecode: {tournament[2]}") + # print(f"Participant Count: {tournament[3]}") + # print(f"Player Pseudonyms: {', '.join(tournament[4])}") + # print(f"Final Order: {', '.join(tournament[5])}") + print("-----------------------------") + return JsonResponse(json_data, safe=False) + + +def write_data(request): + # addTournament(string,uint256,uint256,string[],string[]) + + # # Configuration de la transaction pour la fonction store + # account = "0x66CeBE2A1F7dae0F6AdBAad2c15A56A9121abfEf" + # private_key = "beb16ee3434ec5abec8b799549846cc04443c967b8d3643b943e2e969e7d25be" + + # nonce = web3.eth.get_transaction_count(account) + # transaction = contract.functions.addTournament("test",1721830559,6,["aaudeber", "tlorne", "ocassany", "yestello", "jcheca", "toto"],["toto", "jcheca", "yestello", "tlorne", "ocassany", "aaudeber"]).build_transaction({ + # 'chainId': 11155111, # ID de la chaîne Sepolia + # 'gas': 2000000, + # 'gasPrice': web3.to_wei(eth_gas_price, 'gwei'), + # 'nonce': nonce + # }) + + # # Signature de la transaction + # signed_txn = web3.eth.account.sign_transaction(transaction, private_key) + + # # Envoi de la transaction + # tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction) + # print("Transaction hash:", web3.to_hex(tx_hash)) + + # # Attente de la confirmation de la transaction + # tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash) + # print("Transaction receipt:", tx_receipt) + print("-----------------------------") + diff --git a/pong/static/index.html b/pong/static/index.html index 68b11bb..4135741 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -67,6 +67,50 @@ font-size: 16px; } + @@ -105,6 +149,37 @@
+ + +

BIENVENUE DANS LE PONG 42

diff --git a/requirements.txt b/requirements.txt index 9b9e85a..0792c48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ Django psycopg2 python-dotenv channels -daphne \ No newline at end of file +daphne +web3 \ No newline at end of file From 0a0641db1faad1ba417dfca1ddf55a32931dd94f Mon Sep 17 00:00:00 2001 From: Theouche Date: Sat, 10 Aug 2024 18:56:12 +0200 Subject: [PATCH 14/81] duration ok --- pong/game/game.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pong/game/game.py b/pong/game/game.py index 735daae..26d3edc 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -3,6 +3,7 @@ import json import asyncio import random +from datetime import datetime from .utils import endfortheouche @@ -29,12 +30,16 @@ class Game: self.p2_mov = 0 self.bt1 = 0 self.bt2 = 0 + self.start_time = None async def start_game(self): print(f"- Game #{self.game_id} STARTED") self.game_loop_task = asyncio.create_task(self.game_loop()) + print(" begin MATCH at : ") + self.start_time = datetime.now() + print(f" begin MATCH : {self.start_time} ") async def game_loop(self): while not self.ended: @@ -160,6 +165,10 @@ class Game: if self.game_loop_task: self.game_loop_task.cancel() print(f"- Game #{self.game_id} ENDED") + + end_time = datetime.now() + duration = (end_time - self.start_time).total_seconds() / 60 + # Notify that one player left the game if disconnected_player: remaining_player = self.player2 if disconnected_player == self.player1 else self.player1 @@ -180,8 +189,5 @@ class Game: await self.player2.send(end_message) await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], - self.bt1, self.bt2, 42, False, None) + self.bt1, self.bt2, duration, False, None) - - -######################################################## Test amelioration IA ######################################################## From b1c865acae0f42033d4a293e142e63957bf55e34 Mon Sep 17 00:00:00 2001 From: Theouche Date: Mon, 12 Aug 2024 17:16:13 +0200 Subject: [PATCH 15/81] Ca casse les couilles, tounroi veut pas s'afficher, I need chatgpt plus prenium extra ! --- makefile | 2 +- pong/game/urls.py | 5 ++-- pong/game/views.py | 14 +++++++++ pong/static/game.js | 64 +++++++++++++++++++++++++++++++++--------- pong/static/index.html | 34 +++++++++++++++++++++- 5 files changed, 100 insertions(+), 19 deletions(-) diff --git a/makefile b/makefile index 0a07cd8..976e007 100644 --- a/makefile +++ b/makefile @@ -32,7 +32,7 @@ ps: db-shell: $(COMPOSE) exec db psql -U 42student players_db -re : destroy down up +re: destroy down up help: @echo "Usage:" diff --git a/pong/game/urls.py b/pong/game/urls.py index e27f293..7a2a3ef 100644 --- a/pong/game/urls.py +++ b/pong/game/urls.py @@ -4,9 +4,7 @@ from django.urls import path, include from . import views from .views import player_list, tournoi_list, match_list from rest_framework.routers import DefaultRouter -from .views import match_list_json -from .views import player_list_json - +from .views import match_list_json, player_list_json, tournoi_list_json urlpatterns = [ @@ -20,4 +18,5 @@ urlpatterns = [ path('tournois/', tournoi_list, name='tournoi_list'), path('api/match_list/', match_list_json, name='match_list_json'), path('api/player_list/', player_list_json, name='player_list_json'), + path('api/tournoi_list/', tournoi_list_json, name='tournoi_list_json') ] diff --git a/pong/game/views.py b/pong/game/views.py index be12945..e810b78 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -114,6 +114,20 @@ def player_list_json(request): # Renvoie les données en JSON return JsonResponse(data) +def tournoi_list_json(request): + # Récupère tous les joueurs + tournois = Tournoi.objects.all() + + # Crée un dictionnaire avec les informations des joueurs + data = { + 'tournois': list(tournois.values( + 'id', 'name', 'nbr_player', 'date', 'winner' + )) + } + + # Renvoie les données en JSON + return JsonResponse(data) + ####################### THEOUCHE PART ############################ diff --git a/pong/static/game.js b/pong/static/game.js index 380d21b..4aa78d2 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -18,6 +18,7 @@ document.addEventListener('DOMContentLoaded', () => { const menuButton = document.querySelector('.burger-menu'); const playerList = document.getElementById('player-list'); const matchList = document.getElementById('match-list'); + const tournoiList = document.getElementById('tournoi-list'); const dropdownMenu = document.getElementById('dropdown-menu'); const pongElements = document.getElementById('pong-elements'); @@ -283,26 +284,26 @@ document.addEventListener('DOMContentLoaded', () => { function showTable(tableId) { // Masquer tous les tableaux - if (playerList) { - playerList.style.display = 'none'; - } - if (matchList) { - matchList.style.display = 'none'; - } - + printf('Entering showTable') + console.log('Entering showTable', tableId); + if (playerList) playerList.style.display = 'none'; + if (matchList) matchList.style.display = 'none'; + if (tournoiList) tournoiList.style.display = 'none'; + // Afficher le tableau sélectionné if (tableId === 'player-list') { - if (playerList) { - playerList.style.display = 'block'; - } + print('Showing player list'); + if (playerList) playerList.style.display = 'block'; fetchPlayers(); } else if (tableId === 'match-list') { - if (matchList) { - matchList.style.display = 'block'; - } + print('Showing match list'); + if (matchList) matchList.style.display = 'block'; fetchMatches(); + } else if (tableId === 'tournoi-list') { + print('Showing tournoi list'); + if (tournoiList) tournoiList.style.display = 'block'; + fetchTournois(); } - // Masquer le menu après la sélection if (dropdownMenu) { dropdownMenu.style.display = 'none'; @@ -345,6 +346,19 @@ document.addEventListener('DOMContentLoaded', () => { .catch(error => console.error('Error fetching match data:', error)); } + function fetchTournois(){ + print('Fetching tournois...'); + fetch('/api/tournoi_list/') + .then(response => response.json()) + .then(data => { + print('Tournois data:', data); + if (data.tournois) { + displayTournois(data.tournois); + } + }) + .catch(error => console.error('Error fetching match data:', error)); + } + function displayMatches(matches) { const matchListBody = document.querySelector('#match-list tbody'); matchListBody.innerHTML = ''; @@ -394,4 +408,26 @@ document.addEventListener('DOMContentLoaded', () => { }); } + function displayTournois(tournois) { + print('Displaying tournois:'); + const tournoisListBody = document.querySelector('#tournoi-list tbody'); + tournoisListBody.innerHTML = ''; + + if (tournois.length === 0) { + print('No tournois to display'); + } + + tournois.forEach(tournoi => { + const row = document.createElement('tr'); + row.innerHTML = ` + ${tournoi.id} + ${tournoi.name} + ${tournoi.nbr_player} + ${tournoi.date} + ${tournoi.winner.name} + `; + tournoisListBody.appendChild(row); + }); + } + }); diff --git a/pong/static/index.html b/pong/static/index.html index 84de3dc..27fc9f7 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -208,6 +208,8 @@
@@ -268,7 +270,7 @@
- @@ -347,136 +192,6 @@ - - - From 58a0362b43f132903171c88d9d76adc029249aa9 Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 13 Aug 2024 17:05:22 +0200 Subject: [PATCH 23/81] Button ajoute good --- pong/static/index.html | 291 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) diff --git a/pong/static/index.html b/pong/static/index.html index 9110db1..81d043e 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -10,9 +10,117 @@ + + + + +
+ Français + English + Italiano + Español + Deutsch +
@@ -21,6 +129,59 @@
+ + + + + + + + +

BIENVENUE DANS LE PONG 42

@@ -192,6 +353,136 @@
+ + + From 53d1f969c09d14398c538cad8c74581c00499889 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 14 Aug 2024 16:10:53 +0200 Subject: [PATCH 24/81] bouton post form aligne --- pong/static/game.js | 7 +++---- pong/static/index.html | 2 +- pong/static/styles.css | 45 +++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index 8c53964..0698013 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -114,7 +114,7 @@ document.addEventListener('DOMContentLoaded', () => { //logo.style.display = 'none'; pongElements.style.display = 'none'; console.log("new button must appear !"); - document.getElementById("post-form-buttons").style.display = 'block'; + document.getElementById("post-form-buttons").style.display = 'inline-block'; //startWebSocketConnection(token); } else { alert('Registration failed. Please try again.'); @@ -140,8 +140,7 @@ document.addEventListener('DOMContentLoaded', () => { token = data.token; } return data.registered; - }quickMatchButton.style.display = 'block'; - tournamentButton.style.display = 'block'; + } async function handleLogin() { const nickname = nicknameInput.value.trim(); @@ -155,7 +154,7 @@ document.addEventListener('DOMContentLoaded', () => { //logo.style.display = 'none'; //pongElements.style.display = 'none'; console.log("new button must appear !"); - document.getElementById("post-form-buttons").style.display = 'block'; + document.getElementById("post-form-buttons").style.display = 'inline-block'; //startWebSocketConnection(token); } else { alert('Authentication failed. Please try again.'); diff --git a/pong/static/index.html b/pong/static/index.html index 81d043e..52649e4 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -6,7 +6,7 @@ Pong Game - + diff --git a/pong/static/styles.css b/pong/static/styles.css index 1b7ef45..fdaee3a 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -13,9 +13,9 @@ html { justify-content: center; height: 100%; overflow: hidden; - } + label { margin: 10px 0 5px; } @@ -261,60 +261,59 @@ button:hover { max-width: 80%; } -/* Styles pour la barre de navigation */ + .navbar { - position: absolute; /* Positionne la barre de navigation relativement à son conteneur */ - top: 10px; /* Ajuste la position du menu déroulant par rapport au haut */ - right: 10px; /* Ajuste la position du menu déroulant par rapport à la droite */ + position: absolute; + top: 10px; + right: 10px; padding: 10px; } -/* Styles pour le bouton du menu burger */ .burger-menu { font-size: 24px; background: none; border: none; - color: #00ffff; /* Couleur du texte du bouton */ + color: #00ffff; cursor: pointer; transition: color 0.3s ease; } .burger-menu:hover { - color: #ffffff; /* Couleur du texte au survol */ + color: #ffffff; } -/* Styles pour le menu déroulant */ + .dropdown-content { display: none; position: absolute; - top: 100%; /* Positionne le menu directement sous le bouton */ - right: 0; /* Aligne le menu avec le bouton */ - margin-top: 10px; /* Espace entre le bouton et le menu */ - background-color: #1a1a2e; /* Couleur de fond du menu */ - color: #ffffff; /* Couleur du texte du menu */ + top: 100%; + right: 0; + margin-top: 10px; + background-color: #1a1a2e; + color: #ffffff; box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.3); border-radius: 5px; z-index: 1; - width: max-content; /* Ajuste la largeur du menu en fonction du contenu */ + width: max-content; } -/* Affiche le menu déroulant lorsqu'il est actif */ .dropdown-content.show { display: block; } -/* Styles pour les liens du menu déroulant */ + .dropdown-content a { - color: #ffffff; /* Couleur du texte des liens */ + color: #ffffff; padding: 12px 16px; text-decoration: none; display: block; - border-bottom: 1px solid rgba(255, 255, 255, 0.2); /* Ligne de séparation entre les éléments */ - transition: background-color 0.3s ease; /* Transition pour le fond au survol */ + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + transition: background-color 0.3s ease; } -/* Styles pour les liens au survol */ + .dropdown-content a:hover { - background-color: #333; /* Couleur de fond au survol */ - color: #00ffff; /* Couleur du texte au survol */ + background-color: #333; + color: #00ffff; } + From c871a711355563046434ec6c50442f887ab9152a Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Wed, 14 Aug 2024 16:29:20 +0200 Subject: [PATCH 25/81] wip --- .env | 7 +- filebeat.yml => config/filebeat.yml | 0 config/kibana.yml | 54 +++++++ config/logstash.conf | 30 ++++ docker-compose.yaml | 90 ++++++------ docker-compose.yaml-simle | 61 -------- docker-compose.yml | 211 ++++++++++++++-------------- logstash.conf | 21 --- makefile | 4 +- manage.py | 0 10 files changed, 240 insertions(+), 238 deletions(-) rename filebeat.yml => config/filebeat.yml (100%) create mode 100644 config/kibana.yml create mode 100644 config/logstash.conf delete mode 100644 docker-compose.yaml-simle delete mode 100644 logstash.conf mode change 100755 => 100644 manage.py diff --git a/.env b/.env index 78f2dda..9dd1c1a 100644 --- a/.env +++ b/.env @@ -8,10 +8,11 @@ POSTGRES_DB=players_db POSTGRES_USER=42student POSTGRES_PASSWORD=qwerty +# Django settings DB_HOST=db DB_PORT=5432 - -PROJECT_PATH=${PWD}/pong +PWD_PATH=${PWD} +PROJECT_PATH=${PWD_PATH}/pong # ElasticSearch settings STACK_VERSION=8.14.3 @@ -24,5 +25,3 @@ ELASTIC_PASSWORD=qwerty42 # Kibana settings KIBANA_PASSWORD=qwerty42 KIBANA_PORT=5601 - -ENCRYPTION_KEY=c34d38b3a14956121ff2170e5030b471551370178f43e5626eec58b04a30fae2 diff --git a/filebeat.yml b/config/filebeat.yml similarity index 100% rename from filebeat.yml rename to config/filebeat.yml diff --git a/config/kibana.yml b/config/kibana.yml new file mode 100644 index 0000000..a1ed606 --- /dev/null +++ b/config/kibana.yml @@ -0,0 +1,54 @@ +# Kibana's Elasticsearch URL +elasticsearch.hosts: ["https://es01:9200"] + +# The name of the Kibana instance +server.name: "kibana" + +# The base path for Kibana +#server.basePath: "" + +# Serve the Kibana instance at the root path +#server.rewriteBasePath: false + +# Enable or disable the Kibana server +server.enabled: true + +# The port Kibana will listen on +server.port: 5601 + +# Enable or disable the xpack features +xpack.enabled: true + +# Set the encryption key for encrypted saved objects +#xpack.encryptedSavedObjects.encryptionKey: "" + +# Set the key for the kibana security features +#xpack.security.encryptionKey: "" + +# Enable or disable the monitoring feature +xpack.monitoring.enabled: true + +# Set the URL of the Elasticsearch instance to which Kibana should connect +#xpack.reporting.enabled: true + + #xpack.reporting.roles.enabled: false + +# Enable the Kibana alerting feature +#xpack.alerting.enabled: false + +# Enable or disable the usage collection +#xpack.usageCollection.enabled: true + +# Configure the log level for Kibana +#logging.level: info + +# Configure the directory where logs will be stored +logging.dest: /var/log/kibana/kibana.log + +# Configure security and authentication settings +elasticsearch.username: test +elasticsearch.password: test + +# Disable or enable the Kibana plugin +#xpack.license.management.enabled: false + diff --git a/config/logstash.conf b/config/logstash.conf new file mode 100644 index 0000000..28710ab --- /dev/null +++ b/config/logstash.conf @@ -0,0 +1,30 @@ +input { + file { + path => "/var/lib/docker/containers/*/*.log" + start_position => "beginning" + sincedb_path => "/dev/null" + type => "docker" + codec => "json" + } +} + +filter { + if [log_message] =~ /GET/ { + grok { + match => { "log_message" => "%{IP:client_ip} - - \[%{HTTPDATE:timestamp}\] \"%{WORD:method} %{URIPATH:request_path} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:response_size}" } + } + date { + match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] + target => "@timestamp" + } + } +} + +output { + elasticsearch { + hosts => ["http://es01:9200"] + index => "docker-logs-%{+YYYY.MM.dd}" + user=> "${ELASTIC_USER}" + password=> "${ELASTIC_PASSWORD}" + } +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 8b2b3dd..a046dbe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -25,6 +25,12 @@ services: DB_PASSWORD: ${POSTGRES_PASSWORD} depends_on: - db + healthcheck: + test: ["CMD-SHELL", "curl", "http://localhost:8080"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s db: image: postgres:latest @@ -40,47 +46,33 @@ services: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - #healthcheck: - #test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - #interval: 10s - #timeout: 5s - #retries: 5 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 volumes: - - pong_logstash_data_01:/usr/share/elasticsearch/data + - pong_es_data_01:/usr/share/elasticsearch/data ports: - - "127.0.0.1:9200:9200" + - "9200:9200" networks: - - app-network + - app-network environment: - - node.name=es01 - - cluster.name=${CLUSTER_NAME} - - discovery.type=single-node - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - xpack.security.enabled=false - - xpack.license.self_generated.type=trial - depends_on: - - logstash01 - - logstash01: - image: docker.elastic.co/logstash/logstash:${STACK_VERSION} - container_name: logstash01 - volumes: - - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro - - /var/lib/docker/containers:/var/lib/docker/containers:ro - - /var/run/docker.sock:/var/run/docker.sock:ro - ports: - - "5044:5044" - networks: - - app-network - environment: - - ELASTIC_HOSTS=http://es01:9200 - - ELASTIC_USER=${ELASTIC_USERNAME} - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - xpack.monitoring.enabled=false + - node.name=es01 + - cluster.name=${CLUSTER_NAME} + - discovery.type=single-node + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - bootstrap.memory_lock=true + - xpack.security.enabled=false + healthcheck: + test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"'"] + interval: 10s + timeout: 10s + retries: 5 kibana: image: docker.elastic.co/kibana/kibana:${STACK_VERSION} @@ -99,11 +91,27 @@ services: - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} depends_on: - es01 - #healthcheck: - #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] - #interval: 20s - #timeout: 10s - #retries: 120 + healthcheck: + test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q '200 OK'"] + interval: 10s + timeout: 20s + retries: 200 + + + logstash01: + image: docker.elastic.co/logstash/logstash:${STACK_VERSION} + container_name: logstash01 + volumes: + - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + ports: + - "5044:5044" + networks: + - app-network + environment: + - ELASTIC_HOSTS=http://es01:9200 + - ELASTIC_USER=${ELASTIC_USERNAME} + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.monitoring.enabled=false volumes: pong: @@ -118,10 +126,8 @@ volumes: driver: local pong_kibana: driver: local - pong_logstash_data_01: - driver: local - pong_filebeat_data_01: - driver: local + + networks: app-network: diff --git a/docker-compose.yaml-simle b/docker-compose.yaml-simle deleted file mode 100644 index d11b2d0..0000000 --- a/docker-compose.yaml-simle +++ /dev/null @@ -1,61 +0,0 @@ -services: - backend: - build: - context: . - dockerfile: Dockerfile - image: backend - container_name: backend - restart: always - command: /bin/sh -c "sleep 5 && - venv/bin/python manage.py makemigrations --noinput && - venv/bin/python manage.py migrate --noinput && - venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" - volumes: - - pong:/transcendence/pong - ports: - - "8080:8080" - networks: - - app-network - environment: - DB_HOST: db - DB_PORT: 5432 - DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} - DB_PASSWORD: ${POSTGRES_PASSWORD} - depends_on: - - db - - db: - image: postgres:latest - container_name: postgres - restart: always - volumes: - - pong_pg_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - app-network - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - pong: - driver: local - driver_opts: - type: none - device: ${PROJECT_PATH} - o: bind - pong_pg_data: - driver: local - -networks: - app-network: - driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index 944e595..fc73df1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,58 +1,43 @@ services: setup: - image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} - volumes: - - certs:/usr/share/elasticsearch/config/certs - user: "0" - command: > - bash -c ' - if [ x${ELASTIC_PASSWORD} == x ]; then - echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; - exit 1; - elif [ x${KIBANA_PASSWORD} == x ]; then - echo "Set the KIBANA_PASSWORD environment variable in the .env file"; - exit 1; - fi; - if [ ! -f config/certs/ca.zip ]; then - echo "Creating CA"; - bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; - unzip config/certs/ca.zip -d config/certs; - fi; - if [ ! -f config/certs/certs.zip ]; then - echo "Creating certs"; - echo -ne \ - "instances:\n"\ - " - name: es01\n"\ - " dns:\n"\ - " - es01\n"\ - " - localhost\n"\ - " ip:\n"\ - " - 127.0.0.1\n"\ - " - name: kibana\n"\ - " dns:\n"\ - " - kibana\n"\ - " - localhost\n"\ - " ip:\n"\ - " - 127.0.0.1\n"\ + image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} + container_name: setup + user: "0" + volumes: + - certs:/usr/share/elasticsearch/config/certs + command: > + sh -c ' + if [ ! -f /usr/share/elasticsearch/config/certs/elastic-certificate.p12 ]; then + echo "Creating elastic-certificate.p12..."; + bin/elasticsearch-certutil cert --name elastic-certificate --days 365 --self-signed --out /usr/share/elasticsearch/config/certs/elastic-certificate.p12 --pass ""; + else + echo "elastic-certificate.p12 already exists, skipping certificate creation."; + fi; + + if [ ! -f /usr/share/elasticsearch/config/certs/instances.yml ]; then + echo "Creating certs"; + echo -ne \ + "instances:\n"\ + " - name: es01\n"\ + " dns:\n"\ + " - es01\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ + " - name: kibana\n"\ + " dns:\n"\ + " - kibana\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ > config/certs/instances.yml; - bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; - unzip config/certs/certs.zip -d config/certs; - fi; - echo "Setting file permissions" - chown -R root:root config/certs; - find . -type d -exec chmod 750 \{\} \;; - find . -type f -exec chmod 640 \{\} \;; - echo "Waiting for Elasticsearch availability"; - until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done; - echo "Setting kibana_system password"; - until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; - echo "All done!"; - ' - healthcheck: - test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"] - interval: 1s - timeout: 5s - retries: 120 + fi; + + echo "Setting file permissions"; + find /usr/share/elasticsearch/config/certs -type d -exec chmod 750 \{\} \;; + find /usr/share/elasticsearch/config/certs -type f -exec chmod 640 \{\} \;; + tail -f /dev/null; + ' backend: build: @@ -80,6 +65,12 @@ services: DB_PASSWORD: ${POSTGRES_PASSWORD} depends_on: - db + healthcheck: + test: ["CMD-SHELL", "curl", "http://localhost:8080"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s db: image: postgres:latest @@ -95,20 +86,19 @@ services: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - #healthcheck: - #test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - #interval: 10s - #timeout: 5s - #retries: 5 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 volumes: - - certs:/usr/share/elasticsearch/config/certs - - pong_logstash_data_01:/usr/share/elasticsearch/data + - certs:/usr/share/elasticsearch/config/certs:ro ports: - - "127.0.0.1:9200:9200" + - "9200:9200" networks: - app-network environment: @@ -118,38 +108,25 @@ services: - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - bootstrap.memory_lock=true - xpack.security.enabled=true - - xpack.security.http.ssl.enabled=true - - xpack.security.http.ssl.key=certs/es01/es01.key - - xpack.security.http.ssl.certificate=certs/es01/es01.crt - - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.enabled=true - - xpack.security.transport.ssl.key=certs/es01/es01.key - - xpack.security.transport.ssl.certificate=certs/es01/es01.crt - - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt - - xpack.security.transport.ssl.verification_mode=certificate + - xpack.security.transport.ssl.keystore.path=/usr/share/elasticsearch/config/certs/elastic-certificate.p12 + - xpack.security.transport.ssl.keystore.type=PKCS12 + - xpack.security.transport.ssl.keystore.password="" - xpack.license.self_generated.type=${LICENSE} depends_on: + - setup - logstash01 - - logstash01: - image: docker.elastic.co/logstash/logstash:${STACK_VERSION} - container_name: logstash01 - volumes: - - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro - ports: - - "5044:5044" - networks: - - app-network - environment: - - ELASTIC_HOSTS=http://es01:9200 - - ELASTIC_USER=${ELASTIC_USERNAME} - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - xpack.monitoring.enabled=false + healthcheck: + test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"'"] + interval: 10s + timeout: 10s + retries: 5 kibana: image: docker.elastic.co/kibana/kibana:${STACK_VERSION} container_name: kibana volumes: + - certs:/usr/share/kibana/config/certs:ro - pong_kibana:/usr/share/kibana/data user: "1000:1000" ports: @@ -163,30 +140,27 @@ services: - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} depends_on: - es01 - #healthcheck: - #test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] - #interval: 20s - #timeout: 10s - #retries: 120 - - filebeat01: - depends_on: - - es01 - image: docker.elastic.co/beats/filebeat:${STACK_VERSION} + healthcheck: + test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] + interval: 10s + timeout: 20s + retries: 200 + + logstash01: + image: docker.elastic.co/logstash/logstash:${STACK_VERSION} + container_name: logstash01 volumes: - - pong_filebeat_data_01:/usr/share/filebeat/data - - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - - /var/lib/docker/containers:/var/lib/docker/containers:ro - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - - ELASTIC_USER=elastic - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - ELASTIC_HOSTS=https://es01:9200 - - KIBANA_HOSTS=http://kibana:5601 - - LOGSTASH_HOSTS=http://logstash01:9600 + - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + ports: + - "5044:5044" networks: - app-network - + environment: + - ELASTIC_HOSTS=http://es01:9200 + - ELASTIC_USER=${ELASTIC_USERNAME} + - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + - xpack.monitoring.enabled=false + volumes: certs: driver: local @@ -202,11 +176,32 @@ volumes: driver: local pong_kibana: driver: local - pong_logstash_data_01: - driver: local - pong_filebeat_data_01: - driver: local networks: app-network: + name: app-network driver: bridge + + + + #filebeat01: + #depends_on: + #- es01 + # image: docker.elastic.co/beats/filebeat:${STACK_VERSION} + # volumes: + # - certs:/usr/share/logstash/certs + # - pong_filebeat_data_01:/usr/share/filebeat/data + # - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro + # - /var/lib/docker/containers:/var/lib/docker/containers:ro + # - /var/run/docker.sock:/var/run/docker.sock:ro + # environment: + # - ELASTIC_USER=elastic + # - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} + # - ELASTIC_HOSTS=https://es01:9200 + # - KIBANA_HOSTS=http://kibana:5601 + # - LOGSTASH_HOSTS=http://logstash01:9600 + # - xpack.monitoring.enabled=false + # networks: + # - app-network + + diff --git a/logstash.conf b/logstash.conf deleted file mode 100644 index 4872c61..0000000 --- a/logstash.conf +++ /dev/null @@ -1,21 +0,0 @@ -input { - file { - path => "/var/lib/docker/containers/*/*.log" - start_position => "beginning" - sincedb_path => "/usr/share/logstash/data/sincedb" - type => "docker" - codec => "json" - } -} - -filter { -} - -output { - elasticsearch { - hosts => ["http://es01:9200"] - index => "docker-logs-%{+YYYY.MM.dd}" - user=> "${ELASTIC_USER}" - password=> "${ELASTIC_PASSWORD}" - } -} diff --git a/makefile b/makefile index 126ed39..169500b 100644 --- a/makefile +++ b/makefile @@ -1,10 +1,10 @@ -COMPOSE_FILE=docker-compose.yaml +COMPOSE_FILE=docker-compose.yml COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) up: $(COMPOSE) build - $(COMPOSE) up + $(COMPOSE) up $(CONTAINER) build: $(COMPOSE) build $(CONTAINER) diff --git a/manage.py b/manage.py old mode 100755 new mode 100644 From d96ec4ea87e292af8518930d219380d23427a470 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 14 Aug 2024 18:46:05 +0200 Subject: [PATCH 26/81] end match but really big probleme to register our data in the baskend =( --- pong/game/game.py | 19 ++++++--- pong/game/matchmaking.py | 2 +- pong/game/utils.py | 85 +++++++++++++++++++++++----------------- 3 files changed, 63 insertions(+), 43 deletions(-) diff --git a/pong/game/game.py b/pong/game/game.py index 26d3edc..7ff81f3 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -47,7 +47,7 @@ class Game: await self.update_bot_position() await self.handle_pad_movement() - self.update_game_state() + await self.update_game_state() await self.send_game_state() await asyncio.sleep(1/60) # Around 60 FPS @@ -61,7 +61,7 @@ class Game: self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0) - def update_game_state(self): + async def update_game_state(self): if self.ended: return # Update ball position @@ -84,15 +84,19 @@ class Game: self.bt2 += 1 self.update_ball_velocity() # Check for scoring + 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: self.game_state['player2_score'] += 1 - if self.game_state['player2_score'] >= 5: - self.end_game() + if self.game_state['player2_score'] >= 2: + print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + await self.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 - if self.game_state['player1_score'] >= 5: - self.end_game() + if self.game_state['player1_score'] >= 2: + await self.end_game() self.reset_ball() def reset_ball(self): @@ -160,7 +164,9 @@ class Game: self.game_state['player2_position'] = min(self.game_state['player2_position'] + (5 * self.speed), 300) async def end_game(self, disconnected_player=None): + print("end GAME CALLED") if not self.ended: + print("Game ended !!!!! ") self.ended = True if self.game_loop_task: self.game_loop_task.cancel() @@ -187,6 +193,7 @@ class Game: await self.player1.send(end_message) if not self.botgame: await self.player2.send(end_message) + print("save data") await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], self.bt1, self.bt2, duration, False, None) diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 28b8dda..32f9981 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -40,7 +40,7 @@ class MatchMaker: await asyncio.sleep(1) self.timer += 1 # Waiting for more than 30s -> BOT game - if self.timer >= 30 and self.waiting_players: + if self.timer >= 5 and self.waiting_players: player1 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs BOT") self.botgame = True diff --git a/pong/game/utils.py b/pong/game/utils.py index a1f8e0d..181853f 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -4,32 +4,44 @@ from django.shortcuts import get_object_or_404 from django.db.models import Max, Sum, F from datetime import timedelta from channels.db import database_sync_to_async +#from asgiref.sync import database_sync_to_async + async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): - # Check if player p1 exists, if not create - if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): - player_1 = await create_player(p1) - print("############# PLAYER DONE") - else: - player_1 = await database_sync_to_async(Player.objects.get)(name=p1) + try: + print("here endfortheouche §!!!") - # Check if player p2 exists, if not create - if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): - player_2 = await create_player(p2) - print("############# PLAYER DONE") - else: - player_2 = await database_sync_to_async(Player.objects.get)(name=p2) - - # create Match - print("############# BEFORE MATCH") - await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) - print("############# AFTER DONE") + """ await database_sync_to_async(Player.objects.filter(name=p1).exists)() + print("ok") """ + + if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): + print("############# player 1 not existed .... creating player #############") + player_1 = await create_player(p1) + print("############# PLAYER DONE ############") + else: + print("############# Player 1 find, get data #############") + player_1 = await database_sync_to_async(Player.objects.get)(name=p1) + print("############# Player get #############") - # Update data p1 et p2 - - await uptdate_player_statistics(p1) - print("############# END STAT P1") - await uptdate_player_statistics(p2) + if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): + print("############# player 2 not existed .... creating player #############") + player_2 = await create_player(p2) + print("############# PLAYER DONE") + else: + print("############# Player 2 find, get data #############") + player_2 = await database_sync_to_async(Player.objects.get)(name=p2) + print("############# Player get #############") + + print("############# BEFORE MATCH") + await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) + print("############# AFTER DONE") + + await uptdate_player_statistics(p1) + print("############# END STAT P1") + await uptdate_player_statistics(p2) + + except Exception as e: + print(f"Error in endfortheouche: {e}") @database_sync_to_async def create_player( @@ -46,22 +58,23 @@ def create_player( num_participated_tournaments=0, num_won_tournaments=0 ): - if Player.objects.filter(name=name).exists(): - raise ValueError(f"A player with the name '{name}' already exists.") - + print("create player !!!") + """ if database_sync_to_async(Player.objects.filter(name=name).exists)(): + raise ValueError(f"A player with the name '{name}' already exists.") """ + player = Player( name=name, - total_match = total_match, - total_win = total_win, - p_win = p_win, - m_score_match = m_score_match, - m_score_adv_match = m_score_adv_match, - best_score = best_score, - m_nbr_ball_touch = m_nbr_ball_touch, - total_duration = total_duration, - m_duration = m_duration, - num_participated_tournaments = num_participated_tournaments, - num_won_tournaments = num_won_tournaments + total_match=total_match, + total_win=total_win, + p_win=p_win, + m_score_match=m_score_match, + m_score_adv_match=m_score_adv_match, + best_score=best_score, + m_nbr_ball_touch=m_nbr_ball_touch, + total_duration=total_duration, + m_duration=m_duration, + num_participated_tournaments=num_participated_tournaments, + num_won_tournaments=num_won_tournaments ) player.save() return player From 86779624fcb96aa685956b6439bb45d3ec9c8f78 Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 15 Aug 2024 14:03:37 +0200 Subject: [PATCH 27/81] gros probleme backend --- pong/game/utils.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/pong/game/utils.py b/pong/game/utils.py index 181853f..f075ac5 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -10,36 +10,26 @@ from channels.db import database_sync_to_async async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") - - """ await database_sync_to_async(Player.objects.filter(name=p1).exists)() - print("ok") """ if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): - print("############# player 1 not existed .... creating player #############") player_1 = await create_player(p1) - print("############# PLAYER DONE ############") + print("############# PLAYER DONE") else: - print("############# Player 1 find, get data #############") player_1 = await database_sync_to_async(Player.objects.get)(name=p1) - print("############# Player get #############") if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): - print("############# player 2 not existed .... creating player #############") player_2 = await create_player(p2) print("############# PLAYER DONE") else: - print("############# Player 2 find, get data #############") player_2 = await database_sync_to_async(Player.objects.get)(name=p2) - print("############# Player get #############") print("############# BEFORE MATCH") await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) print("############# AFTER DONE") - await uptdate_player_statistics(p1) + await update_player_statistics(p1) print("############# END STAT P1") - await uptdate_player_statistics(p2) - + await update_player_statistics(p2) except Exception as e: print(f"Error in endfortheouche: {e}") From ac1c10548e41f3f6b98d2b64a529471b51afc2fb Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 15 Aug 2024 14:17:54 +0200 Subject: [PATCH 28/81] same --- pong/game/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pong/game/utils.py b/pong/game/utils.py index f075ac5..7901375 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -17,6 +17,8 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_ else: player_1 = await database_sync_to_async(Player.objects.get)(name=p1) + print("ok") + if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): player_2 = await create_player(p2) print("############# PLAYER DONE") @@ -100,7 +102,7 @@ def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_ return match @database_sync_to_async -def uptdate_player_statistics(player_name): +def update_player_statistics(player_name): print("############# BEG STAT P") player = get_object_or_404(Player, name=player_name) From 0595dccb21b8ebc7ee4bb4e79f6ce36d735fa48c Mon Sep 17 00:00:00 2001 From: Theouche Date: Fri, 16 Aug 2024 09:14:55 +0200 Subject: [PATCH 29/81] begin to clean jcheca part --- pong/game/utils.py | 1 - pong/static/index.html | 95 +----------------------------------------- pong/static/styles.css | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 95 deletions(-) diff --git a/pong/game/utils.py b/pong/game/utils.py index 7901375..b01c212 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -10,7 +10,6 @@ from channels.db import database_sync_to_async async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") - if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): player_1 = await create_player(p1) print("############# PLAYER DONE") diff --git a/pong/static/index.html b/pong/static/index.html index 52649e4..48d0691 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -10,21 +10,7 @@ - + - - diff --git a/pong/static/styles.css b/pong/static/styles.css index fdaee3a..8c3436e 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -317,3 +317,93 @@ button:hover { color: #00ffff; } +.language-switcher { + position: absolute; + top: 10px; + right: 10px; + display: flex; + gap: 10px; +} + +.language-switcher img { + width: 30px; + height: 20px; + cursor: pointer; +} + +#settings-btn { + position: fixed; + bottom: 10px; + right: 10px; + cursor: pointer; + z-index: 1000; + border: none; + border-radius: 50%; + padding: 10px; + font-size: 18px; +} + +#settings-menu { + position: fixed; + bottom: 50px; + right: 10px; + padding: 20px; + background-color: rgb(66, 63, 63); + border: 1px solid #ccc; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + width: 250px; + z-index: 1000; +} + +#close-settings { + position: absolute; + top: 10px; + right: 10px; + background: none; + border: none; + cursor: pointer; + font-size: 16px; +} + +.modal { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(0,0,0); + background-color: rgba(0,0,0,0.4); + padding-top: 60px; +} + +.modal-content { + background-color: #fefefe; + margin: 5% auto; + padding: 20px; + border: 5px solid #888; + width: 80%; + max-height: 70vh; + overflow-y: auto; +} + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +pre { + white-space: pre-wrap; + word-wrap: break-word; +} \ No newline at end of file From b0706f1c366620fb0eb41cf5b37bc8facd61ccfd Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Sat, 17 Aug 2024 20:11:18 +0200 Subject: [PATCH 30/81] first logs from logstash --- .env | 12 ++- config/filebeat.yml | 10 --- config/kibana.yml | 54 ------------- config/logstash.conf | 39 ++++----- docker-compose.yaml | 134 ------------------------------ docker-compose.yml | 189 ++++++++++++++++++++++++------------------- env_template | 23 +++--- makefile | 6 +- 8 files changed, 144 insertions(+), 323 deletions(-) delete mode 100644 config/filebeat.yml delete mode 100644 config/kibana.yml delete mode 100644 docker-compose.yaml diff --git a/.env b/.env index 9dd1c1a..c295954 100644 --- a/.env +++ b/.env @@ -17,11 +17,15 @@ PROJECT_PATH=${PWD_PATH}/pong # ElasticSearch settings STACK_VERSION=8.14.3 CLUSTER_NAME=docker-cluster -LICENSE=trial +LICENSE=basic -ELASTIC_USERNAME=adrien -ELASTIC_PASSWORD=qwerty42 +ELASTIC_USERNAME=elastic +ELASTIC_PASSWORD=elastic_pass # Kibana settings -KIBANA_PASSWORD=qwerty42 KIBANA_PORT=5601 +KIBANA_USERNAME=kibana_system +KIBANA_PASSWORD=kibana_pass + +ENCRYPTION_KEY=c34d38b3a14956121ff2170e5030b471551370178f43e5626eec58b04a30fae2 + diff --git a/config/filebeat.yml b/config/filebeat.yml deleted file mode 100644 index 3082ccb..0000000 --- a/config/filebeat.yml +++ /dev/null @@ -1,10 +0,0 @@ -filebeat.inputs: -- type: docker - containers.ids: - - "*" - -processors: -- add_docker_metadata: ~ - -output.logstash: - hosts: ["http://logstash01:5044"] diff --git a/config/kibana.yml b/config/kibana.yml deleted file mode 100644 index a1ed606..0000000 --- a/config/kibana.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Kibana's Elasticsearch URL -elasticsearch.hosts: ["https://es01:9200"] - -# The name of the Kibana instance -server.name: "kibana" - -# The base path for Kibana -#server.basePath: "" - -# Serve the Kibana instance at the root path -#server.rewriteBasePath: false - -# Enable or disable the Kibana server -server.enabled: true - -# The port Kibana will listen on -server.port: 5601 - -# Enable or disable the xpack features -xpack.enabled: true - -# Set the encryption key for encrypted saved objects -#xpack.encryptedSavedObjects.encryptionKey: "" - -# Set the key for the kibana security features -#xpack.security.encryptionKey: "" - -# Enable or disable the monitoring feature -xpack.monitoring.enabled: true - -# Set the URL of the Elasticsearch instance to which Kibana should connect -#xpack.reporting.enabled: true - - #xpack.reporting.roles.enabled: false - -# Enable the Kibana alerting feature -#xpack.alerting.enabled: false - -# Enable or disable the usage collection -#xpack.usageCollection.enabled: true - -# Configure the log level for Kibana -#logging.level: info - -# Configure the directory where logs will be stored -logging.dest: /var/log/kibana/kibana.log - -# Configure security and authentication settings -elasticsearch.username: test -elasticsearch.password: test - -# Disable or enable the Kibana plugin -#xpack.license.management.enabled: false - diff --git a/config/logstash.conf b/config/logstash.conf index 28710ab..f8a8a2c 100644 --- a/config/logstash.conf +++ b/config/logstash.conf @@ -1,30 +1,21 @@ input { - file { - path => "/var/lib/docker/containers/*/*.log" - start_position => "beginning" - sincedb_path => "/dev/null" - type => "docker" - codec => "json" - } + udp { + host => "0.0.0.0" + port => 5044 + } } -filter { - if [log_message] =~ /GET/ { - grok { - match => { "log_message" => "%{IP:client_ip} - - \[%{HTTPDATE:timestamp}\] \"%{WORD:method} %{URIPATH:request_path} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:response_size}" } - } - date { - match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] - target => "@timestamp" - } - } -} +filter {} output { - elasticsearch { - hosts => ["http://es01:9200"] - index => "docker-logs-%{+YYYY.MM.dd}" - user=> "${ELASTIC_USER}" - password=> "${ELASTIC_PASSWORD}" - } + elasticsearch { + index => "logstash-%{+YYYY.MM.dd}" + hosts => ["https://es01:9200"] + user => "elastic" + password => elastic_pass + ssl_enabled => true + ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt" + ssl_verification_mode => "full" + } + #stdout {} } diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index a046dbe..0000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,134 +0,0 @@ -services: - backend: - build: - context: . - dockerfile: Dockerfile - image: backend - container_name: backend - restart: always - command: /bin/sh -c "sleep 5 && - venv/bin/python manage.py makemigrations --noinput && - venv/bin/python manage.py migrate --noinput && - venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" - volumes: - - pong:/transcendence/pong - ports: - - "8080:8080" - networks: - - app-network - environment: - DB_HOST: db - DB_PORT: 5432 - DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} - DB_PASSWORD: ${POSTGRES_PASSWORD} - depends_on: - - db - healthcheck: - test: ["CMD-SHELL", "curl", "http://localhost:8080"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s - - db: - image: postgres:latest - container_name: postgres - restart: always - volumes: - - pong_pg_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - app-network - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 - - es01: - image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} - container_name: es01 - volumes: - - pong_es_data_01:/usr/share/elasticsearch/data - ports: - - "9200:9200" - networks: - - app-network - environment: - - node.name=es01 - - cluster.name=${CLUSTER_NAME} - - discovery.type=single-node - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - bootstrap.memory_lock=true - - xpack.security.enabled=false - healthcheck: - test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"'"] - interval: 10s - timeout: 10s - retries: 5 - - kibana: - image: docker.elastic.co/kibana/kibana:${STACK_VERSION} - container_name: kibana - volumes: - - pong_kibana:/usr/share/kibana/data - user: "1000:1000" - ports: - - 5601:5601 - networks: - - app-network - environment: - - SERVERNAME=pong.kibana.org - - ELASTICSEARCH_HOSTS=http://es01:9200 - - ELASTICSEARCH_USERNAME=${ELASTIC_USERNAME} - - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} - depends_on: - - es01 - healthcheck: - test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q '200 OK'"] - interval: 10s - timeout: 20s - retries: 200 - - - logstash01: - image: docker.elastic.co/logstash/logstash:${STACK_VERSION} - container_name: logstash01 - volumes: - - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro - ports: - - "5044:5044" - networks: - - app-network - environment: - - ELASTIC_HOSTS=http://es01:9200 - - ELASTIC_USER=${ELASTIC_USERNAME} - - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - - xpack.monitoring.enabled=false - -volumes: - pong: - driver: local - driver_opts: - type: none - device: ${PROJECT_PATH} - o: bind - pong_pg_data: - driver: local - pong_es_data_01: - driver: local - pong_kibana: - driver: local - - - -networks: - app-network: - driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index fc73df1..e23d562 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,38 +6,59 @@ services: volumes: - certs:/usr/share/elasticsearch/config/certs command: > - sh -c ' - if [ ! -f /usr/share/elasticsearch/config/certs/elastic-certificate.p12 ]; then - echo "Creating elastic-certificate.p12..."; - bin/elasticsearch-certutil cert --name elastic-certificate --days 365 --self-signed --out /usr/share/elasticsearch/config/certs/elastic-certificate.p12 --pass ""; - else - echo "elastic-certificate.p12 already exists, skipping certificate creation."; - fi; - - if [ ! -f /usr/share/elasticsearch/config/certs/instances.yml ]; then - echo "Creating certs"; - echo -ne \ - "instances:\n"\ - " - name: es01\n"\ - " dns:\n"\ - " - es01\n"\ - " - localhost\n"\ - " ip:\n"\ - " - 127.0.0.1\n"\ - " - name: kibana\n"\ - " dns:\n"\ - " - kibana\n"\ - " - localhost\n"\ - " ip:\n"\ - " - 127.0.0.1\n"\ + bash -c ' + if [ x${ELASTIC_PASSWORD} == x ]; then + echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; + exit 1; + elif [ x${KIBANA_PASSWORD} == x ]; then + echo "Set the KIBANA_PASSWORD environment variable in the .env file"; + exit 1; + fi; + if [ ! -f config/certs/ca.zip ]; then + echo "Creating CA"; + bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; + unzip config/certs/ca.zip -d config/certs; + fi; + if [ ! -f config/certs/certs.zip ]; then + echo "Creating certs"; + echo -ne \ + "instances:\n"\ + " - name: es01\n"\ + " dns:\n"\ + " - es01\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ + " - name: kibana\n"\ + " dns:\n"\ + " - kibana\n"\ + " - localhost\n"\ + " ip:\n"\ + " - 127.0.0.1\n"\ > config/certs/instances.yml; - fi; - echo "Setting file permissions"; - find /usr/share/elasticsearch/config/certs -type d -exec chmod 750 \{\} \;; - find /usr/share/elasticsearch/config/certs -type f -exec chmod 640 \{\} \;; - tail -f /dev/null; + bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; + unzip config/certs/certs.zip -d config/certs; + fi; + + echo "Setting file permissions" + chown -R root:root config/certs; + find . -type d -exec chmod 750 \{\} \;; + find . -type f -exec chmod 640 \{\} \;; + + echo "Waiting for Elasticsearch availability"; + until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done; + echo "Setting kibana_system password"; + until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; + echo "All done!"; ' + healthcheck: + test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"] + interval: 1s + timeout: 5s + retries: 120 + + backend: build: @@ -54,7 +75,7 @@ services: volumes: - pong:/transcendence/pong ports: - - "8080:8080" + - 8080:8080 networks: - app-network environment: @@ -95,12 +116,16 @@ services: es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 + depends_on: + setup: + condition: service_healthy volumes: - certs:/usr/share/elasticsearch/config/certs:ro + - pong_es_data_01:/usr/share/elasticsearch/data + labels: + co.elastic.logs/module: elasticsearch ports: - - "9200:9200" - networks: - - app-network + - 9200:9200 environment: - node.name=es01 - cluster.name=${CLUSTER_NAME} @@ -108,55 +133,79 @@ services: - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - bootstrap.memory_lock=true - xpack.security.enabled=true + - xpack.security.http.ssl.enabled=true + - xpack.security.http.ssl.key=certs/es01/es01.key + - xpack.security.http.ssl.certificate=certs/es01/es01.crt + - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.enabled=true - - xpack.security.transport.ssl.keystore.path=/usr/share/elasticsearch/config/certs/elastic-certificate.p12 - - xpack.security.transport.ssl.keystore.type=PKCS12 - - xpack.security.transport.ssl.keystore.password="" + - xpack.security.transport.ssl.key=certs/es01/es01.key + - xpack.security.transport.ssl.certificate=certs/es01/es01.crt + - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt + - xpack.security.transport.ssl.verification_mode=certificate - xpack.license.self_generated.type=${LICENSE} - depends_on: - - setup - - logstash01 healthcheck: - test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"'"] + test: + [ + "CMD-SHELL", + "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", + ] interval: 10s timeout: 10s - retries: 5 + retries: 120 kibana: image: docker.elastic.co/kibana/kibana:${STACK_VERSION} container_name: kibana + labels: + co.elastic.logs/module: kibana + depends_on: + es01: + condition: service_healthy volumes: - certs:/usr/share/kibana/config/certs:ro - pong_kibana:/usr/share/kibana/data - user: "1000:1000" ports: - 5601:5601 - networks: - - app-network environment: - - SERVERNAME=pong.kibana.org - - ELASTICSEARCH_HOSTS=http://es01:9200 - - ELASTICSEARCH_USERNAME=${ELASTIC_USERNAME} - - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD} - depends_on: - - es01 + - SERVERNAME=kibana + - ELASTICSEARCH_HOSTS=https://es01:9200 + - ELASTICSEARCH_USERNAME=${KIBANA_USERNAME} + - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} + - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt + - XPACK_SECURITY_ENCRYPTIONKEY=${ENCRYPTION_KEY} + - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=${ENCRYPTION_KEY} + - XPACK_REPORTING_ENCRYPTIONKEY=${ENCRYPTION_KEY} healthcheck: - test: ["CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'"] + test: + [ + "CMD-SHELL", + "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'" + ] interval: 10s - timeout: 20s - retries: 200 + timeout: 10s + retries: 120 logstash01: image: docker.elastic.co/logstash/logstash:${STACK_VERSION} container_name: logstash01 + labels: + co.elastic.logs/module: logstash + user: root + depends_on: + es01: + condition: service_healthy + kibana: + condition: service_healthy volumes: + - certs:/usr/share/logstash/certs + - pong_logstash_data01:/usr/share/logstash/data - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro ports: - - "5044:5044" - networks: - - app-network + - "5044:5044/udp" + command: logstash -f /usr/share/logstash/pipeline/logstash.conf environment: - - ELASTIC_HOSTS=http://es01:9200 + - NODE_NAME="logstash" + - ELASTIC_HOSTS=https://es01:9200 - ELASTIC_USER=${ELASTIC_USERNAME} - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - xpack.monitoring.enabled=false @@ -176,32 +225,10 @@ volumes: driver: local pong_kibana: driver: local + pong_logstash_data01: + driver: local networks: app-network: name: app-network driver: bridge - - - - #filebeat01: - #depends_on: - #- es01 - # image: docker.elastic.co/beats/filebeat:${STACK_VERSION} - # volumes: - # - certs:/usr/share/logstash/certs - # - pong_filebeat_data_01:/usr/share/filebeat/data - # - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - # - /var/lib/docker/containers:/var/lib/docker/containers:ro - # - /var/run/docker.sock:/var/run/docker.sock:ro - # environment: - # - ELASTIC_USER=elastic - # - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - # - ELASTIC_HOSTS=https://es01:9200 - # - KIBANA_HOSTS=http://kibana:5601 - # - LOGSTASH_HOSTS=http://logstash01:9600 - # - xpack.monitoring.enabled=false - # networks: - # - app-network - - diff --git a/env_template b/env_template index 991d475..b297aeb 100644 --- a/env_template +++ b/env_template @@ -4,32 +4,27 @@ DEBUG=True DJANGO_ALLOWED_HOSTS=['*'] # PostgreSQL settings -POSTGRES_DB= -POSTGRES_USER= +POSTGRES_DB=players_db +POSTGRES_USER=42student POSTGRES_PASSWORD= +# Django settings DB_HOST=db DB_PORT=5432 - -PROJECT_PATH=${PWD}/pong -POSTGRES_DATA_PATH=${PWD}/data/db -ES_DATA_PATH=${PWD}/data/es -KIBA_DATA_PATH=${PWD}/data/kiba -LSTASH_DATA_PATH=${PWD}/data/lstash +PWD_PATH=${PWD} +PROJECT_PATH=${PWD_PATH}/pong # ElasticSearch settings STACK_VERSION=8.14.3 CLUSTER_NAME=docker-cluster LICENSE=basic +ELASTIC_USERNAME=elastic ELASTIC_PASSWORD= -ES_PORT=9200 # Kibana settings -KIBANA_PASSWORD= KIBANA_PORT=5601 +KIBANA_USERNAME= +KIBANA_PASSWORD= -ES_MEM_LIMIT=1073741824 -KB_MEM_LIMIT=1073741824 -LS_MEM_LIMIT=1073741824 - +ENCRYPTION_KEY=c34d38b3a14956121ff2170e5030b471551370178f43e5626eec58b04a30fae2 diff --git a/makefile b/makefile index 169500b..ab94427 100644 --- a/makefile +++ b/makefile @@ -2,9 +2,11 @@ COMPOSE_FILE=docker-compose.yml COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) +.PHONY: up build start stop down destroy logs ps db-shell help + up: $(COMPOSE) build - $(COMPOSE) up $(CONTAINER) + $(COMPOSE) up $(CONTAINER) || true build: $(COMPOSE) build $(CONTAINER) @@ -40,7 +42,7 @@ help: @echo " make down [c=service] # Stop and remove containers" @echo " make destroy # Stop and remove containers and volumes" @echo " make stop [c=service] # Stop containers" - @echo " make restart [c=service] # Restart containers" @echo " make logs [c=service] # Tail logs of containers" @echo " make ps # List containers" @echo " make help # Show this help" + From f747e4a00f289a1a6a9da9a25b39532deeb4bac5 Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Sun, 18 Aug 2024 19:34:17 +0200 Subject: [PATCH 31/81] added LOCAL GAME mode --- docker-compose.yml | 4 +- makefile | 2 +- pong/game/consumers.py | 29 +++++ pong/game/game.py | 82 +++++++------ pong/game/matchmaking.py | 44 ++++--- pong/game/views.py | 20 ++-- pong/static/game.js | 246 ++++++++++++++++++++++++++++++++------- pong/static/index.html | 18 +++ 8 files changed, 339 insertions(+), 106 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d11b2d0..21e272e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,11 +10,11 @@ services: venv/bin/python manage.py makemigrations --noinput && venv/bin/python manage.py migrate --noinput && venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" + venv/bin/daphne -b 0.0.0.0 -p 80 pong.asgi:application" volumes: - pong:/transcendence/pong ports: - - "8080:8080" + - "80:80" networks: - app-network environment: diff --git a/makefile b/makefile index 92b9d50..1a44697 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ COMPOSE_FILE=docker-compose.yml COMPOSE=docker compose -f $(COMPOSE_FILE) CONTAINER=$(c) -up: +up: down $(COMPOSE) build $(COMPOSE) up diff --git a/pong/game/consumers.py b/pong/game/consumers.py index b473ece..e3d68a1 100644 --- a/pong/game/consumers.py +++ b/pong/game/consumers.py @@ -16,6 +16,8 @@ class GameConsumer(AsyncWebsocketConsumer): data = json.loads(text_data) if data['type'] == 'authenticate': await self.authenticate(data['token']) + elif data['type'] == 'authenticate2': + await self.authenticate2(data['token_1'], data['token_2']) elif data['type'] == 'key_press': if self.game: await self.game.handle_key_press(self, data['key']) @@ -45,6 +47,33 @@ class GameConsumer(AsyncWebsocketConsumer): await self.send(text_data=json.dumps({'type': 'waiting_room'})) await match_maker.add_player(self) + async def authenticate2(self, token, token2): + 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") + user2 = await self.get_user_from_token2(token2) + if user2: + self.user2 = user2 + await self.send(text_data=json.dumps({'type': 'authenticated'})) + print(f"User {self.user2} authenticated") + await match_maker.create_game(self, None, True) + else: + await self.send(text_data=json.dumps({'type': 'error', 'message': 'Authentication failed'})) + print("Authentication failed") + else: + await self.send(text_data=json.dumps({'type': 'error', 'message': 'Authentication failed'})) + print("Authentication failed") + + @database_sync_to_async + def get_user_from_token2(self, token): + try: + user2 = User.objects.filter(auth_token=token).first() + return user2 + except User.DoesNotExist: + return None + async def disconnect(self, close_code): if self.game: await self.game.end_game(disconnected_player=self) diff --git a/pong/game/game.py b/pong/game/game.py index 7ff81f3..23f9719 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -6,23 +6,36 @@ import random from datetime import datetime from .utils import endfortheouche - class Game: - def __init__(self, game_id, player1, player2): + def __init__(self, game_id, player1, player2, localgame): self.game_id = game_id self.player1 = player1 self.player2 = player2 - self.botgame = player2 is None - self.game_state = { - 'player1_name': player1.user.username, - 'player2_name': player2.user.username if player2 else 'BOT', - 'player1_position': 150, - 'player2_position': 150, - 'ball_position': {'x': 390, 'y': 190}, - 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, - 'player1_score': 0, - 'player2_score': 0 - } + self.localgame = localgame + if self.localgame: + self.botgame = False + self.game_state = { + 'player1_name': player1.user.username, + 'player2_name': player1.user2.username, + 'player1_position': 150, + 'player2_position': 150, + 'ball_position': {'x': 390, 'y': 190}, + 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, + 'player1_score': 0, + 'player2_score': 0 + } + else: + self.botgame = player2 is None + self.game_state = { + 'player1_name': player1.user.username, + 'player2_name': player2.user.username if player2 else 'BOT', + 'player1_position': 150, + 'player2_position': 150, + 'ball_position': {'x': 390, 'y': 190}, + 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, + 'player1_score': 0, + 'player2_score': 0 + } self.speed = 1 self.game_loop_task = None self.ended = False @@ -31,21 +44,18 @@ class Game: self.bt1 = 0 self.bt2 = 0 self.start_time = None - - async def start_game(self): print(f"- Game #{self.game_id} STARTED") self.game_loop_task = asyncio.create_task(self.game_loop()) - print(" begin MATCH at : ") self.start_time = datetime.now() - print(f" begin MATCH : {self.start_time} ") + print(f" Begin MATCH at: {self.start_time}") async def game_loop(self): + print(" In the game loop..") while not self.ended: if self.botgame: - await self.update_bot_position() - + await self.update_bot_position() await self.handle_pad_movement() await self.update_game_state() await self.send_game_state() @@ -60,7 +70,6 @@ class Game: elif self.game_state['player2_position'] + 80 > target_y: self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0) - async def update_game_state(self): if self.ended: return @@ -84,18 +93,19 @@ class Game: self.bt2 += 1 self.update_ball_velocity() # Check for scoring - print(f"########### score user 1 {self.game_state['player1_score']} ###########") - print(f"§§§§§§§§§§§ score user 2 {self.game_state['player2_score']} §§§§§§§§§§§") + #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: self.game_state['player2_score'] += 1 - if self.game_state['player2_score'] >= 2: + if self.game_state['player2_score'] > 2: print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") await self.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 - if self.game_state['player1_score'] >= 2: + if self.game_state['player1_score'] > 2: + print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") await self.end_game() self.reset_ball() @@ -128,30 +138,33 @@ class Game: }) await self.player1.send(message) if not self.botgame: - await self.player2.send(message) + if not self.localgame: + await self.player2.send(message) async def handle_key_press(self, player, key): if self.ended: return - if player == self.player1: - print(f"Key press: {key}") + if self.localgame: if key == 'arrowup': self.p1_mov = -1 - #self.game_state['player1_position'] = max(self.game_state['player1_position'] - 25, 0) elif key == 'arrowdown': self.p1_mov = 1 - #self.game_state['player1_position'] = min(self.game_state['player1_position'] + 25, 300) - elif not self.botgame and player == self.player2: + elif key == 'w': + self.p2_mov = -1 + elif key == 's': + self.p2_mov = 1 + elif player == self.player1: + if key == 'arrowup': + self.p1_mov = -1 + elif key == 'arrowdown': + self.p1_mov = 1 + elif player == self.player2: if key == 'arrowup': self.p2_mov = -1 - #self.game_state['player2_position'] = max(self.game_state['player2_position'] - 25, 0) elif key == 'arrowdown': self.p2_mov = 1 - #self.game_state['player2_position'] = min(self.game_state['player2_position'] + 25, 300) async def handle_pad_movement(self): - #print(f"P1 mov: {self.p1_mov}") - #print(f"P2 mov: {self.p2_mov}") if self.ended: return if self.p1_mov == -1: @@ -197,4 +210,3 @@ class Game: await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], self.bt1, self.bt2, duration, False, None) - diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 32f9981..9d20580 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -35,12 +35,12 @@ class MatchMaker: player1 = self.waiting_players.pop(0) player2 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs {player2.user.username}") - await self.create_game(player1, player2) + await self.create_game(player1, player2, False) else: await asyncio.sleep(1) self.timer += 1 # Waiting for more than 30s -> BOT game - if self.timer >= 5 and self.waiting_players: + if self.timer >= 30 and self.waiting_players: player1 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs BOT") self.botgame = True @@ -49,26 +49,30 @@ class MatchMaker: if not self.waiting_players: break - async def create_game(self, player1, player2): + async def create_game(self, player1, player2, localgame): game_id = len(self.active_games) + 1 - print(f"- Creating game: #{game_id}") - new_game = Game(game_id, player1, player2) + if localgame: + print(f"- Creating LOCAL game: #{game_id}") + else: + print(f"- Creating MATCH game: #{game_id}") + new_game = Game(game_id, player1, player2, localgame) self.active_games[game_id] = new_game await player1.set_game(new_game) - await player2.set_game(new_game) - await self.notify_players(player1, player2, game_id) + if not localgame: + await player2.set_game(new_game) + await self.notify_players(player1, player2, game_id, localgame) asyncio.create_task(new_game.start_game()) async def create_bot_game(self, player1): game_id = len(self.active_games) + 1 print(f"- Creating BOT game: #{game_id}") - new_game = Game(game_id, player1, None) + new_game = Game(game_id, player1, None, False) self.active_games[game_id] = new_game await player1.set_game(new_game) - await self.notify_players(player1, None, game_id) + await self.notify_players(player1, None, game_id, False) asyncio.create_task(new_game.start_game()) - async def notify_players(self, player1, player2, game_id): + async def notify_players(self, player1, player2, game_id, localgame): if player2: await player1.send(json.dumps({ 'type': 'game_start', @@ -83,12 +87,20 @@ class MatchMaker: 'player2': player2.user.username })) else: - await player1.send(json.dumps({ - 'type': 'game_start', - 'game_id': game_id, - 'player1': player1.user.username, - 'player2': 'BOT' - })) + if localgame: + await player1.send(json.dumps({ + 'type': 'game_start', + 'game_id': game_id, + 'player1': player1.user.username, + 'player2': player1.user2.username + })) + else: + await player1.send(json.dumps({ + 'type': 'game_start', + 'game_id': game_id, + 'player1': player1.user.username, + 'player2': 'BOT' + })) async def handle_key_press(self, player, key): for game in self.active_games.values(): diff --git a/pong/game/views.py b/pong/game/views.py index e810b78..e9b0151 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -18,6 +18,16 @@ from rest_framework import viewsets import json import uuid +@csrf_exempt +def check_user_exists(request): + if request.method == 'POST': + data = json.loads(request.body) + username = data.get('username') + if User.objects.filter(username=username).exists(): + return JsonResponse({'exists': True}) + return JsonResponse({'exists': False}) + return JsonResponse({'error': 'Invalid request method'}, status=400) + @csrf_exempt def register_user(request): if request.method == 'POST': @@ -31,16 +41,6 @@ def register_user(request): return JsonResponse({'registered': False, 'error': 'User already exists'}) return JsonResponse({'error': 'Invalid request method'}, status=400) -@csrf_exempt -def check_user_exists(request): - if request.method == 'POST': - data = json.loads(request.body) - username = data.get('username') - if User.objects.filter(username=username).exists(): - return JsonResponse({'exists': True}) - return JsonResponse({'exists': False}) - return JsonResponse({'error': 'Invalid request method'}, status=400) - @csrf_exempt def authenticate_user(request): if request.method == 'POST': diff --git a/pong/static/game.js b/pong/static/game.js index 0698013..f081244 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -1,26 +1,45 @@ document.addEventListener('DOMContentLoaded', () => { - console.log('DOMContentLoaded event fired'); - const checkNicknameButton = document.getElementById('check-nickname'); - const registerButton = document.getElementById('register'); - const loginButton = document.getElementById('login'); + const formBlock = document.getElementById('block-form'); + const authForm = document.getElementById('auth-form'); - const gameContainer = document.getElementById('game1'); const nicknameInput = document.getElementById('nickname'); + const checkNicknameButton = document.getElementById('check-nickname'); + + const registerForm = document.getElementById('register-form'); const passwordInput = document.getElementById('password'); const confirmPasswordInput = document.getElementById('confirm-password'); - const loginPasswordInput = document.getElementById('login-password'); + const registerButton = document.getElementById('register'); + const loginForm = document.getElementById('login-form'); - const registerForm = document.getElementById('register-form'); - const formBlock = document.getElementById('block-form'); + const loginPasswordInput = document.getElementById('login-password'); + const loginButton = document.getElementById('login'); + + const authForm2 = document.getElementById('auth-form2'); + const nicknameInput2 = document.getElementById('nickname2'); + const checkNicknameButton2 = document.getElementById('check-nickname2'); + + const registerForm2 = document.getElementById('register-form2'); + const passwordInput2 = document.getElementById('password2'); + const confirmPasswordInput2 = document.getElementById('confirm-password2'); + const registerButton2 = document.getElementById('register2'); + + const loginForm2 = document.getElementById('login-form2'); + const loginPasswordInput2 = document.getElementById('login-password2'); + const loginButton2 = document.getElementById('login2'); + + const gameContainer = document.getElementById('game1'); + 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 dropdownMenu = document.getElementById('dropdown-menu'); const pongElements = document.getElementById('pong-elements'); const logo = document.querySelector('.logo'); + const localGameButton = document.getElementById('local-game'); const quickMatchButton = document.getElementById('quick-match'); const tournamentButton = document.getElementById('tournament'); @@ -41,11 +60,15 @@ document.addEventListener('DOMContentLoaded', () => { registerButton.addEventListener('click', handleRegister); loginButton.addEventListener('click', handleLogin); + checkNicknameButton2.addEventListener('click', handleCheckNickname2); + registerButton2.addEventListener('click', handleRegister2); + loginButton2.addEventListener('click', handleLogin2); + + localGameButton.addEventListener('click', startLocalGame); quickMatchButton.addEventListener('click', startQuickMatch); tournamentButton.addEventListener('click', startTournament); - async function handleCheckNickname() { const nickname = nicknameInput.value.trim(); if (nickname) { @@ -109,13 +132,7 @@ document.addEventListener('DOMContentLoaded', () => { const result = await registerUser(nickname, password); if (result) { registerForm.style.display = 'none'; - //gameContainer.style.display = 'flex'; - //formBlock.style.display = 'none'; - //logo.style.display = 'none'; - pongElements.style.display = 'none'; - console.log("new button must appear !"); - document.getElementById("post-form-buttons").style.display = 'inline-block'; - //startWebSocketConnection(token); + document.getElementById("post-form-buttons").style.display = 'block'; } else { alert('Registration failed. Please try again.'); } @@ -149,13 +166,7 @@ document.addEventListener('DOMContentLoaded', () => { const result = await authenticateUser(nickname, password); if (result) { loginForm.style.display = 'none'; - //gameContainer.style.display = 'flex'; - //formBlock.style.display = 'none'; - //logo.style.display = 'none'; - //pongElements.style.display = 'none'; - console.log("new button must appear !"); - document.getElementById("post-form-buttons").style.display = 'inline-block'; - //startWebSocketConnection(token); + document.getElementById("post-form-buttons").style.display = 'block'; } else { alert('Authentication failed. Please try again.'); } @@ -164,18 +175,6 @@ document.addEventListener('DOMContentLoaded', () => { } } - function startQuickMatch() { - gameContainer.style.display = 'flex'; - logo.style.display = 'none'; - menuButton.style.display = 'none'; - formBlock.style.display = 'none'; - startWebSocketConnection(token); - } - - function startTournament() { - console.log("For now, do nothing, hurry up and work Senor chaku !!!!") - } - async function authenticateUser(username, password) { const response = await fetch('/authenticate_user/', { method: 'POST', @@ -191,12 +190,176 @@ document.addEventListener('DOMContentLoaded', () => { return data.authenticated; } - function startWebSocketConnection(token) { + // functions to handle the second player + + async function handleCheckNickname2() { + const nickname2 = nicknameInput2.value.trim(); + if (nickname2) { + try { + const exists = await checkUserExists2(nickname2); + if (exists) { + authForm2.style.display = 'none'; + loginForm2.style.display = 'block'; + // Auto-focus and key handling for LOGIN-FORM2 + loginPasswordInput2.focus(); + loginPasswordInput2.addEventListener('keypress', function (event) { + if (event.key === 'Enter') { + event.preventDefault(); + loginButton2.click(); + } + }); + } else { + authForm2.style.display = 'none'; + registerForm2.style.display = 'block'; + // Auto-focus and key handling for REGISTER-FORM2 + passwordInput2.focus(); + passwordInput2.addEventListener('keypress', function (event) { + if (event.key === 'Enter') { + confirmPasswordInput2.focus(); + confirmPasswordInput2.addEventListener('keypress', function (event) { + if (event.key === 'Enter') { + event.preventDefault(); + registerButton2.click(); + } + }); + } + }); + } + } catch (error) { + console.error('Error checking user existence:', error); + } + } else { + alert('Please enter a nickname.'); + } + } + + async function checkUserExists2(username) { + const response = await fetch('/check_user_exists/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username }) + }); + const data = await response.json(); + return data.exists; + } + + async function handleRegister2() { + const nickname2 = nicknameInput2.value.trim(); + const password2 = passwordInput2.value.trim(); + const confirmPassword2 = confirmPasswordInput2.value.trim(); + + if (password2 === confirmPassword2) { + try { + const result = await registerUser2(nickname2, password2); + if (result) { + registerForm2.style.display = 'none'; + startLocalGame2(); + } else { + alert('Registration failed. Please try again.'); + } + } catch (error) { + console.error('Error registering user:', error); + } + } else { + alert('Passwords do not match.'); + } + } + + async function registerUser2(username, password) { + const response = await fetch('/register_user/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password }) + }); + const data = await response.json(); + if (data.registered) { + token2 = data.token; + } + return data.registered; + } + + async function handleLogin2() { + const nickname2 = nicknameInput2.value.trim(); + const password2 = loginPasswordInput2.value.trim(); + try { + const result = await authenticateUser2(nickname2, password2); + if (result) { + loginForm2.style.display = 'none'; + startLocalGame2(); + } else { + alert('Authentication failed. Please try again.'); + } + } catch (error) { + console.error('Error authenticating user:', error); + } + } + + async function authenticateUser2(username, password) { + const response = await fetch('/authenticate_user/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password }) + }); + const data = await response.json(); + if (data.authenticated) { + token2 = data.token; + } + return data.authenticated; + } + + function startLocalGame() { + console.log("starting a Local Game.."); + document.getElementById("post-form-buttons").style.display = 'none'; + authForm2.style.display = 'block'; + nicknameInput2.focus(); + nicknameInput2.addEventListener('keypress', function (event) { + if (event.key === 'Enter') { + event.preventDefault(); + checkNicknameButton2.click(); + } + }); + } + + function startLocalGame2() { + gameContainer.style.display = 'flex'; + logo.style.display = 'none'; + pongElements.style.display = 'none'; + menuButton.style.display = 'none'; + formBlock.style.display = 'none'; + startWebSocketConnection(token, 2); + } + + function startQuickMatch() { + gameContainer.style.display = 'flex'; + logo.style.display = 'none'; + pongElements.style.display = 'none'; + menuButton.style.display = 'none'; + formBlock.style.display = 'none'; + startWebSocketConnection(token, 1); + } + + function startTournament() { + console.log("For now, do nothing, hurry up and work Senor chaku !!!!") + } + + function startWebSocketConnection(token, players) { socket = new WebSocket(`ws://${window.location.host}/ws/game/`); socket.onopen = function (event) { console.log('WebSocket connection established'); - socket.send(JSON.stringify({ type: 'authenticate', token: token })); + if (players === 1) { + console.log("Sending token for 1 player game"); + socket.send(JSON.stringify({ type: 'authenticate', token: token })); + } else { + console.log("Sending tokens for 2 player game"); + socket.send(JSON.stringify({ type: 'authenticate2', token_1: token, token_2: token2 })); + } }; socket.onmessage = function (event) { @@ -239,15 +402,15 @@ document.addEventListener('DOMContentLoaded', () => { } function handleKeyDown(event) { - if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { - console.log('Key press: ', event.key); + if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'w' || event.key === 's') { + //console.log('Key press: ', event.key); sendKeyPress(event.key.toLowerCase()); } } function sendKeyPress(key) { if (socket.readyState === WebSocket.OPEN) { - console.log('Key sent: ', key); + //console.log('Key sent: ', key); socket.send(JSON.stringify({ type: 'key_press', key })); } } @@ -403,7 +566,6 @@ document.addEventListener('DOMContentLoaded', () => { console.log('No players to display'); } - players.forEach(player => { const row = document.createElement('tr'); row.innerHTML = ` diff --git a/pong/static/index.html b/pong/static/index.html index 48d0691..4270897 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -110,9 +110,27 @@
+ + + From de4829b47e21bb20b5b0428d347f5bcbe4d711cc Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Mon, 19 Aug 2024 17:04:37 +0200 Subject: [PATCH 32/81] swapped the player's keys in local game mode --- pong/game/game.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pong/game/game.py b/pong/game/game.py index 23f9719..31048af 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -146,13 +146,13 @@ class Game: return if self.localgame: if key == 'arrowup': - self.p1_mov = -1 - elif key == 'arrowdown': - self.p1_mov = 1 - elif key == 'w': self.p2_mov = -1 - elif key == 's': + elif key == 'arrowdown': self.p2_mov = 1 + elif key == 'w': + self.p1_mov = -1 + elif key == 's': + self.p1_mov = 1 elif player == self.player1: if key == 'arrowup': self.p1_mov = -1 @@ -205,7 +205,8 @@ class Game: }) await self.player1.send(end_message) if not self.botgame: - await self.player2.send(end_message) + if not self.localgame: + await self.player2.send(end_message) print("save data") await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], self.game_state['player1_score'], self.game_state['player2_score'], From 67879a9d976eb9ab38903b9d33a6f9cbdd735596 Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 20 Aug 2024 16:26:39 +0200 Subject: [PATCH 33/81] merge pb avec adrien --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 892419a..86419bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -225,6 +225,8 @@ volumes: driver: local pong_logstash_data01: driver: local + certs: + driver: local networks: app-network: From 5433da77ed8c4ac9933eee4aed10698d553e75b0 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 21 Aug 2024 14:42:11 +0200 Subject: [PATCH 34/81] jcheca part moved but flag doesn't work --- pong/static/game.js | 150 +++++++++++++++++++++++++++++++++++++++ pong/static/index.html | 154 ----------------------------------------- 2 files changed, 150 insertions(+), 154 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index 0698013..e926d48 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -447,4 +447,154 @@ document.addEventListener('DOMContentLoaded', () => { }); } + var modal = document.getElementById("myModal"); + var btn = document.getElementById("myBtn"); + var span = document.getElementsByClassName("close")[0]; + var jsonContent = document.getElementById("jsonContent"); + btn.onclick = function() { + fetch('/web3/') + .then(response => response.json()) + .then(data => { + jsonContent.textContent = JSON.stringify(data, null, 2); + modal.style.display = "block"; + }); + } + + span.onclick = function() { + modal.style.display = "none"; + } + + window.onclick = function(event) { + if (event.target == modal) { + modal.style.display = "none"; + } + } + + 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 changeLanguage(lang) { + 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; + } + + const starsContainer = document.getElementById('stars'); + for (let i = 0; i < 500; i++) { + const star = document.createElement('div'); + star.className = 'star'; + star.style.width = `${Math.random() * 3}px`; + star.style.height = star.style.width; + star.style.left = `${Math.random() * 100}%`; + star.style.top = `${Math.random() * 100}%`; + star.style.animationDuration = `${Math.random() * 2 + 1}s`; + starsContainer.appendChild(star); + } + + 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 + } + } + + // Set the language when the page loads + 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'; + }); + + // 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'; + }); + }); diff --git a/pong/static/index.html b/pong/static/index.html index 48d0691..b58283c 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -64,30 +64,6 @@

       
     
-    
 
     

BIENVENUE DANS LE PONG 42

@@ -260,136 +236,6 @@
- - - From 7670e6649e4c46d4c9a6d8df4acf204a105945eb Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 21 Aug 2024 16:37:20 +0200 Subject: [PATCH 35/81] Flag resolved --- pong/static/game.js | 60 +++++++++++++++++++++++++++--------------- pong/static/index.html | 12 ++++----- pong/static/styles.css | 2 +- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index e926d48..e4aee56 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -275,6 +275,9 @@ document.addEventListener('DOMContentLoaded', () => { player2Score.textContent = gameState.player2_score; } + + ////////////////////////////// BEG BURGER BUTTON //////////////////////////////// + menuButton.addEventListener('click', toggleMenu); function toggleMenu() { @@ -287,7 +290,6 @@ document.addEventListener('DOMContentLoaded', () => { } const links = document.querySelectorAll('#dropdown-menu a'); - //console.log(links); links.forEach(link => { link.addEventListener('click', (event) => { @@ -447,6 +449,27 @@ document.addEventListener('DOMContentLoaded', () => { }); } + ////////////////////////////// END BURGER BUTTON //////////////////////////////// + + + ////////////////////////////// BEG STARS //////////////////////////////// + + const starsContainer = document.getElementById('stars'); + for (let i = 0; i < 500; i++) { + const star = document.createElement('div'); + star.className = 'star'; + star.style.width = `${Math.random() * 3}px`; + star.style.height = star.style.width; + star.style.left = `${Math.random() * 100}%`; + star.style.top = `${Math.random() * 100}%`; + star.style.animationDuration = `${Math.random() * 2 + 1}s`; + starsContainer.appendChild(star); + } + + ////////////////////////////// END STARS //////////////////////////////// + + + var modal = document.getElementById("myModal"); var btn = document.getElementById("myBtn"); var span = document.getElementsByClassName("close")[0]; @@ -470,6 +493,7 @@ document.addEventListener('DOMContentLoaded', () => { } } + ////////////////////////////// BEG LANGAGE //////////////////////////////// const translations = { fr: { welcome: "BIENVENUE DANS LE PONG 42", @@ -508,26 +532,6 @@ document.addEventListener('DOMContentLoaded', () => { } }; - function changeLanguage(lang) { - 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; - } - - const starsContainer = document.getElementById('stars'); - for (let i = 0; i < 500; i++) { - const star = document.createElement('div'); - star.className = 'star'; - star.style.width = `${Math.random() * 3}px`; - star.style.height = star.style.width; - star.style.left = `${Math.random() * 100}%`; - star.style.top = `${Math.random() * 100}%`; - star.style.animationDuration = `${Math.random() * 2 + 1}s`; - starsContainer.appendChild(star); - } - function setCookie(name, value, days) { const d = new Date(); d.setTime(d.getTime() + (days*24*60*60*1000)); @@ -570,9 +574,21 @@ document.addEventListener('DOMContentLoaded', () => { } } + 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'; }); @@ -597,4 +613,6 @@ document.addEventListener('DOMContentLoaded', () => { document.body.style.fontSize = this.value + 'px'; }); + ////////////////////////////// END SETTING //////////////////////////////// + }); diff --git a/pong/static/index.html b/pong/static/index.html index b58283c..fb590e0 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -6,7 +6,7 @@ Pong Game - + @@ -22,11 +22,11 @@
- Français - English - Italiano - Español - Deutsch + Français + English + Italiano + Español + Deutsch
diff --git a/pong/static/styles.css b/pong/static/styles.css index 8c3436e..450ac4e 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -264,7 +264,7 @@ button:hover { .navbar { position: absolute; - top: 10px; + top: 30px; right: 10px; padding: 10px; } From c72986748e618b2dbd20e21a11ff7bb8e3b7a160 Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 22 Aug 2024 14:31:43 +0200 Subject: [PATCH 36/81] hideAllTable() --- pong/static/game.js | 24 ++++++++++++++++++++---- pong/static/index.html | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index e4aee56..9407136 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -16,6 +16,7 @@ document.addEventListener('DOMContentLoaded', () => { 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 dropdownMenu = document.getElementById('dropdown-menu'); const pongElements = document.getElementById('pong-elements'); @@ -284,18 +285,26 @@ document.addEventListener('DOMContentLoaded', () => { 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"); + //console.log("Here !!!!!!!!!!!! NNNNNNNN"); showTable(tableId); }); }); @@ -303,9 +312,7 @@ document.addEventListener('DOMContentLoaded', () => { function showTable(tableId) { // Masquer tous les tableaux console.log('Entering showTable', tableId); - if (playerList) playerList.style.display = 'none'; - if (matchList) matchList.style.display = 'none'; - if (tournoiList) tournoiList.style.display = 'none'; + hideAllTables(); // Afficher le tableau sélectionné if (tableId === 'player-list') { @@ -324,6 +331,15 @@ document.addEventListener('DOMContentLoaded', () => { //if (tournoiList) tournoiList.style.display = 'block'; fetchTournois(); + } else if (tableId === blockchainList) { + console.log('Showing tournoi list'); + blockchainList.style.display = 'block'; + fetch('/web3/') + .then(response => response.json()) + .then(data => { + jsonContent.textContent = JSON.stringify(data, null, 2); + //modal.style.display = "block"; + }); } // Masquer le menu après la sélection if (dropdownMenu) { diff --git a/pong/static/index.html b/pong/static/index.html index fb590e0..8503345 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -6,7 +6,7 @@ Pong Game - + From c85c5b50a994d188b24c8d6a122a909a4983c088 Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 22 Aug 2024 15:41:43 +0200 Subject: [PATCH 37/81] redirection blockchain --- pong/static/game.js | 42 ++++++++++++++++++++++-------------------- pong/static/index.html | 9 --------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index 9407136..1412185 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -25,6 +25,11 @@ document.addEventListener('DOMContentLoaded', () => { const quickMatchButton = document.getElementById('quick-match'); const tournamentButton = document.getElementById('tournament'); + /* const modal = document.getElementById("myModal"); + const btn = document.getElementById("myBtn"); + const span = document.getElementsByClassName("close")[0]; + const jsonContent = document.getElementById("jsonContent"); */ + let socket; let token; let gameState; @@ -168,7 +173,7 @@ document.addEventListener('DOMContentLoaded', () => { function startQuickMatch() { gameContainer.style.display = 'flex'; logo.style.display = 'none'; - menuButton.style.display = 'none'; + //menuButton.style.display = 'none'; formBlock.style.display = 'none'; startWebSocketConnection(token); } @@ -316,31 +321,32 @@ document.addEventListener('DOMContentLoaded', () => { // Afficher le tableau sélectionné if (tableId === 'player-list') { - console.log('Showing 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'); + console.log('Showing match list 2'); //if (matchList) matchList.style.display = 'block'; fetchMatches(); } else if (tableId === 'tournoi-list') { - console.log('Showing tournoi list'); + console.log('Showing tournoi list 2'); //if (tournoiList) tournoiList.style.display = 'block'; fetchTournois(); - } else if (tableId === blockchainList) { - console.log('Showing tournoi list'); - blockchainList.style.display = 'block'; - fetch('/web3/') - .then(response => response.json()) - .then(data => { - jsonContent.textContent = JSON.stringify(data, null, 2); - //modal.style.display = "block"; - }); + } 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'; @@ -485,15 +491,11 @@ document.addEventListener('DOMContentLoaded', () => { ////////////////////////////// END STARS //////////////////////////////// - - var modal = document.getElementById("myModal"); - var btn = document.getElementById("myBtn"); - var span = document.getElementsByClassName("close")[0]; - var jsonContent = document.getElementById("jsonContent"); - btn.onclick = function() { + /* btn.onclick = function() { fetch('/web3/') .then(response => response.json()) .then(data => { + console.log('ok here !!'); jsonContent.textContent = JSON.stringify(data, null, 2); modal.style.display = "block"; }); @@ -507,7 +509,7 @@ document.addEventListener('DOMContentLoaded', () => { if (event.target == modal) { modal.style.display = "none"; } - } + } */ ////////////////////////////// BEG LANGAGE //////////////////////////////// const translations = { diff --git a/pong/static/index.html b/pong/static/index.html index 8503345..761a97d 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -55,15 +55,6 @@
- - - -

BIENVENUE DANS LE PONG 42

From 5cf91576af92e3bd88dea0195326f3ba36445321 Mon Sep 17 00:00:00 2001 From: Theouche Date: Thu, 22 Aug 2024 17:42:24 +0200 Subject: [PATCH 38/81] hmmm --- pong/game/game.py | 2 ++ pong/game/utils.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pong/game/game.py b/pong/game/game.py index 31048af..851f0b3 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -100,12 +100,14 @@ class Game: self.game_state['player2_score'] += 1 if self.game_state['player2_score'] > 2: print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + await self.send_game_state() await self.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 if self.game_state['player1_score'] > 2: print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + await self.send_game_state() await self.end_game() self.reset_ball() diff --git a/pong/game/utils.py b/pong/game/utils.py index b01c212..4dd3dba 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -6,7 +6,6 @@ from datetime import timedelta from channels.db import database_sync_to_async #from asgiref.sync import database_sync_to_async - async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") From 6ac9629f6afb2df66de24e67a9c66a75bf37dd87 Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Thu, 22 Aug 2024 19:07:24 +0200 Subject: [PATCH 39/81] endfortheouche doesnt work yet --- docker-compose.yml | 108 ++++++++++++++++++++++----------------------- pong/game/game.py | 5 ++- pong/game/utils.py | 41 ++++++++++++----- requirements.txt | 1 + 4 files changed, 88 insertions(+), 67 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 86419bb..6e96098 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,61 +58,6 @@ services: timeout: 5s retries: 120 - - - backend: - build: - context: . - dockerfile: Dockerfile - image: backend - container_name: backend - restart: always - command: /bin/sh -c "sleep 5 && - venv/bin/python manage.py makemigrations --noinput && - venv/bin/python manage.py migrate --noinput && - venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" - volumes: - - pong:/transcendence/pong - ports: - - 8080:8080 - networks: - - app-network - environment: - DB_HOST: db - DB_PORT: 5432 - DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} - DB_PASSWORD: ${POSTGRES_PASSWORD} - depends_on: - - db - healthcheck: - test: ["CMD-SHELL", "curl", "http://localhost:8080"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s - - db: - image: postgres:latest - container_name: postgres - restart: always - volumes: - - pong_pg_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - app-network - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 - es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 @@ -209,6 +154,59 @@ services: - ELASTIC_USER=${ELASTIC_USERNAME} - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - xpack.monitoring.enabled=false + + backend: + build: + context: . + dockerfile: Dockerfile + image: backend + container_name: backend + restart: always + command: /bin/sh -c "sleep 5 && + venv/bin/python manage.py makemigrations --noinput && + venv/bin/python manage.py migrate --noinput && + venv/bin/python manage.py collectstatic --noinput && + venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" + volumes: + - pong:/transcendence/pong + ports: + - 8080:8080 + networks: + - app-network + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: ${POSTGRES_DB} + DB_USER: ${POSTGRES_USER} + DB_PASSWORD: ${POSTGRES_PASSWORD} + depends_on: + - db + healthcheck: + test: ["CMD-SHELL", "curl", "http://localhost:8080"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + + db: + image: postgres:latest + container_name: postgres + restart: always + volumes: + - pong_pg_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - app-network + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 volumes: pong: diff --git a/pong/game/game.py b/pong/game/game.py index 31048af..2baeae2 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -100,12 +100,14 @@ class Game: self.game_state['player2_score'] += 1 if self.game_state['player2_score'] > 2: print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + await self.send_game_state() await self.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 if self.game_state['player1_score'] > 2: print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + await self.send_game_state() await self.end_game() self.reset_ball() @@ -197,7 +199,8 @@ class Game: 'player': disconnected_name }) 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 end_message = json.dumps({ 'type': 'game_ended', diff --git a/pong/game/utils.py b/pong/game/utils.py index b01c212..070da36 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -4,25 +4,34 @@ from django.shortcuts import get_object_or_404 from django.db.models import Max, Sum, F from datetime import timedelta from channels.db import database_sync_to_async -#from asgiref.sync import database_sync_to_async - async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") - if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): + + # Handle Player 1 + exists = await database_sync_to_async(Player.objects.filter(name=p1).exists)() + if exists: + print(f"Player {p1} exists.") + else: + print(f"Player {p1} does not exist.") + + player_1 = await get_name(p1) + print(f"Player 1 retrieval result: {player_1}") + if player_1 is None: + print("############# CREATING PLAYER") player_1 = await create_player(p1) - print("############# PLAYER DONE") else: - player_1 = await database_sync_to_async(Player.objects.get)(name=p1) - - print("ok") - - if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): + print("############# PLAYER FOUND") + + # Handle Player 2 + player_2 = await get_name(p2) + print(f"Player 2 retrieval result: {player_2}") + if player_2 is None: + print("############# CREATING PLAYER") player_2 = await create_player(p2) - print("############# PLAYER DONE") else: - player_2 = await database_sync_to_async(Player.objects.get)(name=p2) + print("############# PLAYER FOUND") print("############# BEFORE MATCH") await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) @@ -31,9 +40,19 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_ await update_player_statistics(p1) print("############# END STAT P1") await update_player_statistics(p2) + print("############# END STAT P2") except Exception as e: print(f"Error in endfortheouche: {e}") +@database_sync_to_async +def get_name(p): + print(f"in get_name({p})..") + try: + return Player.objects.get(name=p) + except Player.DoesNotExist: + print("get_name() exception") + return None + @database_sync_to_async def create_player( name, diff --git a/requirements.txt b/requirements.txt index ceb5c49..3c91bd0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ channels daphne djangorestframework web3 +asyncpg From d149bb1f616ba84018e43b6f84379f9423acf4a7 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Mon, 26 Aug 2024 15:54:13 +0200 Subject: [PATCH 40/81] modif lala --- makefile | 4 ++-- pong/game/matchmaking.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/makefile b/makefile index eb0143a..36ad556 100644 --- a/makefile +++ b/makefile @@ -22,8 +22,8 @@ down: destroy: $(COMPOSE) down -v --rmi all - #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 :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 logs: $(COMPOSE) logs -f $(CONTAINER) diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 32f9981..7becf72 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -40,7 +40,7 @@ class MatchMaker: await asyncio.sleep(1) self.timer += 1 # Waiting for more than 30s -> BOT game - if self.timer >= 5 and self.waiting_players: + if self.timer >= 15 and self.waiting_players: player1 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs BOT") self.botgame = True @@ -100,4 +100,4 @@ class MatchMaker: match_maker = MatchMaker() # to get what you want use get_player_p_win(player_name) !! (voir utils.py) -# \ No newline at end of file +# From 790c6c276daad82a7018426527d5c776c5683072 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Mon, 26 Aug 2024 17:59:54 +0200 Subject: [PATCH 41/81] before thouch change --- Dockerfile | 2 +- config/logstash.conf | 19 +++++++++++-------- pong/settings.py | 38 +++++++++++++++++++++++++++++++++++++- requirements.txt | 1 + 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 10f5083..42ff94d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ RUN python3 -m venv venv RUN venv/bin/pip3 install --upgrade pip RUN venv/bin/pip3 install --no-cache-dir -r requirements.txt -EXPOSE 80 +EXPOSE 8080 diff --git a/config/logstash.conf b/config/logstash.conf index f8a8a2c..602a7df 100644 --- a/config/logstash.conf +++ b/config/logstash.conf @@ -1,21 +1,24 @@ input { - udp { - host => "0.0.0.0" - port => 5044 + file { + path => "/transcendence/django.log" # Adjust this path to where the log file is stored + start_position => "beginning" + sincedb_path => "/dev/null" + codec => "json" } } -filter {} +filter { +} output { elasticsearch { - index => "logstash-%{+YYYY.MM.dd}" hosts => ["https://es01:9200"] user => "elastic" - password => elastic_pass - ssl_enabled => true + password => "${ELASTIC_PASSWORD}" + ssl_enabled => true ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt" ssl_verification_mode => "full" + index => "django-logs-%{+YYYY.MM.dd}" } - #stdout {} + stdout { codec => rubydebug } # Optional: For debugging purposes } diff --git a/pong/settings.py b/pong/settings.py index 83bd985..6c171ec 100644 --- a/pong/settings.py +++ b/pong/settings.py @@ -6,8 +6,9 @@ Django settings for pong project. Generated by 'django-admin startproject' using Django 3.2. """ -from pathlib import Path import os +import logging.config +from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -134,3 +135,38 @@ CHANNEL_LAYERS = { 'BACKEND': 'channels.layers.InMemoryChannelLayer', }, } + +LOGGING = { + 'version': 1, # The version of the logging configuration schema + 'disable_existing_loggers': False, # Allows existing loggers to keep logging + 'formatters': { # Defines how log messages will be formatted + 'json': { + '()': 'pythonjsonlogger.jsonlogger.JsonFormatter', + # 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. + }, + }, + 'handlers': { # Handlers determine where the log messages are sent + 'file': { + 'level': 'INFO', # Minimum log level to be handled (INFO and above) + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, '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 + }, + }, +} diff --git a/requirements.txt b/requirements.txt index ceb5c49..ac9363c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ channels daphne djangorestframework web3 +python-json-logger==2.0.7 From 9398124ed014a0f598e9de3087e3b0a8fdfa191e Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 27 Aug 2024 15:43:19 +0200 Subject: [PATCH 42/81] still big probleme --- pong/game/utils.py | 160 ++++++++++++++++++++++++++++++++++++++------- pong/settings.py | 17 +++++ 2 files changed, 155 insertions(+), 22 deletions(-) diff --git a/pong/game/utils.py b/pong/game/utils.py index 4dd3dba..ccad1dc 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -9,20 +9,12 @@ from channels.db import database_sync_to_async async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") - if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): - player_1 = await create_player(p1) - print("############# PLAYER DONE") - else: - player_1 = await database_sync_to_async(Player.objects.get)(name=p1) + # Vérification de l'existence des joueurs et création si nécessaire + player_1 = await get_or_create_player(p1) + player_2 = await get_or_create_player(p2) print("ok") - if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): - player_2 = await create_player(p2) - print("############# PLAYER DONE") - else: - player_2 = await database_sync_to_async(Player.objects.get)(name=p2) - print("############# BEFORE MATCH") await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) print("############# AFTER DONE") @@ -33,6 +25,36 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_ except Exception as e: print(f"Error in endfortheouche: {e}") +@database_sync_to_async +def get_player_by_name(name): + print(f"Checking if player '{name}' exists") + exists = Player.objects.filter(name=name).exists() + print(f"Player exists: {exists}") + return exists + + +@database_sync_to_async +def get_player(name): + return Player.objects.get(name=name) + + +async def get_or_create_player(name): + print("here !!") + print(f"Checking existence for player: {name}") + player_exists = await get_player_by_name(name) + print(f"END search in database!! (Player exists: {player_exists})") + if not player_exists: + print("Player does not exist, creating player...") + player = await create_player(name) + print(f"Player created: {player}") + return player + else: + print("Player exists, fetching player...") + player = await get_player(name) + print(f"Player fetched: {player}") + return player + + @database_sync_to_async def create_player( name, @@ -49,8 +71,6 @@ def create_player( num_won_tournaments=0 ): print("create player !!!") - """ if database_sync_to_async(Player.objects.filter(name=name).exists)(): - raise ValueError(f"A player with the name '{name}' already exists.") """ player = Player( name=name, @@ -130,9 +150,9 @@ def update_player_statistics(player_name): return won_matches = Match.objects.filter(winner=player) - """ part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) - part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) - won_tourn = Tournoi.objects.filter(winner=player) """ + #part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) + #part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) + #won_tourn = Tournoi.objects.filter(winner=player) total_score = matches_as_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 @@ -154,10 +174,10 @@ def update_player_statistics(player_name): total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0 m_duration = total_duration / total_match - """ total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() - total_win_tourn = won_tourn.count() - p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 - """ + #total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() + #total_win_tourn = won_tourn.count() + #p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 + best_score_as_player1 = matches_as_player1.aggregate(Max('score_player1'))['score_player1__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) @@ -172,8 +192,8 @@ def update_player_statistics(player_name): player.m_nbr_ball_touch = m_nbr_ball_touch player.total_duration = total_duration player.m_duration = m_duration - """ player.num_participated_tournaments = total_tourn_p - player.num_won_tournaments = total_win_tourn """ + # player.num_participated_tournaments = total_tourn_p + #player.num_won_tournaments = total_win_tourn player.save() print("CHAKU IS THE BEST") @@ -185,4 +205,100 @@ def get_player_p_win(player_name): return player.p_win + + + + + +######## try synchrone version ######## + +""" def endfortheouche_sync(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): + try: + print("here endfortheouche §!!!") + player_1 = get_or_create_player_sync(p1) + player_2 = get_or_create_player_sync(p2) + + print("ok") + + print("############# BEFORE MATCH") + create_match_sync(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) + print("############# AFTER DONE") + + #update_player_statistics_sync(p1) + print("############# END STAT P1") + #update_player_statistics_sync(p2) + except Exception as e: + print(f"Error in endfortheouche: {e}") + +def get_player_sync(name): + print(f"Getting player '{name}'") + return Player.objects.get(name=name) + + +def get_or_create_player_sync(name): + print("here !!") + player_exists = Player.objects.filter(name=name).exists() + print("search in database!!") + if not player_exists: + print(f"Player '{name}' does not exist, creating new player.") + return create_player_sync(name) + else: + print(f"Player '{name}' exists.") + return get_player_sync(name) + +def create_player( + name, + total_match=0, + total_win=0, + p_win= None, + m_score_match= None, + m_score_adv_match= None, + best_score=0, + m_nbr_ball_touch= None, + total_duration= None, + m_duration= None, + num_participated_tournaments=0, + num_won_tournaments=0 +): + print("create player !!!") + player = Player( + name=name, + total_match=total_match, + total_win=total_win, + p_win=p_win, + m_score_match=m_score_match, + m_score_adv_match=m_score_adv_match, + best_score=best_score, + m_nbr_ball_touch=m_nbr_ball_touch, + total_duration=total_duration, + m_duration=m_duration, + num_participated_tournaments=num_participated_tournaments, + num_won_tournaments=num_won_tournaments + ) + player.save() + return player + + +def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi): + match = Match( + player1=player1, + player2=player2, + score_player1=score_player1, + score_player2=score_player2, + nbr_ball_touch_p1=nbr_ball_touch_p1, + nbr_ball_touch_p2=nbr_ball_touch_p2, + duration=duration, + is_tournoi=is_tournoi, + tournoi=tournoi + ) + + if score_player1 > score_player2: + match.winner = match.player1 + elif score_player2 > score_player1: + match.winner = match.player2 + else: + match.winner = None + + match.save() + return match """ diff --git a/pong/settings.py b/pong/settings.py index 83bd985..4d0ffcc 100644 --- a/pong/settings.py +++ b/pong/settings.py @@ -134,3 +134,20 @@ CHANNEL_LAYERS = { 'BACKEND': 'channels.layers.InMemoryChannelLayer', }, } + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'django': { + 'handlers': ['console'], + 'level': 'DEBUG', + }, + }, +} \ No newline at end of file From d5331673661c1d8a584236af0527f601bb08cbba Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 27 Aug 2024 16:02:48 +0200 Subject: [PATCH 43/81] beg epuration --- pong/game/urls.py | 4 ---- pong/game/views.py | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/pong/game/urls.py b/pong/game/urls.py index 7a2a3ef..df150f0 100644 --- a/pong/game/urls.py +++ b/pong/game/urls.py @@ -2,7 +2,6 @@ from django.urls import path, include from . import views -from .views import player_list, tournoi_list, match_list from rest_framework.routers import DefaultRouter from .views import match_list_json, player_list_json, tournoi_list_json @@ -13,9 +12,6 @@ urlpatterns = [ path('register_user/', views.register_user, name='register_user'), path('authenticate_user/', views.authenticate_user, name='authenticate_user'), path('web3/', views.read_data, name='read_data'), - path('players/', player_list, name='player_list'), - path('matches/', match_list, name='match_list'), - path('tournois/', tournoi_list, name='tournoi_list'), path('api/match_list/', match_list_json, name='match_list_json'), path('api/player_list/', player_list_json, name='player_list_json'), path('api/tournoi_list/', tournoi_list_json, name='tournoi_list_json') diff --git a/pong/game/views.py b/pong/game/views.py index e9b0151..8bd8097 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -72,18 +72,6 @@ def get_or_create_token(user): ####################### THEOUCHE PART ############################ -def player_list(request): - players = Player.objects.all() - return render(request, 'pong/player_list.html', {'players': players}) - -def match_list(request): - matches = Match.objects.select_related('player1', 'player2', 'winner', 'tournoi').all() - return render(request, 'pong/match_list.html', {'matches': matches}) - -def tournoi_list(request): - tournois = Tournoi.objects.select_related('winner').all() - return render(request, 'pong/tournoi_list.html', {'tournois': tournois}) - from django.http import JsonResponse def match_list_json(request): From 24cc7c57bc5753547cb5d3912dc53068127e2dc5 Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 27 Aug 2024 16:46:27 +0200 Subject: [PATCH 44/81] prob synchronicite solved git add . --- pong/game/game.py | 4 +- pong/game/templates/pong/match_list.html | 51 -------- pong/game/templates/pong/player_list.html | 53 -------- pong/game/templates/pong/tournoi_list.html | 37 ------ pong/game/utils.py | 139 ++++++++++++++++++--- 5 files changed, 123 insertions(+), 161 deletions(-) delete mode 100644 pong/game/templates/pong/match_list.html delete mode 100644 pong/game/templates/pong/player_list.html delete mode 100644 pong/game/templates/pong/tournoi_list.html diff --git a/pong/game/game.py b/pong/game/game.py index 851f0b3..fd8c25c 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -5,6 +5,8 @@ import asyncio import random from datetime import datetime from .utils import endfortheouche +from asgiref.sync import sync_to_async + class Game: def __init__(self, game_id, player1, player2, localgame): @@ -210,6 +212,6 @@ class Game: if not self.localgame: await self.player2.send(end_message) print("save data") - await endfortheouche(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.bt1, self.bt2, duration, False, None) diff --git a/pong/game/templates/pong/match_list.html b/pong/game/templates/pong/match_list.html deleted file mode 100644 index 72c1315..0000000 --- a/pong/game/templates/pong/match_list.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - Matches List - - -

Matches List

- - - - - - - - - - - - - - - - - - - {% for match in matches %} - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDPlayer 1Player 2Score Player 1Score Player 2WinnerBall Touches Player 1Ball Touches Player 2DurationDateIs TournamentTournament
{{ match.id }}{{ match.player1.name }}{{ match.player2.name }}{{ match.score_player1 }}{{ match.score_player2 }}{{ match.winner.name }}{{ match.nbr_ball_touch_p1 }}{{ match.nbr_ball_touch_p2 }}{{ match.duration }}{{ match.date }}{{ match.is_tournoi }}{{ match.tournoi.name }}
No matches found.
- - diff --git a/pong/game/templates/pong/player_list.html b/pong/game/templates/pong/player_list.html deleted file mode 100644 index b9fbb42..0000000 --- a/pong/game/templates/pong/player_list.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - Players List - - -

Players List

- - - - - - - - - - - - - - - - - - - - {% for player in players %} - - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameTotal MatchesTotal WinsWin PercentageAverage Match ScoreAverage Opponent ScoreBest ScoreAverage Ball TouchesTotal DurationAverage DurationParticipated TournamentsWon Tournaments
{{ player.id }}{{ player.name }}{{ player.total_match }}{{ player.total_win }}{{ player.p_win }}{{ player.m_score_match }}{{ player.m_score_adv_match }}{{ player.best_score }}{{ player.m_nbr_ball_touch }}{{ player.total_duration }}{{ player.m_duration }}{{ player.num_participated_tournaments }}{{ player.num_won_tournaments }}
No players found.
- - diff --git a/pong/game/templates/pong/tournoi_list.html b/pong/game/templates/pong/tournoi_list.html deleted file mode 100644 index e5718f5..0000000 --- a/pong/game/templates/pong/tournoi_list.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Tournaments List - - -

Tournaments List

- - - - - - - - - - - - {% for tournoi in tournois %} - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameNumber of PlayersDateWinner
{{ tournoi.id }}{{ tournoi.name }}{{ tournoi.nbr_player }}{{ tournoi.date }}{{ tournoi.winner.name }}
No tournaments found.
- - diff --git a/pong/game/utils.py b/pong/game/utils.py index ccad1dc..7ef52e9 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -6,7 +6,7 @@ from datetime import timedelta from channels.db import database_sync_to_async #from asgiref.sync import database_sync_to_async -async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): +""" async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") # Vérification de l'existence des joueurs et création si nécessaire @@ -203,7 +203,7 @@ def get_player_p_win(player_name): player = get_object_or_404(Player, name=player_name) # Retourner la valeur de p_win return player.p_win - + """ @@ -211,40 +211,52 @@ def get_player_p_win(player_name): ######## try synchrone version ######## - -""" def endfortheouche_sync(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: print("here endfortheouche §!!!") - player_1 = get_or_create_player_sync(p1) - player_2 = get_or_create_player_sync(p2) + # Vérification de l'existence des joueurs et création si nécessaire + player_1 = get_or_create_player(p1) + player_2 = get_or_create_player(p2) print("ok") print("############# BEFORE MATCH") - create_match_sync(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_sync(p1) + update_player_statistics(p1) print("############# END STAT P1") - #update_player_statistics_sync(p2) + update_player_statistics(p2) except Exception as e: print(f"Error in endfortheouche: {e}") -def get_player_sync(name): - print(f"Getting player '{name}'") +def get_player_by_name(name): + print(f"Checking if player '{name}' exists") + exists = Player.objects.filter(name=name).exists() + print(f"Player exists: {exists}") + return exists + + +def get_player(name): return Player.objects.get(name=name) -def get_or_create_player_sync(name): +def get_or_create_player(name): print("here !!") - player_exists = Player.objects.filter(name=name).exists() - print("search in database!!") + print(f"Checking existence for player: {name}") + player_exists = get_player_by_name(name) + print(f"END search in database!! (Player exists: {player_exists})") if not player_exists: - print(f"Player '{name}' does not exist, creating new player.") - return create_player_sync(name) + print("Player does not exist, creating player...") + player = create_player(name) + print(f"Player created: {player}") + return player else: - print(f"Player '{name}' exists.") - return get_player_sync(name) + print("Player exists, fetching player...") + player = get_player(name) + print(f"Player fetched: {player}") + return player + def create_player( name, @@ -279,6 +291,10 @@ def create_player( player.save() return player +def create_tournoi(name, nbr_player, date, winner): + tournoi = Tournoi(name=name, nbr_player=nbr_player, date=date, winner=winner) + tournoi.save() + return tournoi def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi): match = Match( @@ -301,4 +317,89 @@ def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_ match.winner = None match.save() - return match """ + return match + +def update_player_statistics(player_name): + print("############# BEG STAT P") + 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_player2 = Match.objects.filter(player2=player) + print("############# ACTUALLY, IT'S GOOD") + + # Calculer les statistiques + total_match = matches_as_player1.count() + matches_as_player2.count() + + if total_match == 0: + # Eviter la division par zéro + player.total_match = total_match + player.total_win = 0 + player.p_win = 0 + player.m_score_match = 0 + player.m_score_adv_match = 0 + player.best_score = 0 + player.m_nbr_ball_touch = 0 + player.total_duration = 0 + player.m_duration = 0 + player.num_participated_tournaments = 0 + player.num_won_tournaments = 0 + player.save() + return + + won_matches = Match.objects.filter(winner=player) + #part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) + #part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) + #won_tourn = Tournoi.objects.filter(winner=player) + + total_score = matches_as_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 + total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 + + total_score_adv = matches_as_player1.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 + total_score_adv += matches_as_player2.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 + + total_win = won_matches.count() + p_win = (total_win / total_match) * 100 + + m_score_match = total_score / total_match + m_score_adv_match = total_score_adv / total_match + + nbr_ball_touch = matches_as_player1.aggregate(Sum('nbr_ball_touch_p1'))['nbr_ball_touch_p1__sum'] or 0 + nbr_ball_touch += matches_as_player2.aggregate(Sum('nbr_ball_touch_p2'))['nbr_ball_touch_p2__sum'] or 0 + m_nbr_ball_touch = nbr_ball_touch / total_match + + total_duration = matches_as_player1.aggregate(Sum('duration'))['duration__sum'] or 0 + total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0 + m_duration = total_duration / total_match + + #total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() + #total_win_tourn = won_tourn.count() + #p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 + + best_score_as_player1 = matches_as_player1.aggregate(Max('score_player1'))['score_player1__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) + + # Mettre à jour les champs du joueur + player.total_match = total_match + player.total_win = total_win + player.p_win = p_win + player.m_score_match = m_score_match + player.m_score_adv_match = m_score_adv_match + player.best_score = best_score + player.m_nbr_ball_touch = m_nbr_ball_touch + player.total_duration = total_duration + player.m_duration = m_duration + # player.num_participated_tournaments = total_tourn_p + #player.num_won_tournaments = total_win_tourn + + player.save() + print("CHAKU IS THE BEST") + +def get_player_p_win(player_name): + # Rechercher le joueur par son nom + player = get_object_or_404(Player, name=player_name) + # Retourner la valeur de p_win + return player.p_win + From 909a334a38b88e5ffcedafb2c3fc590f16d15763 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Tue, 27 Aug 2024 16:58:49 +0200 Subject: [PATCH 45/81] adrien fix tout les probleme!!! :) --- logs/django.log | 1 + makefile | 2 +- pong/game/templates/pong/match_list.html | 51 -------- pong/game/templates/pong/player_list.html | 53 -------- pong/game/templates/pong/tournoi_list.html | 37 ------ pong/static/game.js | 140 +++++++++++---------- pong/static/index.html | 64 +--------- 7 files changed, 79 insertions(+), 269 deletions(-) create mode 100644 logs/django.log delete mode 100644 pong/game/templates/pong/match_list.html delete mode 100644 pong/game/templates/pong/player_list.html delete mode 100644 pong/game/templates/pong/tournoi_list.html diff --git a/logs/django.log b/logs/django.log new file mode 100644 index 0000000..81fe80d --- /dev/null +++ b/logs/django.log @@ -0,0 +1 @@ +{"message": "Not Found: /totofaitduvelo", "taskName": null, "status_code": 404, "request": ""} diff --git a/makefile b/makefile index 81d3320..0c6d19d 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ CONTAINER=$(c) up: down $(COMPOSE) build - $(COMPOSE) up $(CONTAINER) || true + $(COMPOSE) up -d $(CONTAINER) || true build: $(COMPOSE) build $(CONTAINER) diff --git a/pong/game/templates/pong/match_list.html b/pong/game/templates/pong/match_list.html deleted file mode 100644 index 72c1315..0000000 --- a/pong/game/templates/pong/match_list.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - Matches List - - -

Matches List

- - - - - - - - - - - - - - - - - - - {% for match in matches %} - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDPlayer 1Player 2Score Player 1Score Player 2WinnerBall Touches Player 1Ball Touches Player 2DurationDateIs TournamentTournament
{{ match.id }}{{ match.player1.name }}{{ match.player2.name }}{{ match.score_player1 }}{{ match.score_player2 }}{{ match.winner.name }}{{ match.nbr_ball_touch_p1 }}{{ match.nbr_ball_touch_p2 }}{{ match.duration }}{{ match.date }}{{ match.is_tournoi }}{{ match.tournoi.name }}
No matches found.
- - diff --git a/pong/game/templates/pong/player_list.html b/pong/game/templates/pong/player_list.html deleted file mode 100644 index b9fbb42..0000000 --- a/pong/game/templates/pong/player_list.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - Players List - - -

Players List

- - - - - - - - - - - - - - - - - - - - {% for player in players %} - - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameTotal MatchesTotal WinsWin PercentageAverage Match ScoreAverage Opponent ScoreBest ScoreAverage Ball TouchesTotal DurationAverage DurationParticipated TournamentsWon Tournaments
{{ player.id }}{{ player.name }}{{ player.total_match }}{{ player.total_win }}{{ player.p_win }}{{ player.m_score_match }}{{ player.m_score_adv_match }}{{ player.best_score }}{{ player.m_nbr_ball_touch }}{{ player.total_duration }}{{ player.m_duration }}{{ player.num_participated_tournaments }}{{ player.num_won_tournaments }}
No players found.
- - diff --git a/pong/game/templates/pong/tournoi_list.html b/pong/game/templates/pong/tournoi_list.html deleted file mode 100644 index e5718f5..0000000 --- a/pong/game/templates/pong/tournoi_list.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Tournaments List - - -

Tournaments List

- - - - - - - - - - - - {% for tournoi in tournois %} - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameNumber of PlayersDateWinner
{{ tournoi.id }}{{ tournoi.name }}{{ tournoi.nbr_player }}{{ tournoi.date }}{{ tournoi.winner.name }}
No tournaments found.
- - diff --git a/pong/static/game.js b/pong/static/game.js index 1a65cdf..799147b 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -557,28 +557,31 @@ document.addEventListener('DOMContentLoaded', () => { const matchListBody = document.querySelector('#match-list tbody'); matchListBody.innerHTML = ''; - if (matches.length === 0) { - console.log('No matches to display'); - } - - matches.forEach(match => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${match.id} - ${match.player1__name} - ${match.player2__name} - ${match.score_player1} - ${match.score_player2} - ${match.winner__name} - ${match.nbr_ball_touch_p1} - ${match.nbr_ball_touch_p2} - ${match.duration} - ${match.date} - ${match.is_tournoi} - ${match.tournoi__name} - `; - matchListBody.appendChild(row); - }); + const row = document.createElement('tr'); + if (matches.length != 0) { + matches.forEach(match => { + row.innerHTML = ` + ${match.id} + ${match.player1__name} + ${match.player2__name} + ${match.score_player1} + ${match.score_player2} + ${match.winner__name} + ${match.nbr_ball_touch_p1} + ${match.nbr_ball_touch_p2} + ${match.duration} + ${match.date} + ${match.is_tournoi} + ${match.tournoi__name} + `; + matchListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + `; + matchListBody.appendChild(row); + } } function displayPlayers(players) { @@ -586,51 +589,58 @@ document.addEventListener('DOMContentLoaded', () => { const playersListBody = document.querySelector('#player-list tbody'); playersListBody.innerHTML = ''; - if (players.length === 0) { - console.log('No players to display'); - } + const row = document.createElement('tr'); + if (players.length != 0) { + players.forEach(player => { + row.innerHTML = ` + ${player.id} + ${player.name} + ${player.total_match} + ${player.total_win} + ${player.p_win} + ${player.m_score_match} + ${player.m_score_adv_match} + ${player.best_score} + ${player.m_nbr_ball_touch} + ${player.total_duration} + ${player.m_duration} + ${player.num_participated_tournaments} + ${player.num_won_tournaments} + `; + playersListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + ` + playersListBody.appendChild(row); + } + } - players.forEach(player => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${player.id} - ${player.name} - ${player.total_match} - ${player.total_win} - ${player.p_win} - ${player.m_score_match} - ${player.m_score_adv_match} - ${player.best_score} - ${player.m_nbr_ball_touch} - ${player.total_duration} - ${player.m_duration} - ${player.num_participated_tournaments} - ${player.num_won_tournaments} - `; - playersListBody.appendChild(row); - }); - } + function displayTournois(tournois) { + console.log('Displaying tournois:'); + const tournoisListBody = document.querySelector('#tournoi-list tbody'); + tournoisListBody.innerHTML = ''; - function displayTournois(tournois) { - console.log('Displaying tournois:'); - const tournoisListBody = document.querySelector('#tournoi-list tbody'); - tournoisListBody.innerHTML = ''; - - if (tournois.length === 0) { - console.log('No tournois to display'); - } - - tournois.forEach(tournoi => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${tournoi.id} - ${tournoi.name} - ${tournoi.nbr_player} - ${tournoi.date} - ${tournoi.winner.name} - `; - tournoisListBody.appendChild(row); - }); + const row = document.createElement('tr'); + if (tournois.length != 0) { + tournois.forEach(tournoi => { + row.innerHTML = ` + ${tournoi.id} + ${tournoi.name} + ${tournoi.nbr_player} + ${tournoi.date} + ${tournoi.winner.name} + `; + tournoisListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + ` + tournoisListBody.appendChild(row); + } + } ////////////////////////////// END BURGER BUTTON //////////////////////////////// diff --git a/pong/static/index.html b/pong/static/index.html index 06dc845..d261bcf 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -144,29 +144,7 @@ - {% if matches %} - {% for match in matches %} - - {{ match.id }} - {{ match.player1.name }} - {{ match.player2.name }} - {{ match.score_player1 }} - {{ match.score_player2 }} - {{ match.winner.name }} - {{ match.nbr_ball_touch_p1 }} - {{ match.nbr_ball_touch_p2 }} - {{ match.duration }} - {{ match.date }} - {{ match.is_tournoi }} - {{ match.tournoi.name }} - - {% endfor %} - {% else %} - - No matches found. - - {% endif %} - +
@@ -191,30 +169,7 @@ - {% if players %} - {% for player in players %} - - {{ player.id }} - {{ player.name }} - {{ player.total_match }} - {{ player.total_win }} - {{ player.p_win }} - {{ player.m_score_match }} - {{ player.m_score_adv_match }} - {{ player.best_score }} - {{ player.m_nbr_ball_touch }} - {{ player.total_duration }} - {{ player.m_duration }} - {{ player.num_participated_tournaments }} - {{ player.num_won_tournaments }} - - {% endfor %} - {% else %} - - No players found. - - {% endif %} - + @@ -231,21 +186,6 @@ - {% if tournois %} - {% for tournoi in tournois %} - - {{ tournoi.id }} - {{ tournoi.name }} - {{ tournoi.nbr_player }} - {{ tournoi.date }} - {{ tournoi.winner.name }} - - {% endfor %} - {% else %} - - No tournois found. - - {% endif %} From e5e8fdc6733d540f578c39e037c76d4d8576606e Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 27 Aug 2024 17:24:40 +0200 Subject: [PATCH 46/81] merge avec adrien --- logs/django.log | 1 + 1 file changed, 1 insertion(+) diff --git a/logs/django.log b/logs/django.log index 81fe80d..48f0c29 100644 --- a/logs/django.log +++ b/logs/django.log @@ -1 +1,2 @@ {"message": "Not Found: /totofaitduvelo", "taskName": null, "status_code": 404, "request": ""} +{"message": "Not Found: /favicon.ico", "taskName": null, "status_code": 404, "request": ""} From 2a4aef62b205d3ff9961dcd20e87cc53dcebae4f Mon Sep 17 00:00:00 2001 From: Theouche Date: Tue, 27 Aug 2024 18:19:36 +0200 Subject: [PATCH 47/81] theouche --- pong/game/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pong/game/utils.py b/pong/game/utils.py index 7ef52e9..95e8c38 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -213,7 +213,8 @@ def get_player_p_win(player_name): ######## try synchrone version ######## def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: - print("here endfortheouche §!!!") + 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_2 = get_or_create_player(p2) From 4d257e2c5892559280bdb0509d24d89f9edb1af7 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Tue, 27 Aug 2024 18:42:28 +0200 Subject: [PATCH 48/81] fix diplsay dashboard --- pong/static/game.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pong/static/game.js b/pong/static/game.js index 799147b..6305385 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -557,9 +557,9 @@ document.addEventListener('DOMContentLoaded', () => { const matchListBody = document.querySelector('#match-list tbody'); matchListBody.innerHTML = ''; - const row = document.createElement('tr'); if (matches.length != 0) { matches.forEach(match => { + const row = document.createElement('tr'); row.innerHTML = ` ${match.id} ${match.player1__name} @@ -589,9 +589,9 @@ document.addEventListener('DOMContentLoaded', () => { const playersListBody = document.querySelector('#player-list tbody'); playersListBody.innerHTML = ''; - const row = document.createElement('tr'); if (players.length != 0) { players.forEach(player => { + const row = document.createElement('tr'); row.innerHTML = ` ${player.id} ${player.name} @@ -622,9 +622,9 @@ document.addEventListener('DOMContentLoaded', () => { const tournoisListBody = document.querySelector('#tournoi-list tbody'); tournoisListBody.innerHTML = ''; - const row = document.createElement('tr'); if (tournois.length != 0) { tournois.forEach(tournoi => { + const row = document.createElement('tr'); row.innerHTML = ` ${tournoi.id} ${tournoi.name} From 7a5f572f77a64ecaa3c8e70ec468805cd3a050c1 Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Tue, 27 Aug 2024 18:43:46 +0200 Subject: [PATCH 49/81] remove django.log --- logs/django.log | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 logs/django.log diff --git a/logs/django.log b/logs/django.log deleted file mode 100644 index 48f0c29..0000000 --- a/logs/django.log +++ /dev/null @@ -1,2 +0,0 @@ -{"message": "Not Found: /totofaitduvelo", "taskName": null, "status_code": 404, "request": ""} -{"message": "Not Found: /favicon.ico", "taskName": null, "status_code": 404, "request": ""} From 90c8cb49c2fd41ac3b1b54d4cad6762b5b54dbbf Mon Sep 17 00:00:00 2001 From: Adrien Audebert Date: Tue, 27 Aug 2024 18:44:28 +0200 Subject: [PATCH 50/81] modif gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bc4f360..a8727e7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ __pycache__/ data/ .env makefile +logs/django.log From 697d8b5d0f14793936867911842cb7ad28630941 Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Tue, 27 Aug 2024 18:46:56 +0200 Subject: [PATCH 51/81] starting the tournament code --- pong/game/consumers.py | 18 +++++++ pong/game/game.py | 25 ++++++---- pong/game/matchmaking.py | 3 -- .../pong/tournament_waiting_room.html | 10 ++++ pong/game/tournament.py | 36 +++++++++++++ pong/static/game.js | 50 +++++++++---------- pong/static/index.html | 4 +- pong/static/styles.css | 19 +++---- requirements.txt | 4 +- 9 files changed, 116 insertions(+), 53 deletions(-) create mode 100644 pong/game/templates/pong/tournament_waiting_room.html create mode 100644 pong/game/tournament.py diff --git a/pong/game/consumers.py b/pong/game/consumers.py index e3d68a1..a5e3853 100644 --- a/pong/game/consumers.py +++ b/pong/game/consumers.py @@ -5,6 +5,7 @@ from channels.generic.websocket import AsyncWebsocketConsumer from django.contrib.auth.models import User from channels.db import database_sync_to_async from .matchmaking import match_maker +from .tournament import tournament_match_maker class GameConsumer(AsyncWebsocketConsumer): async def connect(self): @@ -18,6 +19,8 @@ class GameConsumer(AsyncWebsocketConsumer): await self.authenticate(data['token']) elif data['type'] == 'authenticate2': await self.authenticate2(data['token_1'], data['token_2']) + elif data['type'] == 'authenticate3': + await self.authenticate3(data['token']) elif data['type'] == 'key_press': if self.game: await self.game.handle_key_press(self, data['key']) @@ -74,10 +77,25 @@ class GameConsumer(AsyncWebsocketConsumer): except User.DoesNotExist: 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): if self.game: await self.game.end_game(disconnected_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") async def set_game(self, game): diff --git a/pong/game/game.py b/pong/game/game.py index 2baeae2..4708878 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -22,7 +22,8 @@ class Game: 'ball_position': {'x': 390, 'y': 190}, 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, 'player1_score': 0, - 'player2_score': 0 + 'player2_score': 0, + 'game_text': '' } else: self.botgame = player2 is None @@ -34,7 +35,8 @@ class Game: 'ball_position': {'x': 390, 'y': 190}, 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, 'player1_score': 0, - 'player2_score': 0 + 'player2_score': 0, + 'game-text': '' } self.speed = 1 self.game_loop_task = None @@ -53,9 +55,13 @@ class Game: async def game_loop(self): print(" In the game loop..") + x = 0 while not self.ended: 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.update_game_state() await self.send_game_state() @@ -66,9 +72,9 @@ class Game: if self.game_state['player2_position'] < target_y < self.game_state['player2_position'] + 80: pass 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: - 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): if self.ended: @@ -92,21 +98,18 @@ class Game: self.game_state['ball_velocity']['x'] *= -1 self.bt2 += 1 self.update_ball_velocity() - # Check for scoring - #print(f"########### score user 1 {self.game_state['player1_score']} ###########") - #print(f"§§§§§§§§§§§ score user 2 {self.game_state['player2_score']} §§§§§§§§§§§") - + # Check if some player won the game if self.game_state['ball_position']['x'] <= 10: self.game_state['player2_score'] += 1 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.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 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.end_game() self.reset_ball() diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 9d20580..5ca454c 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -110,6 +110,3 @@ class MatchMaker: # Instance of the class match_maker = MatchMaker() - -# to get what you want use get_player_p_win(player_name) !! (voir utils.py) -# \ No newline at end of file diff --git a/pong/game/templates/pong/tournament_waiting_room.html b/pong/game/templates/pong/tournament_waiting_room.html new file mode 100644 index 0000000..dc09859 --- /dev/null +++ b/pong/game/templates/pong/tournament_waiting_room.html @@ -0,0 +1,10 @@ + +
+

Tournament Waiting Room

+

Players currently waiting: {{ players|length }}

+
    + {% for player in players %} +
  • {{ player }}
  • + {% endfor %} +
+
\ No newline at end of file diff --git a/pong/game/tournament.py b/pong/game/tournament.py new file mode 100644 index 0000000..60dd111 --- /dev/null +++ b/pong/game/tournament.py @@ -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() \ No newline at end of file diff --git a/pong/static/game.js b/pong/static/game.js index 1a65cdf..6eb7096 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -28,6 +28,7 @@ document.addEventListener('DOMContentLoaded', () => { const loginButton2 = document.getElementById('login2'); const gameContainer = document.getElementById('game1'); + const tournamentContainer = document.getElementById('tournament-bracket'); const menuButton = document.querySelector('.burger-menu'); const dropdownMenu = document.getElementById('dropdown-menu'); @@ -351,7 +352,12 @@ document.addEventListener('DOMContentLoaded', () => { } 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) { @@ -360,11 +366,14 @@ document.addEventListener('DOMContentLoaded', () => { socket.onopen = function (event) { console.log('WebSocket connection established'); 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 })); - } else { - console.log("Sending tokens for 2 player game"); + } else if (players === 2) { + console.log("Sending tokens for a local game"); 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'); } else if (data.type === 'game_start') { 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') { updateGameState(data.game_state); } else if (data.type === 'player_disconnected') { @@ -385,6 +394,8 @@ document.addEventListener('DOMContentLoaded', () => { console.log("Game ended:", data.game_id); } else if (data.type === 'error') { console.error(data.message); + } else if (data.type === 'update_waiting_room') { + document.getElementById('tournament-bracket').innerHTML = data.html; } else { 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) { if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'w' || event.key === 's') { //console.log('Key press: ', event.key); @@ -427,24 +430,21 @@ document.addEventListener('DOMContentLoaded', () => { } function renderGame() { - const player1Pad = document.getElementById('player1-pad'); - player1Pad.style.top = `${gameState.player1_position}px`; + document.getElementById('player1-name').textContent = `${gameState.player1_name}`; + document.getElementById('player2-name').textContent = `${gameState.player2_name}`; - const player2Pad = document.getElementById('player2-pad'); - player2Pad.style.top = `${gameState.player2_position}px`; + document.getElementById('player1-pad').style.top = `${gameState.player1_position}px`; + document.getElementById('player2-pad').style.top = `${gameState.player2_position}px`; - const ball = document.getElementById('ball'); - ball.style.left = `${gameState.ball_position.x}px`; - ball.style.top = `${gameState.ball_position.y}px`; + document.getElementById('ball').style.left = `${gameState.ball_position.x}px`; + document.getElementById('ball').style.top = `${gameState.ball_position.y}px`; - const player1Score = document.getElementById('player1-score'); - player1Score.textContent = gameState.player1_score; + document.getElementById('player1-score').textContent = gameState.player1_score; + document.getElementById('player2-score').textContent = gameState.player2_score; - const player2Score = document.getElementById('player2-score'); - player2Score.textContent = gameState.player2_score; + document.getElementById('game-text').textContent = gameState.game_text; } - ////////////////////////////// BEG BURGER BUTTON //////////////////////////////// menuButton.addEventListener('click', toggleMenu); diff --git a/pong/static/index.html b/pong/static/index.html index 63f1278..7731712 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -111,8 +111,9 @@ + + diff --git a/pong/static/styles.css b/pong/static/styles.css index 450ac4e..4103df0 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -59,20 +59,10 @@ button:hover { align-items: center; } -.game-code { - font-size: 24px; - position: absolute; - top: 10px; -} - -#gameCode { - left: 10px; -} - .name { font-size: 24px; position: absolute; - top: 30px; + top: 20px; } #player1-name { @@ -144,6 +134,13 @@ button:hover { position: absolute; } +#game-text { + font-size: 64px; + color: #00ffff; + position: absolute; + top: 150px; +} + .logo { position: absolute; top: 20px; diff --git a/requirements.txt b/requirements.txt index 3c91bd0..54b2e96 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -Django +django psycopg2 python-dotenv channels daphne djangorestframework web3 -asyncpg +asyncpg \ No newline at end of file From dcab0489b9baacef340f595e2149c2a214849159 Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Tue, 27 Aug 2024 19:09:11 +0200 Subject: [PATCH 52/81] merging with theouche and adrien ok --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 0c6d19d..e795e69 100644 --- a/makefile +++ b/makefile @@ -32,7 +32,7 @@ ps: db-shell: $(COMPOSE) exec db psql -U 42student players_db -re: destroy down up +re: destroy up help: @echo "Usage:" From c9e806897f26d63ca6e5e2612b942bbb30625688 Mon Sep 17 00:00:00 2001 From: estellon Date: Tue, 27 Aug 2024 21:30:18 +0200 Subject: [PATCH 53/81] css tournament --- pong/static/styles.css | 67 ++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/pong/static/styles.css b/pong/static/styles.css index 4103df0..61748ff 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -260,9 +260,9 @@ button:hover { .navbar { - position: absolute; - top: 30px; - right: 10px; + position: absolute; + top: 30px; + right: 10px; padding: 10px; } @@ -270,28 +270,28 @@ button:hover { font-size: 24px; background: none; border: none; - color: #00ffff; + color: #00ffff; cursor: pointer; transition: color 0.3s ease; } .burger-menu:hover { - color: #ffffff; + color: #ffffff; } .dropdown-content { display: none; position: absolute; - top: 100%; - right: 0; - margin-top: 10px; - background-color: #1a1a2e; - color: #ffffff; + top: 100%; + right: 0; + margin-top: 10px; + background-color: #1a1a2e; + color: #ffffff; box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.3); border-radius: 5px; z-index: 1; - width: max-content; + width: max-content; } .dropdown-content.show { @@ -300,18 +300,18 @@ button:hover { .dropdown-content a { - color: #ffffff; + color: #ffffff; padding: 12px 16px; text-decoration: none; display: block; - border-bottom: 1px solid rgba(255, 255, 255, 0.2); - transition: background-color 0.3s ease; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + transition: background-color 0.3s ease; } .dropdown-content a:hover { - background-color: #333; - color: #00ffff; + background-color: #333; + color: #00ffff; } .language-switcher { @@ -371,8 +371,8 @@ button:hover { width: 100%; height: 100%; overflow: auto; - background-color: rgb(0,0,0); - background-color: rgba(0,0,0,0.4); + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.4); padding-top: 60px; } @@ -403,4 +403,35 @@ button:hover { pre { white-space: pre-wrap; word-wrap: break-word; +} + +.tournament-waiting-room { + background-color: rgba(0, 0, 0, 0.6); + padding: 20px; + border-radius: 15px; + color: #00ffff; + width: 50%; + margin: auto; + text-align: center; + box-shadow: 0 0 30px #00ffff, inset 0 0 20px #00ffff; + +} + +.tournament-waiting-room h2 { + font-family: 'Arial', sans-serif; + font-size: 2em; + margin-bottom: 15px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7); +} + +.tournament-waiting-room p { + font-family: 'Verdana', sans-serif; + font-size: 1.2em; + margin-bottom: 20px; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6); +} + +.tournament-waiting-room ul { + list-style-type: none; + padding: 0; } \ No newline at end of file From 4129f927a8382be68f5db1f95fa3993e003027a9 Mon Sep 17 00:00:00 2001 From: Theouche Date: Wed, 28 Aug 2024 15:21:50 +0200 Subject: [PATCH 54/81] add research bar --- pong/game/game.py | 36 +++++-- pong/game/utils.py | 206 +---------------------------------------- pong/static/game.js | 86 ++++++++++++----- pong/static/index.html | 3 + 4 files changed, 94 insertions(+), 237 deletions(-) diff --git a/pong/game/game.py b/pong/game/game.py index 17f796f..7bd34d7 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -70,13 +70,35 @@ class Game: await asyncio.sleep(1/60) # Around 60 FPS async def update_bot_position(self): - target_y = self.game_state['ball_position']['y'] - if self.game_state['player2_position'] < target_y < self.game_state['player2_position'] + 80: - pass - elif self.game_state['player2_position'] < target_y: - self.game_state['player2_position'] = min(self.game_state['player2_position'] + (50 * self.speed), 300) - elif self.game_state['player2_position'] + 80 > target_y: - self.game_state['player2_position'] = max(self.game_state['player2_position'] - (50 * self.speed), 0) + future_ball_position = self.predict_ball_trajectory() + + target_y = future_ball_position['y'] + player2_position = self.game_state['player2_position'] + + # Ajuste la position du bot en fonction de la position prévue de la balle + if player2_position < target_y < player2_position + 80: + pass # Pas besoin de bouger, le bot est déjà bien placé + elif player2_position < target_y: + self.game_state['player2_position'] = min(player2_position + (50 * self.speed), 300) + elif player2_position + 80 > target_y: + self.game_state['player2_position'] = max(player2_position - (50 * self.speed), 0) + + def predict_ball_trajectory(self, steps=60): + + future_x = self.game_state['ball_position']['x'] + future_y = self.game_state['ball_position']['y'] + velocity_x = self.game_state['ball_velocity']['x'] + velocity_y = self.game_state['ball_velocity']['y'] + + for _ in range(steps): + future_x += velocity_x + future_y += velocity_y + + # Gérer les rebonds sur les murs + if future_y <= 0 or future_y >= 300: + velocity_y = -velocity_y # Inverser la direction du mouvement vertical + + return {'x': future_x, 'y': future_y} async def update_game_state(self): if self.ended: diff --git a/pong/game/utils.py b/pong/game/utils.py index fc31941..099ced4 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -6,211 +6,6 @@ from datetime import timedelta from channels.db import database_sync_to_async #from asgiref.sync import database_sync_to_async -""" async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): - try: - print("here endfortheouche §!!!") - # Vérification de l'existence des joueurs et création si nécessaire - player_1 = await get_or_create_player(p1) - player_2 = await get_or_create_player(p2) - - print("ok") - - print("############# BEFORE MATCH") - await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) - print("############# AFTER DONE") - - await update_player_statistics(p1) - print("############# END STAT P1") - await update_player_statistics(p2) - print("############# END STAT P2") - except Exception as e: - print(f"Error in endfortheouche: {e}") - -@database_sync_to_async -def get_player_by_name(name): - print(f"Checking if player '{name}' exists") - exists = Player.objects.filter(name=name).exists() - print(f"Player exists: {exists}") - return exists - - -@database_sync_to_async -def get_player(name): - return Player.objects.get(name=name) - - -async def get_or_create_player(name): - print("here !!") - print(f"Checking existence for player: {name}") - player_exists = await get_player_by_name(name) - print(f"END search in database!! (Player exists: {player_exists})") - if not player_exists: - print("Player does not exist, creating player...") - player = await create_player(name) - print(f"Player created: {player}") - return player - else: - print("Player exists, fetching player...") - player = await get_player(name) - print(f"Player fetched: {player}") - return player - - -@database_sync_to_async -def create_player( - name, - total_match=0, - total_win=0, - p_win= None, - m_score_match= None, - m_score_adv_match= None, - best_score=0, - m_nbr_ball_touch= None, - total_duration= None, - m_duration= None, - num_participated_tournaments=0, - num_won_tournaments=0 -): - print("create player !!!") - - player = Player( - name=name, - total_match=total_match, - total_win=total_win, - p_win=p_win, - m_score_match=m_score_match, - m_score_adv_match=m_score_adv_match, - best_score=best_score, - m_nbr_ball_touch=m_nbr_ball_touch, - total_duration=total_duration, - m_duration=m_duration, - num_participated_tournaments=num_participated_tournaments, - num_won_tournaments=num_won_tournaments - ) - player.save() - return player - -@database_sync_to_async -def create_tournoi(name, nbr_player, date, winner): - tournoi = Tournoi(name=name, nbr_player=nbr_player, date=date, winner=winner) - tournoi.save() - return tournoi - -@database_sync_to_async -def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi): - match = Match( - player1=player1, - player2=player2, - score_player1=score_player1, - score_player2=score_player2, - nbr_ball_touch_p1=nbr_ball_touch_p1, - nbr_ball_touch_p2=nbr_ball_touch_p2, - duration=duration, - is_tournoi=is_tournoi, - tournoi=tournoi - ) - - if score_player1 > score_player2: - match.winner = match.player1 - elif score_player2 > score_player1: - match.winner = match.player2 - else: - match.winner = None - - match.save() - return match - -@database_sync_to_async -def update_player_statistics(player_name): - print("############# BEG STAT P") - 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_player2 = Match.objects.filter(player2=player) - print("############# ACTUALLY, IT'S GOOD") - - # Calculer les statistiques - total_match = matches_as_player1.count() + matches_as_player2.count() - - if total_match == 0: - # Eviter la division par zéro - player.total_match = total_match - player.total_win = 0 - player.p_win = 0 - player.m_score_match = 0 - player.m_score_adv_match = 0 - player.best_score = 0 - player.m_nbr_ball_touch = 0 - player.total_duration = 0 - player.m_duration = 0 - player.num_participated_tournaments = 0 - player.num_won_tournaments = 0 - player.save() - return - - won_matches = Match.objects.filter(winner=player) - #part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) - #part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) - #won_tourn = Tournoi.objects.filter(winner=player) - - total_score = matches_as_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 - total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 - - total_score_adv = matches_as_player1.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 - total_score_adv += matches_as_player2.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 - - total_win = won_matches.count() - p_win = (total_win / total_match) * 100 - - m_score_match = total_score / total_match - m_score_adv_match = total_score_adv / total_match - - nbr_ball_touch = matches_as_player1.aggregate(Sum('nbr_ball_touch_p1'))['nbr_ball_touch_p1__sum'] or 0 - nbr_ball_touch += matches_as_player2.aggregate(Sum('nbr_ball_touch_p2'))['nbr_ball_touch_p2__sum'] or 0 - m_nbr_ball_touch = nbr_ball_touch / total_match - - total_duration = matches_as_player1.aggregate(Sum('duration'))['duration__sum'] or 0 - total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0 - m_duration = total_duration / total_match - - #total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() - #total_win_tourn = won_tourn.count() - #p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 - - best_score_as_player1 = matches_as_player1.aggregate(Max('score_player1'))['score_player1__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) - - # Mettre à jour les champs du joueur - player.total_match = total_match - player.total_win = total_win - player.p_win = p_win - player.m_score_match = m_score_match - player.m_score_adv_match = m_score_adv_match - player.best_score = best_score - player.m_nbr_ball_touch = m_nbr_ball_touch - player.total_duration = total_duration - player.m_duration = m_duration - # player.num_participated_tournaments = total_tourn_p - #player.num_won_tournaments = total_win_tourn - - player.save() - print("CHAKU IS THE BEST") - -def get_player_p_win(player_name): - # Rechercher le joueur par son nom - player = get_object_or_404(Player, name=player_name) - # Retourner la valeur de p_win - return player.p_win - """ - - - - - - ######## try synchrone version ######## def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: @@ -229,6 +24,7 @@ def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tourna update_player_statistics(p1) print("############# END STAT P1") update_player_statistics(p2) + except Exception as e: print(f"Error in endfortheouche: {e}") diff --git a/pong/static/game.js b/pong/static/game.js index 08efa26..df93785 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -45,11 +45,6 @@ document.addEventListener('DOMContentLoaded', () => { const quickMatchButton = document.getElementById('quick-match'); const tournamentButton = document.getElementById('tournament'); - /* const modal = document.getElementById("myModal"); - const btn = document.getElementById("myBtn"); - const span = document.getElementsByClassName("close")[0]; - const jsonContent = document.getElementById("jsonContent"); */ - let socket; let token; let gameState; @@ -646,6 +641,67 @@ document.addEventListener('DOMContentLoaded', () => { ////////////////////////////// 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'); @@ -662,26 +718,6 @@ document.addEventListener('DOMContentLoaded', () => { ////////////////////////////// END STARS //////////////////////////////// - - /* btn.onclick = function() { - fetch('/web3/') - .then(response => response.json()) - .then(data => { - console.log('ok here !!'); - jsonContent.textContent = JSON.stringify(data, null, 2); - modal.style.display = "block"; - }); - } - - span.onclick = function() { - modal.style.display = "none"; - } - - window.onclick = function(event) { - if (event.target == modal) { - modal.style.display = "none"; - } - } */ ////////////////////////////// BEG LANGAGE //////////////////////////////// const translations = { diff --git a/pong/static/index.html b/pong/static/index.html index 426cc25..ed10b9d 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -128,6 +128,8 @@ + + + + diff --git a/pong/static/styles.css b/pong/static/styles.css index 6e601bc..36bd2dd 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -11,7 +11,7 @@ html { align-items: center; justify-content: center; height: 100%; - overflow: hidden; + overflow: auto; } @@ -255,6 +255,7 @@ button:hover { position: relative; z-index: 10; max-width: 80%; + overflow: auto; } @@ -439,4 +440,10 @@ body { color: rgb(0, 255, 255); /* Valeur par défaut */ font-family: Arial, sans-serif; font-size: 16px; +} + +canvas { + max-width: 100%; + height: auto; + margin-top: 20px; } \ No newline at end of file From dccbfd1601e65b3396fbbfabe37190e07b7c7e13 Mon Sep 17 00:00:00 2001 From: Theouche Date: Fri, 30 Aug 2024 15:41:59 +0200 Subject: [PATCH 57/81] logo hide when graph shown --- pong/static/burger.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pong/static/burger.js b/pong/static/burger.js index fc66d94..a98343c 100644 --- a/pong/static/burger.js +++ b/pong/static/burger.js @@ -27,6 +27,7 @@ document.addEventListener('DOMContentLoaded', () => { if (matchList) matchList.style.display = 'none'; if (tournoiList) tournoiList.style.display = 'none'; if (blockchainList) blockchainList.style.display = 'none'; + logo.style.display = 'block'; } const links = document.querySelectorAll('#dropdown-menu a'); @@ -41,7 +42,7 @@ document.addEventListener('DOMContentLoaded', () => { function showTable(tableId) { hideAllTables(); - + logo.style.display = 'none'; if (tableId === 'player-list') { playerList.style.display = 'block'; From c0634938a6fbc66dfe51c4688eaa454c3213b081 Mon Sep 17 00:00:00 2001 From: Theouche Date: Fri, 30 Aug 2024 18:23:04 +0200 Subject: [PATCH 58/81] bouton fonctionne --- pong/static/game.js | 60 ++++++++++++++++++++++++++++++++++++++++++ pong/static/index.html | 5 ++++ pong/static/styles.css | 26 ++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/pong/static/game.js b/pong/static/game.js index 0d6fe1b..f4e7216 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -33,6 +33,7 @@ document.addEventListener('DOMContentLoaded', () => { const pongElements = document.getElementById('pong-elements'); const logo = document.querySelector('.logo'); + const postFormButtons = document.getElementById('post-form-buttons'); const localGameButton = document.getElementById('local-game'); const quickMatchButton = document.getElementById('quick-match'); const tournamentButton = document.getElementById('tournament'); @@ -40,6 +41,7 @@ document.addEventListener('DOMContentLoaded', () => { let socket; let token; let gameState; + let saveData = null; // Auto-focus and key handling for AUTH-FORM nicknameInput.focus(); @@ -66,6 +68,7 @@ document.addEventListener('DOMContentLoaded', () => { async function handleCheckNickname() { const nickname = nicknameInput.value.trim(); if (nickname) { + window.firstPlayerName = nickname; try { const exists = await checkUserExists(nickname); if (exists) { @@ -316,6 +319,13 @@ document.addEventListener('DOMContentLoaded', () => { } function startLocalGame2() { + nickname = nicknameInput.value.trim(); + nickname2 = nicknameInput2.value.trim(); + saveData = { + type: 'local', + player1_name: nickname, + player2_name: nickname2 + }; gameContainer.style.display = 'flex'; logo.style.display = 'none'; pongElements.style.display = 'none'; @@ -324,10 +334,19 @@ document.addEventListener('DOMContentLoaded', () => { } function startQuickMatch() { + saveData = { + type: 'quick' + } gameContainer.style.display = 'flex'; logo.style.display = 'none'; pongElements.style.display = 'none'; formBlock.style.display = 'none'; + document.getElementById('player1-name').textContent = "player 1"; + document.getElementById('player2-name').textContent = "player 2"; + document.getElementById('game-text').textContent = ""; + document.getElementById('player1-score').textContent = 0; + document.getElementById('player2-score').textContent = 0; + startWebSocketConnection(token, 1); } @@ -404,6 +423,7 @@ document.addEventListener('DOMContentLoaded', () => { function updateGameState(newState) { gameState = newState; renderGame(); + checkForWinner(); } function renderGame() { @@ -434,4 +454,44 @@ document.addEventListener('DOMContentLoaded', () => { starsContainer.appendChild(star); } + const homeButton = document.getElementById('home'); + const replayButton = document.getElementById('retry'); + const gameControls = document.getElementById('game-controls'); + + homeButton.addEventListener('click', () => { + gameContainer.style.display = 'none'; + gameControls.style.display = 'none'; + + logo.style.display = 'block' + + formBlock.style.display = 'block'; + postFormButtons.style.display = 'flex'; + + setupFirstPlayer(); + }); + + function setupFirstPlayer() { + const firstPlayerName = window.firstPlayerName; + document.getElementById('player1-name').textContent = firstPlayerName; + } + + replayButton.addEventListener('click', () => { + document.getElementById('player1-name').textContent = saveData.player1_name; + document.getElementById('player2-name').textContent = saveData.player2_name; + startLocalGame2(); + }); + + + function checkForWinner() { + if (gameState.player1_score === 3 || gameState.player2_score === 3) { + gameControls.style.display = 'flex'; + homeButton.style.display = 'block'; + replayButton.style.display = 'none'; + console.log(saveData.type); + if (saveData.type === 'local'){ + replayButton.style.display = 'block'; + } + } + } + }); diff --git a/pong/static/index.html b/pong/static/index.html index 763222e..0cf0b7f 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -104,6 +104,11 @@ + +