ball now bounces on walls, the speed of the ball now increase when it bounce anywhere (or take a jumper)
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
# 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/09/25 17:08:55 by tomoron ### ########.fr #
|
# Updated: 2024/09/27 03:54:50 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -56,8 +56,11 @@ class Game:
|
|||||||
{id: 6, 'color': None, 'texture': '/static/img/skin/3.jpg'},
|
{id: 6, 'color': None, 'texture': '/static/img/skin/3.jpg'},
|
||||||
{id: 7, 'color': None, 'texture': '/static/img/skin/4.jpg'},
|
{id: 7, 'color': None, 'texture': '/static/img/skin/4.jpg'},
|
||||||
]
|
]
|
||||||
|
wallLength = 1
|
||||||
|
wallWidth = 0.05
|
||||||
|
bounceSpeedIncrease = 0.2
|
||||||
|
|
||||||
def __init__(self, socket, withBot, skinId):
|
def __init__(self, socket, withBot, skinId = 0, opponent = None):
|
||||||
self.p1 = None
|
self.p1 = None
|
||||||
self.p2 = None
|
self.p2 = None
|
||||||
self.p1Ready = False
|
self.p1Ready = False
|
||||||
@ -76,8 +79,16 @@ class Game:
|
|||||||
self.obstacles = []
|
self.obstacles = []
|
||||||
self.lastWin = 2
|
self.lastWin = 2
|
||||||
|
|
||||||
|
self.p1Skin = 0
|
||||||
|
self.p2Skin = 0
|
||||||
|
|
||||||
|
self.opponentLock = opponent
|
||||||
|
|
||||||
if(withBot):
|
if(withBot):
|
||||||
self.join(socket)
|
self.join(socket, skinId)
|
||||||
|
elif(opponent != None):
|
||||||
|
self.join(socket, skinId)
|
||||||
|
#send invite to oponnent
|
||||||
else:
|
else:
|
||||||
while(Game.waitingForPlayerLock):
|
while(Game.waitingForPlayerLock):
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
@ -85,9 +96,9 @@ class Game:
|
|||||||
if(Game.waitingForPlayer == None):
|
if(Game.waitingForPlayer == None):
|
||||||
Game.waitingForPlayer = self
|
Game.waitingForPlayer = self
|
||||||
socket.sync_send({"type":"game","content":{"action":0}})
|
socket.sync_send({"type":"game","content":{"action":0}})
|
||||||
self.join(socket)
|
self.join(socket, skinId)
|
||||||
else:
|
else:
|
||||||
Game.waitingForPlayer.join(socket)
|
Game.waitingForPlayer.join(socket, skinId)
|
||||||
Game.waitingForPlayer = None
|
Game.waitingForPlayer = None
|
||||||
Game.waitingForPlayerLock = False
|
Game.waitingForPlayerLock = False
|
||||||
|
|
||||||
@ -98,25 +109,39 @@ class Game:
|
|||||||
|
|
||||||
def genObstacles(self):
|
def genObstacles(self):
|
||||||
for x in Game.wallsPos:
|
for x in Game.wallsPos:
|
||||||
if random.randint(1, 100) < 0:
|
if random.randint(1, 100) < 50:
|
||||||
self.obstacles.append(x)
|
self.obstacles.append(x)
|
||||||
i = 0
|
i = 0
|
||||||
while(i < len(Game.jumpersPos)):
|
down = False
|
||||||
|
up = False
|
||||||
|
while(i < len(Game.jumpersPos) - 2):
|
||||||
if(random.randint(1, 100) < 50):
|
if(random.randint(1, 100) < 50):
|
||||||
self.obstacles.append(Game.jumpersPos[i])
|
self.obstacles.append(Game.jumpersPos[i])
|
||||||
i+=1
|
down = True
|
||||||
i+=1
|
else:
|
||||||
|
self.obstacles.append(Game.jumpersPos[i + 1])
|
||||||
|
up = True
|
||||||
|
i+=2
|
||||||
|
if not down:
|
||||||
|
self.obstacles.append(Game.jumperPos[i])
|
||||||
|
if not up:
|
||||||
|
self.obstacles.append(Game.jumperPos[i + 1])
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
self.p1.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.sync_send({"type":"game", "content":{"action":7, "content":self.obstacles}})
|
||||||
self.obstaclesInvLength()
|
self.obstaclesInvLength()
|
||||||
|
|
||||||
def join(self, socket):
|
def join(self, socket, skin):
|
||||||
try:
|
try:
|
||||||
if(self.p1 == None):
|
if(self.p1 == None):
|
||||||
self.p1 = socket
|
self.p1 = socket
|
||||||
|
self.p1Skin = skin
|
||||||
else:
|
else:
|
||||||
|
if(self.opponentLock != socket.id):
|
||||||
|
socket.sendError("You are not invited to this game", 9013)
|
||||||
|
return;
|
||||||
self.p2 = socket
|
self.p2 = socket
|
||||||
|
self.p2Skin = skin
|
||||||
socket.game = self
|
socket.game = self
|
||||||
if(self.p2 != None and self.p1 != None):
|
if(self.p2 != None and self.p1 != None):
|
||||||
self.p1.sync_send({"type":"game", "content":{"action":1,"id":self.p2.id,"username":self.p2.username}})
|
self.p1.sync_send({"type":"game", "content":{"action":1,"id":self.p2.id,"username":self.p2.username}})
|
||||||
@ -192,15 +217,12 @@ class Game:
|
|||||||
if(disc < 0):
|
if(disc < 0):
|
||||||
return None
|
return None
|
||||||
res = (((-b) + math.sqrt(disc)) / ( 2 * a )) + (((-b) - math.sqrt(disc)) / ( 2 * a ))
|
res = (((-b) + math.sqrt(disc)) / ( 2 * a )) + (((-b) - math.sqrt(disc)) / ( 2 * a ))
|
||||||
print("res : ", res/2)
|
|
||||||
return(res / 2)
|
return(res / 2)
|
||||||
|
|
||||||
def check_jumper_colision(self, jumper):
|
def check_jumper_colision(self, jumper):
|
||||||
jpos = (jumper["pos"]["x"], jumper["pos"]["z"])
|
jpos = (jumper["pos"]["x"], jumper["pos"]["z"])
|
||||||
pos1 = self.ballPos["pos"]
|
pos1 = self.ballPos["pos"]
|
||||||
pos2 = self.ballPos["pos"][0] +self.ballVel[0], self.ballPos["pos"][1] + self.ballVel[1]
|
pos2 = self.ballPos["pos"][0] +self.ballVel[0], self.ballPos["pos"][1] + self.ballVel[1]
|
||||||
print(pos1)
|
|
||||||
print(pos2)
|
|
||||||
slope = 0
|
slope = 0
|
||||||
if(pos1[0] - pos2[0] == 0):
|
if(pos1[0] - pos2[0] == 0):
|
||||||
slope=100000
|
slope=100000
|
||||||
@ -214,27 +236,59 @@ class Game:
|
|||||||
c = (((-jpos[0]) ** 2) + (((-jpos[1]) + offset) ** 2)) - (Game.jumperRadius ** 2)
|
c = (((-jpos[0]) ** 2) + (((-jpos[1]) + offset) ** 2)) - (Game.jumperRadius ** 2)
|
||||||
return(self.solve_quadratic(a, b ,c))
|
return(self.solve_quadratic(a, b ,c))
|
||||||
|
|
||||||
|
def check_wall_colision(self, wall):
|
||||||
|
wpos = wall["pos"]["x"]
|
||||||
|
pos1 = self.ballPos["pos"]
|
||||||
|
pos2 = self.ballPos["pos"][0] +self.ballVel[0], self.ballPos["pos"][1] + self.ballVel[1]
|
||||||
|
slope = 0
|
||||||
|
if(abs(pos1[1]) <= (Game.wallWidth / 2) + Game.ballRadius):
|
||||||
|
print("inside")
|
||||||
|
return(None)
|
||||||
|
if(pos1[0] - pos2[0] == 0):
|
||||||
|
slope=100000
|
||||||
|
else:
|
||||||
|
slope = (pos1[1] - pos2[1])/(pos1[0] - pos2[0])
|
||||||
|
offset = pos1[1] - (slope * pos1[0])
|
||||||
|
|
||||||
|
if(slope == 0):
|
||||||
|
return(None)
|
||||||
|
|
||||||
|
wallSide = (Game.wallWidth / 2) + Game.ballRadius
|
||||||
|
if(pos1[1] < 0):
|
||||||
|
wallSide *= -1
|
||||||
|
hitPos = (wallSide - offset) / slope
|
||||||
|
print(f'{hitPos=}')
|
||||||
|
relPos = wpos - hitPos
|
||||||
|
print("relative position : ", relPos)
|
||||||
|
print("max colision : ", (Game.wallLength / 2) + Game.ballRadius)
|
||||||
|
if(abs(relPos) < (Game.wallLength / 2) + Game.ballRadius):
|
||||||
|
return(hitPos)
|
||||||
|
print("not in wall 1")
|
||||||
|
return(None)
|
||||||
|
|
||||||
def check_collision_obstacles(self):
|
def check_collision_obstacles(self):
|
||||||
min_time = -1
|
min_time = -1
|
||||||
for x in self.obstacles:
|
for x in self.obstacles:
|
||||||
if x["isUp"] != self.ballPos["up"]:
|
if x["isUp"] != self.ballPos["up"]:
|
||||||
continue
|
continue
|
||||||
|
pos = None
|
||||||
if x["type"] == 1:
|
if x["type"] == 1:
|
||||||
pos = self.check_jumper_colision(x)
|
pos = self.check_jumper_colision(x)
|
||||||
|
elif x["type"] == 2:
|
||||||
|
pos = self.check_wall_colision(x)
|
||||||
if(pos == None):
|
if(pos == None):
|
||||||
print("no colision")
|
|
||||||
continue
|
continue
|
||||||
print("pos :", pos)
|
|
||||||
print("ballPos :", self.ballPos["pos"][0])
|
|
||||||
dist = pos - self.ballPos["pos"][0]
|
dist = pos - self.ballPos["pos"][0]
|
||||||
print("dist : ", dist)
|
time = 0
|
||||||
time = dist / (self.ballVel[0])
|
if(self.ballVel[0] != 0):
|
||||||
|
time = dist / self.ballVel[0]
|
||||||
|
else:
|
||||||
|
time = -1
|
||||||
if(time > 0):
|
if(time > 0):
|
||||||
if(min_time == -1):
|
if(min_time == -1):
|
||||||
min_time = time
|
min_time = time
|
||||||
else:
|
else:
|
||||||
min_time = (min(min_time, time))
|
min_time = (min(min_time, time))
|
||||||
print("time :",time)
|
|
||||||
return(min_time)
|
return(min_time)
|
||||||
|
|
||||||
def getTimeUntilColision(self, limitNeg, limitPos, position, velocity):
|
def getTimeUntilColision(self, limitNeg, limitPos, position, velocity):
|
||||||
@ -259,9 +313,6 @@ class Game:
|
|||||||
|
|
||||||
def getPlayerDistance(self, player, ballPos):
|
def getPlayerDistance(self, player, ballPos):
|
||||||
playerPos = player["pos"]
|
playerPos = player["pos"]
|
||||||
print("Player pos : ", playerPos)
|
|
||||||
print("chose player :", 2 if ballPos[1] < 0 else 1)
|
|
||||||
print("ball position :", ballPos[0])
|
|
||||||
return(playerPos - ballPos[0])
|
return(playerPos - ballPos[0])
|
||||||
|
|
||||||
async def scoreGoal(self, player):
|
async def scoreGoal(self, player):
|
||||||
@ -281,6 +332,8 @@ class Game:
|
|||||||
|
|
||||||
def checkJumpersDistance(self, ballPos):
|
def checkJumpersDistance(self, ballPos):
|
||||||
for i in range(0, len(self.obstacles)):
|
for i in range(0, len(self.obstacles)):
|
||||||
|
if(self.obstacles[i]["type"] != 1):
|
||||||
|
continue;
|
||||||
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):
|
||||||
@ -288,7 +341,26 @@ class Game:
|
|||||||
self.p2.sync_send({"type":"game", "content":{"action":8,"id":i}})
|
self.p2.sync_send({"type":"game", "content":{"action":8,"id":i}})
|
||||||
self.ballPos["up"] = not self.ballPos["up"]
|
self.ballPos["up"] = not self.ballPos["up"]
|
||||||
|
|
||||||
|
def checkWallsColision(self, ballPos):
|
||||||
|
for i in range(0, len(self.obstacles)):
|
||||||
|
if(self.obstacles[i]["type"] != 2):
|
||||||
|
continue;
|
||||||
|
if(self.obstacles[i]["isUp"] != self.ballPos["up"]):
|
||||||
|
continue;
|
||||||
|
if(abs(ballPos[1]) < (Game.wallWidth / 2) + Game.ballRadius):
|
||||||
|
if(abs(self.obstacles[i]["pos"]["x"] - ballPos[0]) < (Game.wallLength / 2) + Game.ballRadius):
|
||||||
|
print("not in wall 2")
|
||||||
|
return(True)
|
||||||
|
return(False)
|
||||||
|
|
||||||
|
def increaseSpeed(self):
|
||||||
|
x = self.ballVel[0] + (Game.bounceSpeedIncrease * (self.ballVel[0] / self.speed))
|
||||||
|
y = self.ballVel[1] + (Game.bounceSpeedIncrease * (self.ballVel[1] / self.speed))
|
||||||
|
self.ballVel = (x, y)
|
||||||
|
self.speed += Game.bounceSpeedIncrease
|
||||||
|
|
||||||
async def updateBall(self):
|
async def updateBall(self):
|
||||||
|
print("AAAAAAAAAAAAAAAAAAAAAAA update")
|
||||||
now = time.time()
|
now = time.time()
|
||||||
delta = now - self.lastUpdate
|
delta = now - self.lastUpdate
|
||||||
currentBallPos = self.ballPos["pos"]
|
currentBallPos = self.ballPos["pos"]
|
||||||
@ -305,19 +377,22 @@ class Game:
|
|||||||
if(newBallPos[1] > 0):
|
if(newBallPos[1] > 0):
|
||||||
velZ = -velZ
|
velZ = -velZ
|
||||||
else:
|
else:
|
||||||
print("distance :", playerDistance)
|
|
||||||
self.lastWin = 1 if newBallPos[1] < 0 else 2
|
self.lastWin = 1 if newBallPos[1] < 0 else 2
|
||||||
await self.scoreGoal(1 if newBallPos[1] < 0 else 2)
|
await self.scoreGoal(1 if newBallPos[1] < 0 else 2)
|
||||||
return;
|
return;
|
||||||
elif(newBallPos[0] <= Game.limits["left"] or newBallPos[0] >= Game.limits["right"]):
|
elif(newBallPos[0] <= Game.limits["left"] or newBallPos[0] >= Game.limits["right"]):
|
||||||
velX = -velX
|
velX = -velX
|
||||||
|
elif(self.checkWallsColision(newBallPos)):
|
||||||
|
velZ = -velZ
|
||||||
self.checkJumpersDistance(newBallPos)
|
self.checkJumpersDistance(newBallPos)
|
||||||
self.ballVel = (velX, velZ)
|
self.ballVel = (velX, velZ)
|
||||||
|
self.increaseSpeed()
|
||||||
self.lastUpdate = now
|
self.lastUpdate = now
|
||||||
self.ballPos["pos"] = newBallPos
|
self.ballPos["pos"] = newBallPos
|
||||||
self.sendNewBallInfo()
|
self.sendNewBallInfo()
|
||||||
|
|
||||||
def prepareGame(self, stop = False):
|
def prepareGame(self, stop = False):
|
||||||
|
self.speed = Game.startSpeed
|
||||||
self.ballPos = {"pos":(0, 0), "up": False}
|
self.ballPos = {"pos":(0, 0), "up": False}
|
||||||
if(stop):
|
if(stop):
|
||||||
self.ballVel = (0, 0)
|
self.ballVel = (0, 0)
|
||||||
@ -333,6 +408,7 @@ class Game:
|
|||||||
async def gameLoop(self):
|
async def gameLoop(self):
|
||||||
self.started = True
|
self.started = True
|
||||||
self.sendPlayers({"action":2})
|
self.sendPlayers({"action":2})
|
||||||
|
self.prepareGame(True)
|
||||||
await asyncio.sleep(3)
|
await asyncio.sleep(3)
|
||||||
self.prepareGame()
|
self.prepareGame()
|
||||||
while(not self.end):
|
while(not self.end):
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# fieldsVerif.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/09/27 02:22:43 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/09/27 03:34:11 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
import re
|
||||||
|
from .models import User
|
||||||
|
|
||||||
|
mail_pattern = "^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$"
|
||||||
|
|
||||||
|
def usernameValid(username, socket=None):
|
||||||
|
err = None
|
||||||
|
code = 0
|
||||||
|
|
||||||
|
if (username.find(' ') != -1):
|
||||||
|
err = "Username must not contain spaces"
|
||||||
|
code = 9015
|
||||||
|
elif (len(username) < 3):
|
||||||
|
err = "Username must be at least 3 characters long"
|
||||||
|
code = 9016
|
||||||
|
elif (len(username) > 20):
|
||||||
|
err = "Username must be at most 20 characters long"
|
||||||
|
code = 9017
|
||||||
|
elif (not all(c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" for c in username)):
|
||||||
|
err = "Username must contain only letters and numbers"
|
||||||
|
code = 9018
|
||||||
|
elif (User.objects.filter(username=username).exists()):
|
||||||
|
err = "Username already used"
|
||||||
|
code = 9023
|
||||||
|
|
||||||
|
if(err and socket != None):
|
||||||
|
socket.sendError(err, code)
|
||||||
|
return(err == None)
|
||||||
|
|
||||||
|
def passwordValid(password, socket=None):
|
||||||
|
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
|
||||||
|
err = None
|
||||||
|
code = 0
|
||||||
|
|
||||||
|
if (len(password) < 8):
|
||||||
|
err = "Password must be at least 8 characters long"
|
||||||
|
code = 9019
|
||||||
|
# elif (password.find(content["username"]) != -1):
|
||||||
|
# err = "Password must not contain the username"
|
||||||
|
# code = 9021
|
||||||
|
elif (not bool(re.match(password_pattern, password))):
|
||||||
|
err = "Password must contain at least one lowercase letter, one uppercase letter and one special character"
|
||||||
|
code = 9020
|
||||||
|
|
||||||
|
if(err and socket != None):
|
||||||
|
socket.sendError(err, code)
|
||||||
|
return(err == None)
|
||||||
|
|
||||||
|
|
||||||
|
def discordValid(user, socket=None):
|
||||||
|
discord_pattern = "^[a-zA-Z0-9_.]{0,32}$"
|
||||||
|
err = None
|
||||||
|
code = 0
|
||||||
|
|
||||||
|
if (len(user) > 32):
|
||||||
|
err = "Discord username must be at most 32 characters long"
|
||||||
|
code = 9024
|
||||||
|
elif (not bool(re.match(discord_pattern, user))):
|
||||||
|
err = "Discord username must between 2 and 32 letters, numbers, underscores or points"
|
||||||
|
code = 9025
|
||||||
|
elif (len(user) == 1):
|
||||||
|
err = "Discord username must be at least 2 characters long"
|
||||||
|
code = 9026
|
||||||
|
|
||||||
|
if(err and socket != None):
|
||||||
|
socket.sendError(err, code)
|
||||||
|
return(err == None)
|
||||||
|
|
||||||
|
def mailValid(mail, socket=None):
|
||||||
|
mail_pattern = "^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$"
|
||||||
|
err = None
|
||||||
|
code = 0
|
||||||
|
|
||||||
|
if (not bool(re.match(mail_pattern, mail))):
|
||||||
|
err = "Invalid mail"
|
||||||
|
code = 9014
|
||||||
|
if (User.objects.filter(mail=mail).exists()):
|
||||||
|
err = "Mail already used"
|
||||||
|
code = 9022
|
||||||
|
|
||||||
|
if(err and socket != None):
|
||||||
|
socket.sendError(err, code)
|
||||||
|
return(err == None)
|
@ -6,28 +6,21 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/24 17:26:12 by edbernar #+# #+# #
|
# Created: 2024/09/24 17:26:12 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/24 17:32:09 by edbernar ### ########.fr #
|
# Updated: 2024/09/27 03:40:12 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from ..models import User
|
from ..models import User
|
||||||
|
from ..utils import genString
|
||||||
from random import randint
|
from random import randint
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def genereateRandomName():
|
|
||||||
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
len = 50
|
|
||||||
name = "a"
|
|
||||||
for i in range(0, len):
|
|
||||||
name += chars[randint(0, 61)]
|
|
||||||
return name
|
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
def changeBanner(socket, content):
|
def changeBanner(socket, content):
|
||||||
while True:
|
while True:
|
||||||
generate_name = genereateRandomName()
|
generate_name = genString(50)
|
||||||
if (not User.objects.filter(banner=f"/banner/{generate_name}.jpg").exists()):
|
if (not User.objects.filter(banner=f"/banner/{generate_name}.jpg").exists()):
|
||||||
break
|
break
|
||||||
user = User.objects.get(id=socket.id)
|
user = User.objects.get(id=socket.id)
|
||||||
|
@ -6,28 +6,21 @@
|
|||||||
# 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/24 15:53:26 by edbernar ### ########.fr #
|
# Updated: 2024/09/27 03:37:33 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from ..models import User
|
from ..models import User
|
||||||
|
from ..utils import genString
|
||||||
from random import randint
|
from random import randint
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def genereateRandomName():
|
|
||||||
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
len = 50
|
|
||||||
name = "a"
|
|
||||||
for i in range(0, len):
|
|
||||||
name += chars[randint(0, 61)]
|
|
||||||
return name
|
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
def changePfp(socket, content):
|
def changePfp(socket, content):
|
||||||
while True:
|
while True:
|
||||||
generate_name = genereateRandomName()
|
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
|
||||||
user = User.objects.get(id=socket.id)
|
user = User.objects.get(id=socket.id)
|
||||||
|
@ -6,94 +6,52 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/25 23:28:49 by edbernar #+# #+# #
|
# Created: 2024/09/25 23:28:49 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/26 14:56:22 by edbernar ### ########.fr #
|
# Updated: 2024/09/27 03:23:10 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from ..models import User
|
from ..models import User
|
||||||
|
from ..fieldsVerif import usernameValid, passwordValid, discordValid
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import re
|
|
||||||
|
|
||||||
mail_pattern = "^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$"
|
|
||||||
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
|
|
||||||
discord_pattern = "^[a-zA-Z0-9_.]{0,32}$"
|
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
def changePrivateInfo(socket, content):
|
def changePrivateInfo(socket, content):
|
||||||
try:
|
try:
|
||||||
data = []
|
|
||||||
if (content.get("username")):
|
|
||||||
data.append("username")
|
|
||||||
if (content.get("new_password")):
|
|
||||||
data.append("new_password")
|
|
||||||
if (content.get("discord")):
|
|
||||||
data.append("discord")
|
|
||||||
if (content.get("delete")):
|
|
||||||
data.append("delete")
|
|
||||||
if (len(data) != 1):
|
|
||||||
socket.sendError("You must provide exactly one field to update", 9028)
|
|
||||||
return
|
|
||||||
if (content.get("delete")):
|
|
||||||
user = User.objects.get(id=socket.id)
|
user = User.objects.get(id=socket.id)
|
||||||
|
if ("delete" in content):
|
||||||
user.delete()
|
user.delete()
|
||||||
socket.scope["session"].delete()
|
socket.scope["session"].delete()
|
||||||
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully deleted."}))
|
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully deleted."}))
|
||||||
socket.close()
|
socket.close()
|
||||||
|
return;
|
||||||
|
elif ("username" in content):
|
||||||
|
if (not usernameValid(content.get("username"), socket)):
|
||||||
return
|
return
|
||||||
if (content.get("username")):
|
|
||||||
if (content["username"].find(' ') != -1):
|
|
||||||
socket.sendError("Username must not contain spaces", 9015)
|
|
||||||
return
|
|
||||||
if (len(content["username"]) < 3):
|
|
||||||
socket.sendError("Username must be at least 3 characters long", 9016)
|
|
||||||
return
|
|
||||||
if (len(content["username"]) > 20):
|
|
||||||
socket.sendError("Username must be at most 20 characters long", 9017)
|
|
||||||
return
|
|
||||||
if (not all(c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" for c in content["username"])):
|
|
||||||
socket.sendError("Username must contain only letters and numbers", 9018)
|
|
||||||
return
|
|
||||||
if (User.objects.filter(username=content["username"]).exists()):
|
|
||||||
socket.sendError("Username already used", 9023)
|
|
||||||
return
|
|
||||||
if (content.get("new_password")):
|
|
||||||
if (not content.get("old_password")):
|
|
||||||
raise Exception("Old password is required")
|
|
||||||
if (len(content["new_password"]) < 8):
|
|
||||||
socket.sendError("Password must be at least 8 characters long", 9019)
|
|
||||||
return
|
|
||||||
if (content["new_password"].find(str(content.get("username"))) != -1):
|
|
||||||
socket.sendError("Password must not contain the username", 9021)
|
|
||||||
return
|
|
||||||
if (not bool(re.match(password_pattern, content["password"]))):
|
|
||||||
socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9020)
|
|
||||||
if (not bool(re.match(password_pattern, content["new_password"]))):
|
|
||||||
return
|
|
||||||
if (content.get("discord")):
|
|
||||||
if (len(content["discord"]) > 32):
|
|
||||||
socket.sendError("Discord must be at most 32 characters long", 9024)
|
|
||||||
return
|
|
||||||
if (not bool(re.match(discord_pattern, content["discord"]))):
|
|
||||||
socket.sendError("Discord must contain only letters, numbers and underscores or points", 9025)
|
|
||||||
return
|
|
||||||
|
|
||||||
user = User.objects.get(id=socket.id)
|
|
||||||
if (content.get("username")):
|
|
||||||
user.username = content["username"]
|
user.username = content["username"]
|
||||||
socket.username = content["username"]
|
socket.username = content["username"]
|
||||||
socket.scope["session"]['username'] = content["username"]
|
socket.scope["session"]['username'] = content["username"]
|
||||||
if (content.get("new_password")):
|
elif ("new_password" in content):
|
||||||
|
if (not passwordValid(content.get("new_password"), socket)):
|
||||||
|
return
|
||||||
|
if (not content.get("old_password")):
|
||||||
|
socket.sendError("You must provide your current password to change it",9030)
|
||||||
|
return
|
||||||
if (hashlib.md5((user.mail + content["old_password"]).encode()).hexdigest() != user.password):
|
if (hashlib.md5((user.mail + content["old_password"]).encode()).hexdigest() != user.password):
|
||||||
socket.sendError("Invalid password", 9029)
|
socket.sendError("Invalid password", 9029)
|
||||||
return
|
return
|
||||||
user.password = hashlib.md5((user.mail + content["new_password"]).encode()).hexdigest()
|
user.password = hashlib.md5((user.mail + content["new_password"]).encode()).hexdigest()
|
||||||
if (content.get("discord")):
|
elif ("discord" in content):
|
||||||
if (content["discord"] != ""):
|
if (not discordValid(content.get("discord"), socket)):
|
||||||
|
return
|
||||||
|
if (content["discord"] == ""):
|
||||||
|
user.discord_username = None
|
||||||
|
else:
|
||||||
user.discord_username = content["discord"]
|
user.discord_username = content["discord"]
|
||||||
else:
|
else:
|
||||||
user.discord_username = None
|
socket.sendError("You must provide a field to update", 9028)
|
||||||
|
return;
|
||||||
user.save()
|
user.save()
|
||||||
socket.scope["session"].save()
|
socket.scope["session"].save()
|
||||||
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully updated."}))
|
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully updated."}))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: marvin <marvin@student.42.fr> +#+ +:+ +#+ #
|
# By: marvin <marvin@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/08/09 08:08:00 by edbernar #+# #+# #
|
# Created: 2024/08/09 08:08:00 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/22 18:58:55 by marvin ### ########.fr #
|
# Updated: 2024/09/27 03:37:05 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -16,15 +16,14 @@ from ..data import ICLOUD_USER, ICLOUD_PASS, SERVER_URL
|
|||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.mime.image import MIMEImage
|
from email.mime.image import MIMEImage
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
|
from ..fieldsVerif import mailValid, usernameValid, passwordValid
|
||||||
|
from ..utils import genString
|
||||||
import smtplib
|
import smtplib
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
mail_pattern = "^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$"
|
|
||||||
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
|
|
||||||
allowed_char_username = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
|
|
||||||
URLMAIL = SERVER_URL + "/verify?token="
|
URLMAIL = SERVER_URL + "/verify?token="
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
@ -34,40 +33,16 @@ def createAccount(socket, content):
|
|||||||
socket.sendError("Already logged in", 9012)
|
socket.sendError("Already logged in", 9012)
|
||||||
return;
|
return;
|
||||||
try:
|
try:
|
||||||
if (not bool(re.match(mail_pattern, content["mail"]))):
|
if(not mailValid(content["mail"], socket)):
|
||||||
socket.sendError("Invalid mail", 9014)
|
|
||||||
return
|
return
|
||||||
if (content["username"].find(' ') != -1):
|
if(not usernameValid(content["username"], socket)):
|
||||||
socket.sendError("Username must not contain spaces", 9015)
|
|
||||||
return
|
return
|
||||||
if (len(content["username"]) < 3):
|
if(not passwordValid(content["password"], socket)):
|
||||||
socket.sendError("Username must be at least 3 characters long", 9016)
|
|
||||||
return
|
|
||||||
if (len(content["username"]) > 20):
|
|
||||||
socket.sendError("Username must be at most 20 characters long", 9017)
|
|
||||||
return
|
|
||||||
if (not all(c in allowed_char_username for c in content["username"])):
|
|
||||||
socket.sendError("Username must contain only letters and numbers", 9018)
|
|
||||||
return
|
|
||||||
if (len(content["password"]) < 8):
|
|
||||||
socket.sendError("Password must be at least 8 characters long", 9019)
|
|
||||||
return
|
|
||||||
if (not bool(re.match(password_pattern, content["password"]))):
|
|
||||||
socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9020)
|
|
||||||
return
|
|
||||||
if (content["password"].find(content["username"]) != -1):
|
|
||||||
socket.sendError("Password must not contain the username", 9021)
|
|
||||||
return
|
|
||||||
if (User.objects.filter(mail=content["mail"]).exists()):
|
|
||||||
socket.sendError("Mail already used", 9022)
|
|
||||||
return
|
|
||||||
if (User.objects.filter(username=content["username"]).exists()):
|
|
||||||
socket.sendError("Username already used", 9023)
|
|
||||||
return
|
return
|
||||||
password = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
|
password = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
|
||||||
new_user = User.objects.create(username=content["username"], mail=content["mail"], password=password)
|
new_user = User.objects.create(username=content["username"], mail=content["mail"], password=password)
|
||||||
new_user.save()
|
new_user.save()
|
||||||
verif_str = gen_string(200)
|
verif_str = genString(200)
|
||||||
MailVerify.objects.create(uid=new_user, token=verif_str).save()
|
MailVerify.objects.create(uid=new_user, token=verif_str).save()
|
||||||
print("send")
|
print("send")
|
||||||
socket.sync_send(json.dumps({"type": "create_account", "content": "Account created"}))
|
socket.sync_send(json.dumps({"type": "create_account", "content": "Account created"}))
|
||||||
@ -175,7 +150,3 @@ def sendVerifMail(verif_str, mail, username):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Erreur lors de l'envoi de l'e-mail : {e}")
|
print(f"Erreur lors de l'envoi de l'e-mail : {e}")
|
||||||
return(0)
|
return(0)
|
||||||
|
|
||||||
def gen_string(length):
|
|
||||||
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
return(''.join(random.choice(letters) for i in range(length)))
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/11 17:07:08 by tomoron #+# #+# #
|
# Created: 2024/09/11 17:07:08 by tomoron #+# #+# #
|
||||||
# Updated: 2024/09/25 09:23:02 by edbernar ### ########.fr #
|
# Updated: 2024/09/27 02:12:40 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -16,5 +16,5 @@ async def start(socket, content):
|
|||||||
if(socket.game != None):
|
if(socket.game != None):
|
||||||
socket.sendError("Game already started", 9102)
|
socket.sendError("Game already started", 9102)
|
||||||
return;
|
return;
|
||||||
Game(socket, content.get("with_bot", False), content.get("skinId", 0))
|
Game(socket, content.get("with_bot", False), content.get("skinId", 0), content.get("opponent", None))
|
||||||
|
|
||||||
|
@ -6,25 +6,23 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/18 07:26:07 by edbernar #+# #+# #
|
# Created: 2024/09/18 07:26:07 by edbernar #+# #+# #
|
||||||
# Updated: 2024/09/18 08:20:44 by edbernar ### ########.fr #
|
# Updated: 2024/09/27 03:48:39 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from ..models import User
|
from ..models import User
|
||||||
|
from django.db.models import Q
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@sync_to_async
|
@sync_to_async
|
||||||
def searchUser(socket, content):
|
def searchUser(socket, content):
|
||||||
try:
|
try:
|
||||||
users = User.objects.filter(username__contains=content["username"])
|
users = User.objects.filter(Q(username__contains=content["username"]) & ~Q(id=socket.id))[:10]
|
||||||
userList = []
|
userList = []
|
||||||
for user in users:
|
for user in users:
|
||||||
if (user.id != socket.id and user.mail_verified):
|
|
||||||
userList.append((user.username, user.id, user.pfp))
|
userList.append((user.username, user.id, user.pfp))
|
||||||
if len(userList) >= 10:
|
socket.sync_send({"type":"search_user", "content":userList})
|
||||||
break
|
|
||||||
socket.sync_send({"type":"search_user", "content":userList if userList else []})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
socket.sendError("An unknown error occured", 9027, e)
|
socket.sendError("An unknown error occured", 9027, e)
|
||||||
return
|
return
|
@ -0,0 +1,15 @@
|
|||||||
|
# **************************************************************************** #
|
||||||
|
# #
|
||||||
|
# ::: :::::::: #
|
||||||
|
# utils.py :+: :+: :+: #
|
||||||
|
# +:+ +:+ +:+ #
|
||||||
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
|
# +#+#+#+#+#+ +#+ #
|
||||||
|
# Created: 2024/09/27 03:36:08 by tomoron #+# #+# #
|
||||||
|
# Updated: 2024/09/27 03:36:42 by tomoron ### ########.fr #
|
||||||
|
# #
|
||||||
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
def genString(length):
|
||||||
|
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
return(''.join(random.choice(letters) for i in range(length)))
|
@ -31,7 +31,9 @@
|
|||||||
- 9027 : An unknown error occured
|
- 9027 : An unknown error occured
|
||||||
- 9028 : You must provide exactly one field to update
|
- 9028 : You must provide exactly one field to update
|
||||||
- 9029 : Invalid password
|
- 9029 : Invalid password
|
||||||
|
- 9030 : You must provide your current password to it
|
||||||
|
|
||||||
- 9100 : Action out of range
|
- 9100 : Action out of range
|
||||||
- 9101 : No game started
|
- 9101 : No game started
|
||||||
- 9102 : Game already started
|
- 9102 : Game already started
|
||||||
|
- 9103 : You are not invited to this game
|
||||||
|
Reference in New Issue
Block a user