Site
- Add responsive : - Lobby page - Fix bug profil/login/settings'
This commit is contained in:
@ -12,7 +12,7 @@ RUN apt install -y python3.12 postgresql-client
|
|||||||
RUN curl https://bootstrap.pypa.io/get-pip.py -o /root/get-pip.py
|
RUN curl https://bootstrap.pypa.io/get-pip.py -o /root/get-pip.py
|
||||||
RUN python3.12 /root/get-pip.py
|
RUN python3.12 /root/get-pip.py
|
||||||
|
|
||||||
RUN pip3 install requests django psycopg "channels[daphne]"
|
RUN pip3 install requests django psycopg "channels[daphne]" multimethod
|
||||||
|
|
||||||
ARG DB_HOST
|
ARG DB_HOST
|
||||||
ARG DB_NAME
|
ARG DB_NAME
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# Bot.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/05 03:54:20 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 03:55:31 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
class Bot(Player):
|
||||||
|
def __init__(self):
|
||||||
|
print("I am a bot boop boop beep boop")
|
@ -6,11 +6,12 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
|
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/03 23:54:53 by tomoron ### ########.fr #
|
# Updated: 2024/10/05 03:50:25 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
|
from .Player import Player
|
||||||
from .models import GameResults, User
|
from .models import GameResults, User
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
@ -64,33 +65,22 @@ class Game:
|
|||||||
maxScore = 5
|
maxScore = 5
|
||||||
|
|
||||||
def __init__(self, socket, withBot, skinId = 0, opponent = None):
|
def __init__(self, socket, withBot, skinId = 0, opponent = None):
|
||||||
self.p1 = None
|
self.p1 = Player()
|
||||||
self.p2 = None
|
self.p2 = Player()
|
||||||
self.p1Ready = False
|
|
||||||
self.p2Ready = False
|
|
||||||
self.bot = withBot
|
|
||||||
self.started = False
|
self.started = False
|
||||||
self.end = False
|
self.end = False
|
||||||
self.left = None
|
self.left = None
|
||||||
self.winner = None
|
self.winner = None
|
||||||
self.gameStart = 0
|
self.gameStart = 0
|
||||||
self.expSleepTime = 0
|
|
||||||
|
|
||||||
self.p1Pos = {"pos":0, "up": False}
|
|
||||||
self.p2Pos = {"pos":0, "up": False}
|
|
||||||
|
|
||||||
self.ballPos = {"pos":(0, 0), "up": False}
|
self.ballPos = {"pos":(0, 0), "up": False}
|
||||||
|
self.ballVel = (0, 0)
|
||||||
self.speed = Game.startSpeed
|
self.speed = Game.startSpeed
|
||||||
self.ballVel = (self.speed, 0)
|
|
||||||
self.score = [0, 0]
|
self.score = [0, 0]
|
||||||
self.obstacles = []
|
self.obstacles = []
|
||||||
self.lastWin = 2
|
self.lastWin = 2
|
||||||
|
|
||||||
self.p1Skin = 0
|
|
||||||
self.p2Skin = 0
|
|
||||||
|
|
||||||
self.opponentLock = opponent
|
self.opponentLock = opponent
|
||||||
|
|
||||||
if(withBot):
|
if(withBot):
|
||||||
self.join(socket, skinId)
|
self.join(socket, skinId)
|
||||||
elif(opponent != None):
|
elif(opponent != None):
|
||||||
@ -138,40 +128,40 @@ class Game:
|
|||||||
else:
|
else:
|
||||||
self.obstacles.append(Game.jumpersPos[i + 1])
|
self.obstacles.append(Game.jumpersPos[i + 1])
|
||||||
|
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
self.p1.socket.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
||||||
self.obstaclesInvLength()
|
self.obstaclesInvLength()
|
||||||
self.p2.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
self.p2.socket.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
||||||
self.obstaclesInvLength()
|
self.obstaclesInvLength()
|
||||||
|
|
||||||
def join(self, socket, skin = 0):
|
def join(self, socket, skin = 0):
|
||||||
try:
|
try:
|
||||||
if(self.p1 == None):
|
if(self.p1.socket == None):
|
||||||
print("game created, set as player 1")
|
print("game created, set as player 1")
|
||||||
self.p1 = socket
|
self.p1.socket = socket
|
||||||
self.p1Skin = skin
|
self.p1.skin = skin
|
||||||
else:
|
else:
|
||||||
if(self.opponentLock != None and self.opponentLock != socket.id):
|
if(self.opponentLock != None and self.opponentLock != socket.id):
|
||||||
socket.sendError("You are not invited to this game", 9103)
|
socket.sendError("You are not invited to this game", 9103)
|
||||||
return;
|
return;
|
||||||
print("joined game, set as player 2")
|
print("joined game, set as player 2")
|
||||||
self.p2 = socket
|
self.p2.socket = socket
|
||||||
self.p2Skin = skin
|
self.p2.skin = skin
|
||||||
socket.game = self
|
socket.game = self
|
||||||
if(self.p2 != None and self.p1 != None):
|
if(self.p2.socket != None and self.p1.socket != None):
|
||||||
print("both players here, send opponent to both players")
|
print("both players here, send opponent to both players")
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":1,"id":self.p2.id,"username":self.p2.username, "skin":self.p2Skin}})
|
self.p1.socket.sync_send({"type":"game", "content":{"action":1,"id":self.p2.socket.id,"username":self.p2.socket.username, "skin":self.p2.skin}})
|
||||||
self.p2.sync_send({"type":"game", "content":{"action":1,"id":self.p1.id,"username":self.p1.username, "skin":self.p1Skin}})
|
self.p2.socket.sync_send({"type":"game", "content":{"action":1,"id":self.p1.socket.id,"username":self.p1.socket.username, "skin":self.p1.skin}})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
socket.sendError("invalid request", 9005, e)
|
socket.sendError("invalid request", 9005, e)
|
||||||
|
|
||||||
async def setReady(self, socket):
|
async def setReady(self, socket):
|
||||||
if(socket == self.p1):
|
if(socket == self.p1.socket):
|
||||||
self.p1Ready = True
|
self.p1.ready = True
|
||||||
elif (socket == self.p2):
|
elif (socket == self.p2.socket):
|
||||||
self.p2Ready = True
|
self.p2.ready = True
|
||||||
else:
|
else:
|
||||||
return(0)
|
return(0)
|
||||||
if(self.p1Ready and self.p2Ready):
|
if(self.p1.ready and self.p2.ready):
|
||||||
print("both players are ready, starting game")
|
print("both players are ready, starting game")
|
||||||
self.genObstacles()
|
self.genObstacles()
|
||||||
print("obstacles generated :", self.obstacles)
|
print("obstacles generated :", self.obstacles)
|
||||||
@ -181,14 +171,14 @@ class Game:
|
|||||||
def endGame(self, winner):
|
def endGame(self, winner):
|
||||||
if(self.end):
|
if(self.end):
|
||||||
return
|
return
|
||||||
self.p1.sync_send({"type":"game","content":{"action":10,"won":winner==1, "opponentLeft":self.left == 2}})
|
self.p1.socket.sync_send({"type":"game","content":{"action":10,"won":winner==1, "opponentLeft":self.left == 2}})
|
||||||
self.p2.sync_send({"type":"game","content":{"action":10,"won":winner==2, "opponentLeft":self.left == 1}})
|
self.p2.socket.sync_send({"type":"game","content":{"action":10,"won":winner==2, "opponentLeft":self.left == 1}})
|
||||||
self.winner = winner
|
self.winner = winner
|
||||||
self.end = True
|
self.end = True
|
||||||
|
|
||||||
def leave(self, socket):
|
def leave(self, socket):
|
||||||
socket.game = None
|
socket.game = None
|
||||||
if (socket == self.p1):
|
if (socket == self.p1.socket):
|
||||||
self.left = 1
|
self.left = 1
|
||||||
else:
|
else:
|
||||||
self.left = 2
|
self.left = 2
|
||||||
@ -204,17 +194,17 @@ class Game:
|
|||||||
|
|
||||||
def sendPlayers(self, data):
|
def sendPlayers(self, data):
|
||||||
data_raw = json.dumps({"type":"game","content":data})
|
data_raw = json.dumps({"type":"game","content":data})
|
||||||
self.p1.sync_send(data_raw)
|
self.p1.socket.sync_send(data_raw)
|
||||||
self.p2.sync_send(data_raw)
|
self.p2.socket.sync_send(data_raw)
|
||||||
|
|
||||||
def move(self, socket, pos, up):
|
def move(self, socket, pos, up):
|
||||||
opponent = self.p1 if socket != self.p1 else self.p2
|
opponent = self.p1.socket if socket != self.p1.socket else self.p2.socket
|
||||||
if(socket == self.p1):
|
if(socket == self.p1.socket):
|
||||||
self.p1Pos["pos"] = pos
|
self.p1.pos["pos"] = pos
|
||||||
self.p1Pos["up"] = up;
|
self.p1.pos["up"] = up;
|
||||||
else:
|
else:
|
||||||
self.p2Pos["pos"] = -pos;
|
self.p2.pos["pos"] = -pos;
|
||||||
self.p2Pos["up"] = up
|
self.p2.pos["up"] = up
|
||||||
if(opponent != None):
|
if(opponent != None):
|
||||||
opponent.sync_send({"type":"game","content":{"action":3, "pos":-pos, "up":up, "is_opponent":True}})
|
opponent.sync_send({"type":"game","content":{"action":3, "pos":-pos, "up":up, "is_opponent":True}})
|
||||||
|
|
||||||
@ -225,14 +215,14 @@ class Game:
|
|||||||
self.gameStart = time.time() * 1000
|
self.gameStart = time.time() * 1000
|
||||||
else:
|
else:
|
||||||
gameTime = (time.time() * 1000) - self.gameStart
|
gameTime = (time.time() * 1000) - self.gameStart
|
||||||
if(self.p1):
|
if(self.p1.socket):
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":5,
|
self.p1.socket.sync_send({"type":"game", "content":{"action":5,
|
||||||
"pos" : [self.ballPos["pos"][0],self.ballPos["pos"][1]],
|
"pos" : [self.ballPos["pos"][0],self.ballPos["pos"][1]],
|
||||||
"velocity":[self.ballVel[0], self.ballVel[1]],
|
"velocity":[self.ballVel[0], self.ballVel[1]],
|
||||||
"game_time":gameTime
|
"game_time":gameTime
|
||||||
}})
|
}})
|
||||||
if(self.p2):
|
if(self.p2.socket):
|
||||||
self.p2.sync_send({"type":"game","content":{"action":5,
|
self.p2.socket.sync_send({"type":"game","content":{"action":5,
|
||||||
"pos" : [-self.ballPos["pos"][0],-self.ballPos["pos"][1]],
|
"pos" : [-self.ballPos["pos"][0],-self.ballPos["pos"][1]],
|
||||||
"velocity":[-self.ballVel[0], -self.ballVel[1]],
|
"velocity":[-self.ballVel[0], -self.ballVel[1]],
|
||||||
"game_time":gameTime
|
"game_time":gameTime
|
||||||
@ -355,8 +345,8 @@ class Game:
|
|||||||
print("a player suffured from a major skill issue")
|
print("a player suffured from a major skill issue")
|
||||||
self.score[player-1] += 1
|
self.score[player-1] += 1
|
||||||
print("new score :", self.score)
|
print("new score :", self.score)
|
||||||
self.p1.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 2}})
|
self.p1.socket.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 2}})
|
||||||
self.p2.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 1}})
|
self.p2.socket.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 1}})
|
||||||
await asyncio.sleep(4.5)
|
await asyncio.sleep(4.5)
|
||||||
if(self.checkGameEndGoal()):
|
if(self.checkGameEndGoal()):
|
||||||
return
|
return
|
||||||
@ -375,8 +365,8 @@ class Game:
|
|||||||
if(self.obstacles[i]["isUp"] != self.ballPos["up"]):
|
if(self.obstacles[i]["isUp"] != self.ballPos["up"]):
|
||||||
continue
|
continue
|
||||||
if(self.twoPointsDistance((self.obstacles[i]["pos"]["x"], self.obstacles[i]["pos"]["z"]), ballPos) < Game.jumperRadius):
|
if(self.twoPointsDistance((self.obstacles[i]["pos"]["x"], self.obstacles[i]["pos"]["z"]), ballPos) < Game.jumperRadius):
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
|
self.p1.socket.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
|
||||||
self.p2.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
|
self.p2.socket.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
|
||||||
self.ballPos["up"] = not self.ballPos["up"]
|
self.ballPos["up"] = not self.ballPos["up"]
|
||||||
|
|
||||||
def checkWallsColision(self, ballPos):
|
def checkWallsColision(self, ballPos):
|
||||||
@ -402,22 +392,21 @@ class Game:
|
|||||||
now = time.time()
|
now = time.time()
|
||||||
delta = now - self.lastUpdate
|
delta = now - self.lastUpdate
|
||||||
print("delta :", delta)
|
print("delta :", delta)
|
||||||
print("\033[31msleep time diff :", (delta - self.expSleepTime) * 1000, "ms")
|
|
||||||
currentBallPos = self.ballPos["pos"]
|
currentBallPos = self.ballPos["pos"]
|
||||||
velX = self.ballVel[0]
|
velX = self.ballVel[0]
|
||||||
velZ = self.ballVel[1]
|
velZ = self.ballVel[1]
|
||||||
newBallPos = (round(currentBallPos[0] + (delta * velX), 5),
|
newBallPos = (round(currentBallPos[0] + (delta * velX), 5),
|
||||||
round(currentBallPos[1] + (delta * velZ), 5))
|
round(currentBallPos[1] + (delta * velZ), 5))
|
||||||
if(newBallPos[1] <= Game.limits["back"] or newBallPos[1] >= Game.limits["front"]):
|
if(newBallPos[1] <= Game.limits["back"] or newBallPos[1] >= Game.limits["front"]):
|
||||||
player = self.p2Pos if newBallPos[1] < 0 else self.p1Pos
|
player = self.p2.pos if newBallPos[1] < 0 else self.p1.pos
|
||||||
playerDistance = self.getPlayerDistance(player, newBallPos)
|
playerDistance = self.getPlayerDistance(player, newBallPos)
|
||||||
if(playerDistance >= -(Game.playerLength / 2) and playerDistance <= Game.playerLength / 2 and player["up"] == self.ballPos["up"]):
|
if(playerDistance >= -(Game.playerLength / 2) and playerDistance <= Game.playerLength / 2 and player["up"] == self.ballPos["up"]):
|
||||||
velX = -((self.speed * 0.80) * (playerDistance / (Game.playerLength / 2)))
|
velX = -((self.speed * 0.80) * (playerDistance / (Game.playerLength / 2)))
|
||||||
velZ = self.speed - abs(velX)
|
velZ = self.speed - abs(velX)
|
||||||
if(newBallPos[1] > 0):
|
if(newBallPos[1] > 0):
|
||||||
velZ = -velZ
|
velZ = -velZ
|
||||||
self.p1.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] < 0}})
|
self.p1.socket.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] < 0}})
|
||||||
self.p2.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] > 0}})
|
self.p2.socket.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] > 0}})
|
||||||
else:
|
else:
|
||||||
await self.scoreGoal(1 if newBallPos[1] < 0 else 2)
|
await self.scoreGoal(1 if newBallPos[1] < 0 else 2)
|
||||||
return;
|
return;
|
||||||
@ -458,12 +447,11 @@ class Game:
|
|||||||
break;
|
break;
|
||||||
sleep_time = self.getSleepTime()
|
sleep_time = self.getSleepTime()
|
||||||
print("sleep time : " , sleep_time)
|
print("sleep time : " , sleep_time)
|
||||||
self.expSleepTime = sleep_time
|
|
||||||
await asyncio.sleep(sleep_time)
|
await asyncio.sleep(sleep_time)
|
||||||
print("game end")
|
print("game end")
|
||||||
await self.saveResults()
|
await self.saveResults()
|
||||||
self.p1.game = None
|
self.p1.socket.game = None
|
||||||
self.p2.game = None
|
self.p2.socket.game = None
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
def saveResults(self):
|
def saveResults(self):
|
||||||
@ -472,8 +460,8 @@ class Game:
|
|||||||
print("unkown winner, setting to 1")
|
print("unkown winner, setting to 1")
|
||||||
self.winner = 1
|
self.winner = 1
|
||||||
print("saving results")
|
print("saving results")
|
||||||
p1DbUser = User.objects.get(id=self.p1.id)
|
p1DbUser = User.objects.get(id=self.p1.socket.id)
|
||||||
p2DbUser = User.objects.get(id=self.p2.id)
|
p2DbUser = User.objects.get(id=self.p2.socket.id)
|
||||||
results = GameResults.objects.create(
|
results = GameResults.objects.create(
|
||||||
player1 = p1DbUser,
|
player1 = p1DbUser,
|
||||||
player2 = p2DbUser,
|
player2 = p2DbUser,
|
||||||
@ -485,5 +473,5 @@ class Game:
|
|||||||
results.save()
|
results.save()
|
||||||
print("results saved")
|
print("results saved")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.p1.sendError("Couldn't save last game results", 9104, e)
|
self.p1.socket.sendError("Couldn't save last game results", 9104, e)
|
||||||
self.p2.sendError("Couldn't save last game results", 9104, e)
|
self.p2.socket.sendError("Couldn't save last game results", 9104, e)
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# Player.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/05 03:22:32 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 03:46:24 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
class Player():
|
||||||
|
def __init__(self):
|
||||||
|
self.socket = None
|
||||||
|
self.ready = False
|
||||||
|
self.pos = {"pos":0, "up": False}
|
||||||
|
self.skin = 0
|
@ -0,0 +1,78 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# Tournament.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/04 17:17:07 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 04:31:00 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
import string
|
||||||
|
import asyncio
|
||||||
|
from .utils import genString
|
||||||
|
|
||||||
|
class Tournament:
|
||||||
|
currentTournamentsLock = False
|
||||||
|
currentTournaments = {}
|
||||||
|
|
||||||
|
playerLimit = 8
|
||||||
|
def __init__(self, socket):
|
||||||
|
self.messages = []
|
||||||
|
self.players = []
|
||||||
|
while(Tournament.currentTournamentsLock):
|
||||||
|
continue;
|
||||||
|
Tournament.currentTournamentsLock = True
|
||||||
|
self.genCode()
|
||||||
|
Tournament.currentTournaments[self.code] = self
|
||||||
|
Tournament.currentTournamentsLock = False
|
||||||
|
self.join(socket)
|
||||||
|
|
||||||
|
def genCode(self):
|
||||||
|
nbChar = 4
|
||||||
|
self.code = genString(nbChar, string.ascii_uppercase)
|
||||||
|
nbIter = 0
|
||||||
|
while(self.code in Tournament.currentTournaments):
|
||||||
|
if(nbIter == 100):
|
||||||
|
nbInter = 0
|
||||||
|
nbChar += 1
|
||||||
|
self.code = genString(nbChar, string.ascii_uppercase)
|
||||||
|
nbIter += 1
|
||||||
|
|
||||||
|
def broadcast(self, content):
|
||||||
|
for x in self.players:
|
||||||
|
x.sync_send("tournament",content)
|
||||||
|
|
||||||
|
def sendAllInfo(self, socket):
|
||||||
|
players = []
|
||||||
|
for x in self.players:
|
||||||
|
players.append({"id":x.id,"username":x.username, "pfp":x.pfp})
|
||||||
|
socket.sync_send("tournament",{"action":5, "players":players, "messages" : self.messages})
|
||||||
|
|
||||||
|
def sendMessage(self, socket, message):
|
||||||
|
self.messages.append({"username":socket.username, "message":message})
|
||||||
|
if(len(self.messages) > 20):
|
||||||
|
self.messages.pop(0)
|
||||||
|
self.broadcast({"action":3, "username":socket.username, "message":message})
|
||||||
|
|
||||||
|
def leave(self, socket):
|
||||||
|
if(socket not in self.players):
|
||||||
|
return;
|
||||||
|
index = self.players.index(socket)
|
||||||
|
self.players.pop(index)
|
||||||
|
socket.tournament = None
|
||||||
|
self.broadcast({"action":2,"id":socket.id})
|
||||||
|
|
||||||
|
def join(self, socket):
|
||||||
|
if(socket.tournament != None):
|
||||||
|
socket.sendError("already in a tournament", 9036)
|
||||||
|
return
|
||||||
|
if(len(self.players) == Tournament.playerLimit):
|
||||||
|
socket.sync_send("tournament",{"action":0, "isFull":True})
|
||||||
|
return
|
||||||
|
socket.tournament = self
|
||||||
|
self.players.append(socket)
|
||||||
|
socket.sync_send("tournament",{"action":0,"isFull":False, "isStarted":False,"exist":True, "code":self.code})
|
||||||
|
self.broadcast({"action":1, "id":socket.id, "username": socket.username,"pfp":socket.pfp})
|
@ -193,8 +193,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="line"></span>
|
<span class="line"></span>
|
||||||
<p style="text-align: center; margin-bottom: 20px;">Tournament code</p>
|
<p style="text-align: center; margin-bottom: 20px;">Tournament code</p>
|
||||||
<input id="tournamentCode" class="search-input" type="text" placeholder="Enter the tournament code (empty for create one)">
|
<input id="tournamentCode" class="search-input" type="text" placeholder="Enter the tournament code (empty to create one)">
|
||||||
<span class="line" id="tournament-line2"></span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="skin-select">
|
<div class="skin-select">
|
||||||
<div class="barSelection" id="bar2">
|
<div class="barSelection" id="bar2">
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/23 23:35:41 by edbernar #+# #+# #
|
# Created: 2024/09/23 23:35:41 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/27 03:37:33 by tomoron ### ########.fr #
|
# Updated: 2024/10/04 21:13:28 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -23,9 +23,12 @@ def changePfp(socket, content):
|
|||||||
generate_name = genString(50)
|
generate_name = genString(50)
|
||||||
if (not User.objects.filter(pfp=f"/pfp/{generate_name}.jpg").exists()):
|
if (not User.objects.filter(pfp=f"/pfp/{generate_name}.jpg").exists()):
|
||||||
break
|
break
|
||||||
|
with open(f"/var/www/djangoserver/pfp/{generate_name}.jpg", "wb") as image_file:
|
||||||
|
image_file.write(base64.b64decode(content["img"]))
|
||||||
user = User.objects.get(id=socket.id)
|
user = User.objects.get(id=socket.id)
|
||||||
user.pfp = f"/pfp/{generate_name}.jpg"
|
user.pfp = f"/pfp/{generate_name}.jpg"
|
||||||
user.save()
|
user.save()
|
||||||
with open(f"/var/www/djangoserver/pfp/{generate_name}.jpg", "wb") as image_file:
|
socket.pfp = user.pfp
|
||||||
image_file.write(base64.b64decode(content["img"]))
|
socket.scope["session"]["pfp"] = user.pfp
|
||||||
|
socket.scope["session"].save()
|
||||||
socket.sync_send(json.dumps({"type": "change_pfp", "content": {'pfp': user.pfp}}))
|
socket.sync_send(json.dumps({"type": "change_pfp", "content": {'pfp': user.pfp}}))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/09 16:10:26 by tomoron #+# #+# #
|
# Created: 2024/09/09 16:10:26 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/01 16:35:10 by tomoron ### ########.fr #
|
# Updated: 2024/10/04 17:10:39 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -73,6 +73,9 @@ from .gameActions.ping import ping
|
|||||||
|
|
||||||
action_list = [start, ready, leave, move, ping]
|
action_list = [start, ready, leave, move, ping]
|
||||||
async def gameRequest(socket, content):
|
async def gameRequest(socket, content):
|
||||||
|
if("action" not in content):
|
||||||
|
socket.sendError("missing action parameter",9035)
|
||||||
|
return
|
||||||
action = content["action"]
|
action = content["action"]
|
||||||
if(action < 0 or action > len(action_list)):
|
if(action < 0 or action > len(action_list)):
|
||||||
socket.sendError("Action out of range", 9100)
|
socket.sendError("Action out of range", 9100)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# #
|
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/30 19:43:54 by tomoron ### ########.fr #
|
# Updated: 2024/10/04 23:35:03 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -25,26 +25,29 @@ def userExists(mail, password):
|
|||||||
if(not user.exists()):
|
if(not user.exists()):
|
||||||
return({"found":False})
|
return({"found":False})
|
||||||
else:
|
else:
|
||||||
return({"found":True, "id":user[0].id, "username":user[0].username, "mail_verified":user[0].mail_verified})
|
return({"found":True, "id":user[0].id, "username":user[0].username, "mail_verified":user[0].mail_verified, "pfp":user[0].pfp})
|
||||||
|
|
||||||
async def loginByPass(socket, content):
|
async def loginByPass(socket, content):
|
||||||
u_info = await userExists(content["mail"],content["password"])
|
try:
|
||||||
if(u_info["found"]):
|
u_info = await userExists(content["mail"],content["password"])
|
||||||
if(not u_info["mail_verified"]):
|
if(u_info["found"]):
|
||||||
socket.sendError("Account not verified, please verify your account before logging in",9025)
|
if(not u_info["mail_verified"]):
|
||||||
return
|
socket.sendError("Account not verified, please verify your account before logging in",9025)
|
||||||
if(await socket.login(u_info["id"], u_info["username"])):
|
return
|
||||||
await socket.setLastLogin()
|
if(await socket.login(u_info["id"], u_info["username"], u_info["pfp"])):
|
||||||
socket.sync_send(json.dumps({"type":"logged_in", "content":{
|
await socket.setLastLogin()
|
||||||
"status":True,
|
socket.sync_send(json.dumps({"type":"logged_in", "content":{
|
||||||
"username":u_info["username"],
|
"status":True,
|
||||||
"id": u_info["id"],
|
"username":u_info["username"],
|
||||||
"haveUnreadMessage": await getUnreadStatus(u_info["id"])
|
"id": u_info["id"],
|
||||||
}}))
|
"haveUnreadMessage": await getUnreadStatus(u_info["id"])
|
||||||
|
}}))
|
||||||
|
else:
|
||||||
|
socket.sendError("An unknown error occured",9027)
|
||||||
else:
|
else:
|
||||||
socket.sendError("An unknown error occured",9027)
|
socket.sync_send(json.dumps({"type": "error", "content": "Invalid email or password", "code": 9007}))
|
||||||
else:
|
except Exception as e:
|
||||||
socket.sync_send(json.dumps({"type": "error", "content": "Invalid email or password", "code": 9007}))
|
socket.sendError("Invalid request", 9005, e)
|
||||||
|
|
||||||
async def login(socket, content):
|
async def login(socket, content):
|
||||||
try:
|
try:
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# fetchAllData.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/05 02:08:12 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 02:08:52 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
async def fetchAllData(socket, content):
|
||||||
|
socket.tournament.sendAllInfo(socket)
|
@ -0,0 +1,18 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# leave.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/04 18:05:07 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 02:28:42 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
async def tournamentLeave(socket, content):
|
||||||
|
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" * 100)
|
||||||
|
if(socket.tournament == None):
|
||||||
|
socket.sendError("you're not in a tournament", 9037)
|
||||||
|
return;
|
||||||
|
socket.tournament.leave(socket)
|
@ -0,0 +1,17 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# sendMessage.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/04 18:05:27 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 03:27:45 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
async def sendMessage(socket, content):
|
||||||
|
if("message" not in content):
|
||||||
|
socket.sendError("missing message field",9038)
|
||||||
|
return
|
||||||
|
socket.tournament.sendMessage(socket, content["message"])
|
@ -0,0 +1,22 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# start.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/10/04 17:16:02 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/10/05 02:28:50 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
from ...Tournament import Tournament
|
||||||
|
|
||||||
|
async def tournamentStart(socket, content):
|
||||||
|
if("code" in content and len(content["code"])):
|
||||||
|
if(content["code"] in Tournament.currentTournaments):
|
||||||
|
Tournament.currentTournaments[content["code"]].join(socket)
|
||||||
|
else:
|
||||||
|
socket.sync_send("tournament",{"action":0, "exist":False})
|
||||||
|
else:
|
||||||
|
Tournament(socket)
|
@ -6,26 +6,31 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/01 13:16:39 by edbernar #+# #+# #
|
# Created: 2024/10/01 13:16:39 by edbernar #+# #+# #
|
||||||
# Updated: 2024/10/03 01:29:01 by edbernar ### ########.fr #
|
# Updated: 2024/10/05 02:33:45 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
from .tournamentActions.start import tournamentStart
|
||||||
|
from .tournamentActions.leave import tournamentLeave
|
||||||
|
from .tournamentActions.sendMessage import sendMessage
|
||||||
|
from .tournamentActions.fetchAllData import fetchAllData
|
||||||
|
|
||||||
# tournament request format : {"type":"tournament", "content":{"action": 1, ...}}
|
# tournament request format : {"type":"tournament", "content":{"action": 1, ...}}
|
||||||
|
|
||||||
#server actions (actions sent by the server):
|
#server actions (actions sent by the server):
|
||||||
# 0 : start : tell the client if tournament is full or not exist. If not, tell the client can start the tournament
|
# 0 : start : tell the client if tournament is full or not exist. If not, tell the client can start the tournament
|
||||||
# - exist : true/false
|
# - exists : true/false
|
||||||
# - isFull : true/false
|
# - isFull : true/false
|
||||||
# - started : true/false
|
# - started : true/false
|
||||||
# - code : code of the tournament
|
# - code : code of the tournament
|
||||||
#
|
#
|
||||||
# 1 : someoneJoin : tell the client someone join the tournament (considering clients will place selon the order of the join)
|
# 1 : someoneJoined : tell the client someone joined the tournament (considering clients will place depending on the order of the join)
|
||||||
# - id : id of the player
|
# - id : id of the player
|
||||||
# - username : name of the player
|
# - username : name of the player
|
||||||
# - pfp : pfp of the player
|
# - pfp : pfp of the player
|
||||||
#
|
#
|
||||||
# 2 : someoneLeave : tell the client someone leave the tournament (if game not started, players will be replaced in the order of the join)
|
# 2 : someoneLeft : tell the client someone left the tournament (if game not started, players will be replaced in the order of the join)
|
||||||
# - id : id of the player who leave
|
# - id : id of the player who left
|
||||||
#
|
#
|
||||||
# 3 : message : send a message to the tournament chat
|
# 3 : message : send a message to the tournament chat
|
||||||
# - username : name of the player who send the message
|
# - username : name of the player who send the message
|
||||||
@ -35,11 +40,15 @@
|
|||||||
# - id : id of the player
|
# - id : id of the player
|
||||||
# - username : name of the player
|
# - username : name of the player
|
||||||
#
|
#
|
||||||
|
# 5 : allData : gives tournament data to the client
|
||||||
|
# - players : [{id, username, pfp}, ...]
|
||||||
|
# - messages : [{username, message}]
|
||||||
|
|
||||||
|
|
||||||
#client actions (actions sent by the client) :
|
#client actions (actions sent by the client) :
|
||||||
# 0 : start : start a tournament. if code == "", create a new tournament, else join the tournament with the code
|
# 0 : start : start a tournament. if code == "", create a new tournament, else join the tournament with the code
|
||||||
# - code : code of the tournament
|
# - code : code of the tournament
|
||||||
|
#
|
||||||
# 1 : leave : leave the tournament
|
# 1 : leave : leave the tournament
|
||||||
#
|
#
|
||||||
# 2 : message tournament : send a message to the tournament chat
|
# 2 : message tournament : send a message to the tournament chat
|
||||||
@ -48,4 +57,16 @@
|
|||||||
# 3 : fetchAllData : fetch all data of the tournament
|
# 3 : fetchAllData : fetch all data of the tournament
|
||||||
# --> server will send all the data of the tournament (players, messages, etc...) with his actions
|
# --> server will send all the data of the tournament (players, messages, etc...) with his actions
|
||||||
|
|
||||||
|
actionList = [tournamentStart, tournamentLeave, sendMessage, fetchAllData]
|
||||||
|
async def tournamentRequest(socket, content):
|
||||||
|
if("action" not in content):
|
||||||
|
socket.sendError("missing action parameter",9035)
|
||||||
|
return
|
||||||
|
action = content["action"]
|
||||||
|
if(action < 0 or action > len(actionList)):
|
||||||
|
socket.sendError("Action out of range", 9100)
|
||||||
|
return;
|
||||||
|
if(action != 0 and socket.tournament == None):
|
||||||
|
socket.sendError("you're not in a tournament",9037)
|
||||||
|
return ;
|
||||||
|
await actionList[action](socket,content)
|
||||||
|
@ -25,8 +25,9 @@ urlpatterns = [
|
|||||||
path("multiOnlineGamePage", views.multiOnlineGamePage, name='multiOnlineGamePage'),
|
path("multiOnlineGamePage", views.multiOnlineGamePage, name='multiOnlineGamePage'),
|
||||||
path("waitingGamePage", views.waitingGamePage, name='waitingGamePage'),
|
path("waitingGamePage", views.waitingGamePage, name='waitingGamePage'),
|
||||||
path("profilPage", views.profilPage, name='profilPage'),
|
path("profilPage", views.profilPage, name='profilPage'),
|
||||||
path("game", views.game, name='game'),
|
# path("game", views.game, name='game'),
|
||||||
path("wait_game", views.game, name='wait_game'),
|
path("wait_game", views.game, name='wait_game'),
|
||||||
|
path("tournament", views.tournament, name='tournament'),
|
||||||
path("login42", views.login42, name='login42'),
|
path("login42", views.login42, name='login42'),
|
||||||
path("logout", views.logout, name='logout'),
|
path("logout", views.logout, name='logout'),
|
||||||
path("verify", views.verify, name='verify'),
|
path("verify", views.verify, name='verify'),
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/27 03:36:08 by tomoron #+# #+# #
|
# Created: 2024/09/27 03:36:08 by tomoron #+# #+# #
|
||||||
# Updated: 2024/09/27 11:23:51 by edbernar ### ########.fr #
|
# Updated: 2024/10/04 18:59:25 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
def genString(length):
|
def genString(length, letters=string.ascii_letters+string.digits):
|
||||||
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
return(''.join(random.choice(letters) for i in range(length)))
|
return(''.join(random.choice(letters) for i in range(length)))
|
||||||
|
@ -122,6 +122,8 @@ def login42(request):
|
|||||||
request.session["logged_in"] = True
|
request.session["logged_in"] = True
|
||||||
request.session["username"] = db_user[0].username
|
request.session["username"] = db_user[0].username
|
||||||
request.session["id"] = db_user[0].id
|
request.session["id"] = db_user[0].id
|
||||||
|
request.session["pfp"] = db_user[0].pfp
|
||||||
|
request.session.save()
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
def logout(request):
|
def logout(request):
|
||||||
@ -164,4 +166,7 @@ def tournamentPage(request):
|
|||||||
return index(request)
|
return index(request)
|
||||||
if(not request.session.get("logged_in", False)):
|
if(not request.session.get("logged_in", False)):
|
||||||
return(HttpResponse("you are not logged in",status=403))
|
return(HttpResponse("you are not logged in",status=403))
|
||||||
return render(request, "tournamentPage.html", {})
|
return render(request, "tournamentPage.html", {})
|
||||||
|
|
||||||
|
def tournament(request):
|
||||||
|
return redirect("/lobby")
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/09 14:31:30 by tomoron #+# #+# #
|
# Created: 2024/09/09 14:31:30 by tomoron #+# #+# #
|
||||||
# Updated: 2024/09/30 19:42:45 by tomoron ### ########.fr #
|
# Updated: 2024/10/04 21:06:20 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
|
from multimethod import multimethod
|
||||||
from typing import Union
|
from typing import Union
|
||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
@ -36,16 +37,17 @@ from .typeRequests.changePrivateInfo import changePrivateInfo
|
|||||||
from .typeRequests.changePfp import changePfp
|
from .typeRequests.changePfp import changePfp
|
||||||
from .typeRequests.statusMessage import statusMessage,getUnreadStatus
|
from .typeRequests.statusMessage import statusMessage,getUnreadStatus
|
||||||
from .typeRequests.readMessage import readMessage
|
from .typeRequests.readMessage import readMessage
|
||||||
|
from .typeRequests.tournamentRequest import tournamentRequest
|
||||||
|
|
||||||
typeRequest = ["login", "get_private_list_user", "get_private_list_message",
|
typeRequest = ["login", "get_private_list_user", "get_private_list_message",
|
||||||
"send_private_message", "create_account", "get_all_list_user", "game",
|
"send_private_message", "create_account", "get_all_list_user",
|
||||||
"search_user", "get_user_info", "change_pfp", "change_banner",
|
"game", "search_user", "get_user_info", "change_pfp", "change_banner",
|
||||||
"get_private_info", "change_private_info","status_message", "read_message"
|
"get_private_info", "change_private_info","status_message", "read_message", "tournament"
|
||||||
]
|
]
|
||||||
functionRequest = [login, getPrivateListUser, getPrivateListMessage,
|
functionRequest = [login, getPrivateListUser, getPrivateListMessage,
|
||||||
sendPrivateMessage, createAccount, getAllListUser, gameRequest,
|
sendPrivateMessage, createAccount, getAllListUser, gameRequest,
|
||||||
searchUser, getUserInfo, changePfp, changeBanner,
|
searchUser, getUserInfo, changePfp, changeBanner,
|
||||||
getPrivateInfo, changePrivateInfo, statusMessage, readMessage
|
getPrivateInfo, changePrivateInfo, statusMessage, readMessage, tournamentRequest
|
||||||
]
|
]
|
||||||
|
|
||||||
from random import randint
|
from random import randint
|
||||||
@ -83,7 +85,7 @@ class WebsocketHandler(AsyncWebsocketConsumer):
|
|||||||
print("\033[32monline : ", self.onlinePlayers)
|
print("\033[32monline : ", self.onlinePlayers)
|
||||||
return(0)
|
return(0)
|
||||||
|
|
||||||
async def login(self, uid: int, username: str) -> int:
|
async def login(self, uid: int, username: str, pfp : str) -> int:
|
||||||
if(await self.session_get("logged_in", False)):
|
if(await self.session_get("logged_in", False)):
|
||||||
print("already logged in")
|
print("already logged in")
|
||||||
return(0)
|
return(0)
|
||||||
@ -93,15 +95,18 @@ class WebsocketHandler(AsyncWebsocketConsumer):
|
|||||||
await self.session_set("logged_in",True)
|
await self.session_set("logged_in",True)
|
||||||
await self.session_set("id",uid)
|
await self.session_set("id",uid)
|
||||||
await self.session_set("username",username)
|
await self.session_set("username",username)
|
||||||
|
await self.session_set("pfp", pfp)
|
||||||
await self.session_save()
|
await self.session_save()
|
||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
self.id = uid
|
self.id = uid
|
||||||
self.username = username
|
self.username = username
|
||||||
|
self.pfp = pfp
|
||||||
return(1)
|
return(1)
|
||||||
|
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
self.game = None
|
self.game = None
|
||||||
|
self.tournament = None
|
||||||
self.id = 0
|
self.id = 0
|
||||||
self.username = None
|
self.username = None
|
||||||
self.online = True
|
self.online = True
|
||||||
@ -114,6 +119,7 @@ class WebsocketHandler(AsyncWebsocketConsumer):
|
|||||||
return;
|
return;
|
||||||
self.id = await self.session_get("id",0)
|
self.id = await self.session_get("id",0)
|
||||||
self.username = await self.session_get("username", None)
|
self.username = await self.session_get("username", None)
|
||||||
|
self.pfp = await self.session_get("pfp",None)
|
||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
await self.send(text_data=json.dumps({"type":"logged_in", "content":{
|
await self.send(text_data=json.dumps({"type":"logged_in", "content":{
|
||||||
"status":await self.session_get("logged_in",False),
|
"status":await self.session_get("logged_in",False),
|
||||||
@ -133,6 +139,8 @@ class WebsocketHandler(AsyncWebsocketConsumer):
|
|||||||
del self.onlinePlayers[uid]
|
del self.onlinePlayers[uid]
|
||||||
if(self.game !=None):
|
if(self.game !=None):
|
||||||
self.game.leave(self)
|
self.game.leave(self)
|
||||||
|
if(self.tournament !=None):
|
||||||
|
self.tournament.leave(self)
|
||||||
|
|
||||||
async def receive(self, text_data):
|
async def receive(self, text_data):
|
||||||
try:
|
try:
|
||||||
@ -153,7 +161,12 @@ class WebsocketHandler(AsyncWebsocketConsumer):
|
|||||||
self.sendError("Invalid type", 9004)
|
self.sendError("Invalid type", 9004)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.sendError("Invalid request", 9005, e)
|
self.sendError("Invalid request", 9005, e)
|
||||||
|
|
||||||
|
@multimethod
|
||||||
|
def sync_send(self, reqType : str, content:dict):
|
||||||
|
self.sync_send({"type":reqType,"content":content})
|
||||||
|
|
||||||
|
@multimethod
|
||||||
def sync_send(self, data: Union[dict,str]):
|
def sync_send(self, data: Union[dict,str]):
|
||||||
if(not self.online):
|
if(not self.online):
|
||||||
return
|
return
|
||||||
|
@ -172,11 +172,6 @@ function startTournmament()
|
|||||||
{
|
{
|
||||||
const code = document.getElementById('tournamentCode').value;
|
const code = document.getElementById('tournamentCode').value;
|
||||||
|
|
||||||
if (code.length != 6 && code.length != 0)
|
|
||||||
{
|
|
||||||
CN.new("Information", "The code must be 6 characters long or empty");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
sendRequest("tournament", {action: 0, code: code});
|
sendRequest("tournament", {action: 0, code: code});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,13 +6,16 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/18 00:30:31 by edbernar #+# #+# */
|
/* Created: 2024/08/18 00:30:31 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 14:48:51 by edbernar ### ########.fr */
|
/* Updated: 2024/10/05 02:41:30 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
import { fetchProfile, MotionController } from '/static/javascript/three/examples/jsm/libs/motion-controllers.module.js'
|
||||||
|
import { XRControllerModelFactory } from '/static/javascript/three/examples/jsm/webxr/XRControllerModelFactory.js'
|
||||||
|
import { scene, renderer, isInVrMode } from '/static/javascript/multiOnlineGame/multiOnlineGamePage.js'
|
||||||
|
import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3d.js';
|
||||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||||
import { layoutSelected } from '/static/javascript/lobbyPage/main.js'
|
import { layoutSelected } from '/static/javascript/lobbyPage/main.js'
|
||||||
import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3d.js';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Explication du code :
|
Explication du code :
|
||||||
@ -45,12 +48,16 @@ import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3
|
|||||||
- Ajouter une fonction pour l'animation de point marqué (OK)
|
- Ajouter une fonction pour l'animation de point marqué (OK)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let playerExist = false;
|
let playerExist = false;
|
||||||
let isOnPointAnim = false;
|
let isOnPointAnim = false;
|
||||||
let pressedButton = [];
|
let pressedButton = [];
|
||||||
let mapLength = 0;
|
let mapLength = 0;
|
||||||
const goalAnimation = ["triangle", "cylinder", "star", "box", "rectangle", "ring"];
|
const goalAnimation = ["triangle", "cylinder", "star", "box", "rectangle", "ring"];
|
||||||
let key = null;
|
const controllerModelFactory = new XRControllerModelFactory();
|
||||||
|
let motionController = null;
|
||||||
|
let key = null;
|
||||||
|
let controller1 = null;
|
||||||
|
let controller2 = null;
|
||||||
|
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
@ -67,6 +74,8 @@ class Player
|
|||||||
opponent = null;
|
opponent = null;
|
||||||
playerGoalAnimation = null;
|
playerGoalAnimation = null;
|
||||||
opponentGoal = null;
|
opponentGoal = null;
|
||||||
|
controller1 = null;
|
||||||
|
controller2 = null;
|
||||||
|
|
||||||
constructor (object, map, opponent, indexGoalAnimation, goalIdOppenent)
|
constructor (object, map, opponent, indexGoalAnimation, goalIdOppenent)
|
||||||
{
|
{
|
||||||
@ -280,6 +289,7 @@ class Player
|
|||||||
|
|
||||||
update()
|
update()
|
||||||
{
|
{
|
||||||
|
const gamepads = navigator.getGamepads();
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
this.deltaTime = (currentTime - this.previousTime) / 1000;
|
this.deltaTime = (currentTime - this.previousTime) / 1000;
|
||||||
this.previousTime = currentTime;
|
this.previousTime = currentTime;
|
||||||
@ -287,6 +297,23 @@ class Player
|
|||||||
let i;
|
let i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
for (let i = 0; i< gamepads.length; i++)
|
||||||
|
{
|
||||||
|
if (gamepads[i])
|
||||||
|
{
|
||||||
|
const xAxis = gamepads[i].axes[0];
|
||||||
|
const yAxis = gamepads[i].axes[1];
|
||||||
|
if (!gamepads[i].buttons[0].touched)
|
||||||
|
this.buttonACheck = false;
|
||||||
|
else if (this.buttonACheck == false && gamepads[i].buttons[0].touched)
|
||||||
|
{
|
||||||
|
this.buttonACheck = true;
|
||||||
|
this.buttonAAction = true;
|
||||||
|
}
|
||||||
|
this.joysticksMove(xAxis, yAxis);
|
||||||
|
this.buttonAAction = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
while (i < pressedButton.length)
|
while (i < pressedButton.length)
|
||||||
{
|
{
|
||||||
if (pressedButton[i] == key.up && this.object.position.y < this.limits.up)
|
if (pressedButton[i] == key.up && this.object.position.y < this.limits.up)
|
||||||
@ -336,6 +363,40 @@ class Player
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if (isInVrMode)
|
||||||
|
{
|
||||||
|
if (controller1.userData.inputSource && controller1.userData.inputSource.gamepad)
|
||||||
|
{
|
||||||
|
const gamepad = controller1.userData.inputSource.gamepad;
|
||||||
|
const [a, b, xAxis, yAxis] = gamepad.axes;
|
||||||
|
|
||||||
|
this.joysticksMove(xAxis, yAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonACheck = false;
|
||||||
|
buttonAAction = false;
|
||||||
|
|
||||||
|
joysticksMove(xAxis, yAxis)
|
||||||
|
{
|
||||||
|
if (yAxis > 0.75 || this.buttonAAction)
|
||||||
|
addKeyInArr({key: key.down})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.down});
|
||||||
|
if (yAxis < -0.75 || this.buttonAAction)
|
||||||
|
addKeyInArr({key: key.up})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.up});
|
||||||
|
if (xAxis > 0.5)
|
||||||
|
addKeyInArr({key: key.right})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.right});
|
||||||
|
if (xAxis < -0.5)
|
||||||
|
addKeyInArr({key: key.left})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.left});
|
||||||
}
|
}
|
||||||
|
|
||||||
setCameraPosition(x, y, z)
|
setCameraPosition(x, y, z)
|
||||||
@ -369,6 +430,37 @@ class Player
|
|||||||
}, i * 10);
|
}, i * 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureVrController()
|
||||||
|
{
|
||||||
|
controller1 = renderer.xr.getController(0);
|
||||||
|
controller2 = renderer.xr.getController(1);
|
||||||
|
|
||||||
|
scene.add(controller1);
|
||||||
|
scene.add(controller2);
|
||||||
|
|
||||||
|
for (let i = 0; i < scene.children.length; i++)
|
||||||
|
{
|
||||||
|
if (scene.children[i].name === 'vrHeadset')
|
||||||
|
{
|
||||||
|
const controllerGrip1 = renderer.xr.getControllerGrip(0);
|
||||||
|
controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1));
|
||||||
|
scene.children[i].add(controllerGrip1);
|
||||||
|
|
||||||
|
const controllerGrip2 = renderer.xr.getControllerGrip(1);
|
||||||
|
controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2));
|
||||||
|
scene.children[i].add(controllerGrip2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller1.addEventListener('connected', (event) => {
|
||||||
|
controller1.userData.inputSource = event.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
controller2.addEventListener('connected', (event) => {
|
||||||
|
controller2.userData.inputSource = event.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function addKeyInArr(e)
|
function addKeyInArr(e)
|
||||||
@ -447,7 +539,6 @@ function showGamePad()
|
|||||||
gamePad.style.display = 'flex';
|
gamePad.style.display = 'flex';
|
||||||
document.addEventListener('touchstart', (event) => {
|
document.addEventListener('touchstart', (event) => {
|
||||||
const key = event.target.getAttribute("id");
|
const key = event.target.getAttribute("id");
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < keyList.length; i++)
|
for (let i = 0; i < keyList.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -6,20 +6,20 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/18 00:53:53 by edbernar #+# #+# */
|
/* Created: 2024/08/18 00:53:53 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 14:27:34 by edbernar ### ########.fr */
|
/* Updated: 2024/10/04 21:47:35 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
import { availableSkins, lastSelectedGoal } from '/static/javascript/lobbyPage/3d.js';
|
|
||||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
|
||||||
import { OrbitControls } from '/static/javascript/three/examples/jsm/controls/OrbitControls.js'
|
import { OrbitControls } from '/static/javascript/three/examples/jsm/controls/OrbitControls.js'
|
||||||
import { sendRequest } from "/static/javascript/websocket.js";
|
import { availableSkins, lastSelectedGoal } from '/static/javascript/lobbyPage/3d.js';
|
||||||
import { Player } from '/static/javascript/multiOnlineGame/Player.js'
|
import { VRButton } from "/static/javascript/three/examples/jsm/webxr/VRButton.js"
|
||||||
import { Map } from '/static/javascript/multiOnlineGame/Map.js'
|
|
||||||
import { Ball } from '/static/javascript/multiOnlineGame/Ball.js'
|
|
||||||
import { pageRenderer, isMobile } from '/static/javascript/main.js'
|
|
||||||
import { Opponent } from '/static/javascript/multiOnlineGame/Opponent.js'
|
import { Opponent } from '/static/javascript/multiOnlineGame/Opponent.js'
|
||||||
|
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||||
|
import { Player } from '/static/javascript/multiOnlineGame/Player.js'
|
||||||
|
import { pageRenderer, isMobile } from '/static/javascript/main.js'
|
||||||
|
import { Ball } from '/static/javascript/multiOnlineGame/Ball.js'
|
||||||
|
import { Map } from '/static/javascript/multiOnlineGame/Map.js'
|
||||||
|
import { sendRequest } from "/static/javascript/websocket.js";
|
||||||
/*
|
/*
|
||||||
Controls :
|
Controls :
|
||||||
- w : monter
|
- w : monter
|
||||||
@ -49,22 +49,32 @@ Controls :
|
|||||||
- k : recreate et augmente le score de opponent
|
- k : recreate et augmente le score de opponent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const scoreMax = 5;
|
let scene = null;
|
||||||
|
let map = null;
|
||||||
|
let ball = null;
|
||||||
|
let renderer = null;
|
||||||
|
let player = null;
|
||||||
|
let spotLight = null;
|
||||||
|
let ambiantLight = null;
|
||||||
|
let opponent = null;
|
||||||
|
let interval = null;
|
||||||
|
let intervalPing = null;
|
||||||
|
let debug = false;
|
||||||
|
let lastPingTime = 0;
|
||||||
|
let lastFpsTime = 0;
|
||||||
|
let lastFpsDisplayed = 0;
|
||||||
|
let lastFpsArr = [60];
|
||||||
|
let VrButton = null;
|
||||||
|
let isInVrMode = false;
|
||||||
|
|
||||||
let scene = null;
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
let map = null;
|
mutationsList.forEach((mutation) => {
|
||||||
let ball = null;
|
if (VrButton.innerText == 'VR NOT SUPPORTED')
|
||||||
let renderer = null;
|
document.getElementById('newButtonVr').style.display = 'none';
|
||||||
let player = null;
|
if (mutation.attributeName === 'style')
|
||||||
let spotLight = null;
|
VrButton.style.display = 'none';
|
||||||
let ambiantLight = null;
|
});
|
||||||
let opponent = null;
|
});
|
||||||
let interval = null;
|
|
||||||
let intervalPing = null;
|
|
||||||
let debug = false;
|
|
||||||
let lastPingTime = 0;
|
|
||||||
let lastFpsTime = 0;
|
|
||||||
let lastFpsDisplayed = 0;
|
|
||||||
|
|
||||||
// ------------------- (need to be remove) -------------------- //
|
// ------------------- (need to be remove) -------------------- //
|
||||||
const cameraTmp = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight);
|
const cameraTmp = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight);
|
||||||
@ -75,7 +85,6 @@ class MultiOnlineGamePage
|
|||||||
{
|
{
|
||||||
static create(skin)
|
static create(skin)
|
||||||
{
|
{
|
||||||
console.log(lastSelectedGoal);
|
|
||||||
if (!skin)
|
if (!skin)
|
||||||
skin = {player: 0, opponent: 0};
|
skin = {player: 0, opponent: 0};
|
||||||
const bar1 = createBarPlayer(availableSkins[skin.player]);
|
const bar1 = createBarPlayer(availableSkins[skin.player]);
|
||||||
@ -89,6 +98,8 @@ class MultiOnlineGamePage
|
|||||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
|
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
|
||||||
renderer.domElement.style.filter = 'brightness(1)';
|
renderer.domElement.style.filter = 'brightness(1)';
|
||||||
|
|
||||||
|
vrMode();
|
||||||
opponent = new Opponent(bar2, map, Math.floor(Math.random() * 100 % 6));
|
opponent = new Opponent(bar2, map, Math.floor(Math.random() * 100 % 6));
|
||||||
player = new Player(bar1, map, opponent, Math.floor(Math.random() * 100 % 6), skin.goalId);
|
player = new Player(bar1, map, opponent, Math.floor(Math.random() * 100 % 6), skin.goalId);
|
||||||
spotLight = new THREE.SpotLight(0xffffff, 10000, 0, 0.2);
|
spotLight = new THREE.SpotLight(0xffffff, 10000, 0, 0.2);
|
||||||
@ -175,6 +186,8 @@ class MultiOnlineGamePage
|
|||||||
|
|
||||||
static dispose()
|
static dispose()
|
||||||
{
|
{
|
||||||
|
observer.disconnect();
|
||||||
|
VrButton = null;
|
||||||
window.removeEventListener('resize', windowUpdater);
|
window.removeEventListener('resize', windowUpdater);
|
||||||
if (interval)
|
if (interval)
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
@ -298,7 +311,6 @@ function loop()
|
|||||||
renderer.render(scene, player.camera);
|
renderer.render(scene, player.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastFpsArr = [10, 3, 5];
|
|
||||||
|
|
||||||
function showFps()
|
function showFps()
|
||||||
{
|
{
|
||||||
@ -316,4 +328,40 @@ function showFps()
|
|||||||
lastFpsTime = now;
|
lastFpsTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { MultiOnlineGamePage, player, opponent, ball, map};
|
function vrMode()
|
||||||
|
{
|
||||||
|
const supportsXR = 'xr' in window.navigator;
|
||||||
|
const newButton = configButton();
|
||||||
|
|
||||||
|
if (!supportsXR)
|
||||||
|
return ;
|
||||||
|
renderer.xr.enabled = true;
|
||||||
|
document.body.appendChild( VRButton.createButton(renderer) );
|
||||||
|
VrButton = document.getElementById('VRButton');
|
||||||
|
observer.observe(VrButton, { attributes: true });
|
||||||
|
if (VrButton.innerText !== 'VR NOT SUPPORTED')
|
||||||
|
document.body.append(newButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
function configButton()
|
||||||
|
{
|
||||||
|
const newButton = document.createElement('button');
|
||||||
|
const cameraGroup = new THREE.Group();
|
||||||
|
|
||||||
|
cameraGroup.name = "vrHeadset";
|
||||||
|
newButton.innerText = "Vr mode";
|
||||||
|
newButton.setAttribute('id', 'newButtonVr');
|
||||||
|
newButton.addEventListener('click', () => {
|
||||||
|
VrButton.click();
|
||||||
|
scene.add(cameraGroup);
|
||||||
|
scene.remove(player.camera);
|
||||||
|
player.configureVrController();
|
||||||
|
cameraGroup.add(player.camera);
|
||||||
|
cameraGroup.position.set(0, 0.5, 7.5);
|
||||||
|
isInVrMode = true;
|
||||||
|
});
|
||||||
|
return (newButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { MultiOnlineGamePage, player, opponent, ball, map, scene, renderer, isInVrMode };
|
@ -150,14 +150,14 @@ function findNodes( motionController, scene ) {
|
|||||||
// If the extents cannot be found, skip this animation
|
// If the extents cannot be found, skip this animation
|
||||||
if ( ! visualResponse.minNode ) {
|
if ( ! visualResponse.minNode ) {
|
||||||
|
|
||||||
console.warn( `Could not find ${minNodeName} in the model` );
|
// console.warn( `Could not find ${minNodeName} in the model` );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! visualResponse.maxNode ) {
|
if ( ! visualResponse.maxNode ) {
|
||||||
|
|
||||||
console.warn( `Could not find ${maxNodeName} in the model` );
|
// console.warn( `Could not find ${maxNodeName} in the model` );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/10/01 13:42:29 by edbernar #+# #+# */
|
/* Created: 2024/10/01 13:42:29 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 02:27:58 by edbernar ### ########.fr */
|
/* Updated: 2024/10/05 03:48:19 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -38,7 +38,9 @@ class TournamentPage
|
|||||||
divInfo = document.getElementsByClassName('infoo')[0];
|
divInfo = document.getElementsByClassName('infoo')[0];
|
||||||
divChat = document.getElementsByClassName('chat')[0];
|
divChat = document.getElementsByClassName('chat')[0];
|
||||||
document.getElementById('code-tournament').innerText = "Code : " + code;
|
document.getElementById('code-tournament').innerText = "Code : " + code;
|
||||||
|
sendRequest("tournament", {action: 3});
|
||||||
divTopInfo.innerText = 'Tournament';
|
divTopInfo.innerText = 'Tournament';
|
||||||
|
initTournamentChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
static dispose()
|
static dispose()
|
||||||
@ -103,7 +105,6 @@ class TournamentPage
|
|||||||
while (i < playerNb.length - 1)
|
while (i < playerNb.length - 1)
|
||||||
{
|
{
|
||||||
playerList['player' + playerNb[i]] = playerList['player' + playerNb[i + 1]];
|
playerList['player' + playerNb[i]] = playerList['player' + playerNb[i + 1]];
|
||||||
console.log(playerList['player' + playerNb[i]]);
|
|
||||||
document.getElementById('user-' + playerNb[i]).innerText = playerList['player' + playerNb[i]].username;
|
document.getElementById('user-' + playerNb[i]).innerText = playerList['player' + playerNb[i]].username;
|
||||||
document.getElementById('pfp-' + playerNb[i]).style.backgroundImage = `url(${playerList['player' + playerNb[i]].pfp})`;
|
document.getElementById('pfp-' + playerNb[i]).style.backgroundImage = `url(${playerList['player' + playerNb[i]].pfp})`;
|
||||||
i++;
|
i++;
|
||||||
@ -121,6 +122,14 @@ class TournamentPage
|
|||||||
divChat.appendChild(newText);
|
divChat.appendChild(newText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fetchAllData(content)
|
||||||
|
{
|
||||||
|
for (let i = 0; i < content.messages.length; i++)
|
||||||
|
this.newMessage(content.messages[i]);
|
||||||
|
for (let i = 0; i < content.players.length; i++)
|
||||||
|
this.newOpponent(content.players[i]);
|
||||||
|
}
|
||||||
|
|
||||||
static startGame(content)
|
static startGame(content)
|
||||||
{
|
{
|
||||||
pageRenderer.changePage("waitingGamePage", false, {username: content.username, id: content.id, isTournament: true})
|
pageRenderer.changePage("waitingGamePage", false, {username: content.username, id: content.id, isTournament: true})
|
||||||
@ -136,4 +145,30 @@ function newInfo(message)
|
|||||||
divInfo.appendChild(newDiv);
|
divInfo.appendChild(newDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initTournamentChat()
|
||||||
|
{
|
||||||
|
const inputMessage = document.getElementById('inputMessage');
|
||||||
|
const sendButton = document.getElementById("sendButton");
|
||||||
|
|
||||||
|
sendButton.style.cursor = "pointer";
|
||||||
|
sendButton.addEventListener("click", () => {
|
||||||
|
sendRequest("tournament", {action: 2, message: inputMessage.value});
|
||||||
|
inputMessage.value = "";
|
||||||
|
inputMessage.focus();
|
||||||
|
});
|
||||||
|
inputMessage.addEventListener("keyup", (event) => {
|
||||||
|
if (event.key === "Enter" && inputMessage.value.trim() !== "")
|
||||||
|
{
|
||||||
|
event.preventDefault();
|
||||||
|
sendRequest("tournament", {action: 2, message: inputMessage.value});
|
||||||
|
inputMessage.value = "";
|
||||||
|
inputMessage.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
inputMessage.addEventListener("keydown", (event) => {
|
||||||
|
if (event.key === "Enter")
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export { TournamentPage }
|
export { TournamentPage }
|
@ -6,7 +6,7 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/10/01 13:29:50 by edbernar #+# #+# */
|
/* Created: 2024/10/01 13:29:50 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 01:17:26 by edbernar ### ########.fr */
|
/* Updated: 2024/10/05 03:02:38 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -38,6 +38,8 @@ function typeTournament(content)
|
|||||||
TournamentPage.newMessage(content);
|
TournamentPage.newMessage(content);
|
||||||
else if (content.action == 4)
|
else if (content.action == 4)
|
||||||
TournamentPage.startGame(content);
|
TournamentPage.startGame(content);
|
||||||
|
else if (content.action == 5)
|
||||||
|
TournamentPage.fetchAllData(content);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
console.warn("Request tournament not for this page...");
|
console.warn("Request tournament not for this page...");
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/20 11:23:41 by edbernar #+# #+# */
|
/* Created: 2024/08/20 11:23:41 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/09/29 13:28:28 by edbernar ### ########.fr */
|
/* Updated: 2024/10/05 02:14:49 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -122,8 +122,8 @@ body {
|
|||||||
.gamePad .gamePadLeft {
|
.gamePad .gamePadLeft {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50px;
|
left: 30px;
|
||||||
bottom: 50px;
|
bottom: 30px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
@ -135,8 +135,8 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
right: 50px;
|
right: 30px;
|
||||||
bottom: 50px;
|
bottom: 30px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
@ -159,7 +159,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gamePadLeft #padRight {
|
.gamePadLeft #padRight {
|
||||||
margin-left: 50px;
|
margin-left: 10px;
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
@ -168,7 +168,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gamePadRight #padTop {
|
.gamePadRight #padTop {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 10px;
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
@ -252,4 +252,16 @@ body {
|
|||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#newButtonVr {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
top: 55px;
|
||||||
|
width: 152px;
|
||||||
|
height: 40px;
|
||||||
|
z-index: 900;
|
||||||
|
padding: 0;
|
||||||
|
color: white;
|
||||||
|
background-color: rgba(0, 0, 0, 0.367);
|
||||||
}
|
}
|
@ -36,6 +36,10 @@
|
|||||||
- 9032 : Your opponent isn't online
|
- 9032 : Your opponent isn't online
|
||||||
- 9033 : Skin id out of range
|
- 9033 : Skin id out of range
|
||||||
- 9034 : missing field
|
- 9034 : missing field
|
||||||
|
- 9035 : missing action parameter
|
||||||
|
- 9036 : already in a tournament
|
||||||
|
- 9037 : you're not in a tournament
|
||||||
|
- 9038 : missing message field
|
||||||
|
|
||||||
- 9100 : Action out of range
|
- 9100 : Action out of range
|
||||||
- 9101 : No game started
|
- 9101 : No game started
|
||||||
|
Reference in New Issue
Block a user