Walid Bekkal
2 years ago
63 changed files with 1850 additions and 1737 deletions
@ -1,25 +0,0 @@ |
|||||
POSTGRES_HOST=postgres |
|
||||
POSTGRES_PORT=5432 |
|
||||
POSTGRES_USER=postgres_usr |
|
||||
POSTGRES_PASSWORD=postgres_pw |
|
||||
POSTGRES_DB=transcendence |
|
||||
|
|
||||
PGADMIN_DEFAULT_EMAIL=admin@pg.com |
|
||||
PGADMIN_DEFAULT_PASSWORD=admin |
|
||||
|
|
||||
MAIL_USER=vaganiwast@gmail.com |
|
||||
MAIL_PASSWORD= |
|
||||
|
|
||||
FRONT_FPS=144 |
|
||||
|
|
||||
HOST=localhost |
|
||||
FRONT_PORT=80 |
|
||||
BACK_PORT=3001 |
|
||||
HASH_SALT=10 |
|
||||
|
|
||||
JWT_SECRET=test |
|
||||
JWT_EXPIRATION_TIME=900 |
|
||||
|
|
||||
FT_OAUTH_CLIENT_ID= |
|
||||
FT_OAUTH_CLIENT_SECRET= |
|
||||
FT_OAUTH_CALLBACK_URL="http://$HOST:$BACK_PORT/log/inReturn" |
|
@ -1,13 +1,13 @@ |
|||||
module.exports = { |
module.exports = { |
||||
env: { |
env: { |
||||
browser: true, |
browser: true, |
||||
es2021: true |
es2021: true, |
||||
}, |
}, |
||||
extends: 'standard-with-typescript', |
extends: "standard-with-typescript", |
||||
parserOptions: { |
parserOptions: { |
||||
ecmaVersion: 'latest', |
ecmaVersion: "latest", |
||||
sourceType: 'module', |
sourceType: "module", |
||||
project: ['./tsconfig.json'], |
project: ["./tsconfig.json"], |
||||
tsconfigRootDir: __dirname |
tsconfigRootDir: __dirname, |
||||
} |
}, |
||||
} |
}; |
||||
|
@ -1,25 +1,25 @@ |
|||||
import { |
import { |
||||
type ExecutionContext, |
type ExecutionContext, |
||||
Injectable, |
Injectable, |
||||
type CanActivate |
type CanActivate, |
||||
} from '@nestjs/common' |
} from "@nestjs/common"; |
||||
import { AuthGuard } from '@nestjs/passport' |
import { AuthGuard } from "@nestjs/passport"; |
||||
import { type Request } from 'express' |
import { type Request } from "express"; |
||||
|
|
||||
@Injectable() |
@Injectable() |
||||
export class FtOauthGuard extends AuthGuard('42') { |
export class FtOauthGuard extends AuthGuard("42") { |
||||
async canActivate(context: ExecutionContext): Promise<boolean> { |
async canActivate(context: ExecutionContext): Promise<boolean> { |
||||
const activate: boolean = (await super.canActivate(context)) as boolean |
const activate: boolean = (await super.canActivate(context)) as boolean; |
||||
const request: Request = context.switchToHttp().getRequest() |
const request: Request = context.switchToHttp().getRequest(); |
||||
await super.logIn(request) |
await super.logIn(request); |
||||
return activate |
return activate; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
@Injectable() |
@Injectable() |
||||
export class AuthenticatedGuard implements CanActivate { |
export class AuthenticatedGuard implements CanActivate { |
||||
async canActivate(context: ExecutionContext): Promise<boolean> { |
async canActivate(context: ExecutionContext): Promise<boolean> { |
||||
const req: Request = context.switchToHttp().getRequest() |
const req: Request = context.switchToHttp().getRequest(); |
||||
return req.isAuthenticated() |
return req.isAuthenticated(); |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,9 +1,9 @@ |
|||||
import { createParamDecorator, type ExecutionContext } from '@nestjs/common' |
import { createParamDecorator, type ExecutionContext } from "@nestjs/common"; |
||||
import { type Profile } from 'passport-42' |
import { type Profile } from "passport-42"; |
||||
|
|
||||
export const Profile42 = createParamDecorator( |
export const Profile42 = createParamDecorator( |
||||
(data: unknown, ctx: ExecutionContext): Profile => { |
(data: unknown, ctx: ExecutionContext): Profile => { |
||||
const request = ctx.switchToHttp().getRequest() |
const request = ctx.switchToHttp().getRequest(); |
||||
return request.user |
return request.user; |
||||
} |
} |
||||
) |
); |
||||
|
@ -1,13 +1,13 @@ |
|||||
import { IsNumber, IsOptional, IsString } from 'class-validator' |
import { IsNumber, IsOptional, IsString } from "class-validator"; |
||||
|
|
||||
export class ConnectionDto { |
export class ConnectionDto { |
||||
@IsNumber() |
@IsNumber() |
||||
UserId: number |
UserId: number; |
||||
|
|
||||
@IsNumber() |
@IsNumber() |
||||
ChannelId: number |
ChannelId: number; |
||||
|
|
||||
@IsString() |
@IsString() |
||||
@IsOptional() |
@IsOptional() |
||||
pwd: string |
pwd: string; |
||||
} |
} |
||||
|
@ -1,28 +1,28 @@ |
|||||
import { Transform } from 'class-transformer' |
import { Transform } from "class-transformer"; |
||||
import { |
import { |
||||
IsPositive, |
IsPositive, |
||||
IsAlpha, |
IsAlpha, |
||||
IsString, |
IsString, |
||||
IsOptional, |
IsOptional, |
||||
IsNumber, |
IsNumber, |
||||
IsBoolean |
IsBoolean, |
||||
} from 'class-validator' |
} from "class-validator"; |
||||
|
|
||||
export class CreateChannelDto { |
export class CreateChannelDto { |
||||
@IsOptional() |
@IsOptional() |
||||
@IsPositive() |
@IsPositive() |
||||
id: number |
id: number; |
||||
|
|
||||
@IsString() |
@IsString() |
||||
name: string |
name: string; |
||||
|
|
||||
@IsNumber() |
@IsNumber() |
||||
owner: number |
owner: number; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
password: string |
password: string; |
||||
|
|
||||
@IsBoolean() |
@IsBoolean() |
||||
@Transform(({ value }) => value === 'true') |
@Transform(({ value }) => value === "true") |
||||
isPrivate: boolean |
isPrivate: boolean; |
||||
} |
} |
||||
|
@ -1,12 +1,12 @@ |
|||||
import { IsNumber, IsString } from 'class-validator' |
import { IsNumber, IsString } from "class-validator"; |
||||
|
|
||||
export class CreateMessageDto { |
export class CreateMessageDto { |
||||
@IsString() |
@IsString() |
||||
text: string |
text: string; |
||||
|
|
||||
@IsNumber() |
@IsNumber() |
||||
UserId: number |
UserId: number; |
||||
|
|
||||
@IsNumber() |
@IsNumber() |
||||
ChannelId: number |
ChannelId: number; |
||||
} |
} |
||||
|
@ -1,30 +1,30 @@ |
|||||
import { PartialType } from '@nestjs/mapped-types' |
import { PartialType } from "@nestjs/mapped-types"; |
||||
import { CreateChannelDto } from './create-channel.dto' |
import { CreateChannelDto } from "./create-channel.dto"; |
||||
import { IsNumber, IsOptional, IsString } from 'class-validator' |
import { IsNumber, IsOptional, IsString } from "class-validator"; |
||||
|
|
||||
export class UpdateChannelDto extends PartialType(CreateChannelDto) { |
export class UpdateChannelDto extends PartialType(CreateChannelDto) { |
||||
id: number |
id: number; |
||||
@IsOptional() |
@IsOptional() |
||||
@IsNumber() |
@IsNumber() |
||||
users: [number] |
users: [number]; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
@IsNumber() |
@IsNumber() |
||||
messages: [number] |
messages: [number]; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
@IsNumber() |
@IsNumber() |
||||
owners: [number] // user id
|
owners: [number]; // user id
|
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
@IsNumber() |
@IsNumber() |
||||
banned: [number] // user id
|
banned: [number]; // user id
|
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
@IsNumber() |
@IsNumber() |
||||
muted: [number] // user id
|
muted: [number]; // user id
|
||||
|
|
||||
@IsString() |
@IsString() |
||||
@IsOptional() |
@IsOptional() |
||||
password: string |
password: string; |
||||
} |
} |
||||
|
@ -1,16 +1,15 @@ |
|||||
|
import { IsNumber, IsString } from "class-validator"; |
||||
import { IsNumber, IsString} from 'class-validator' |
|
||||
|
|
||||
export class IdDto { |
export class IdDto { |
||||
@IsNumber() |
@IsNumber() |
||||
id: number |
id: number; |
||||
} |
} |
||||
|
|
||||
export class PasswordDto { |
export class PasswordDto { |
||||
@IsString() |
@IsString() |
||||
password: string |
password: string; |
||||
} |
} |
||||
|
|
||||
export class MuteDto { |
export class MuteDto { |
||||
data: Array<number> |
data: number[]; |
||||
} |
} |
||||
|
@ -1,17 +1,23 @@ |
|||||
import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from 'typeorm' |
import { |
||||
|
Column, |
||||
|
Entity, |
||||
|
JoinColumn, |
||||
|
OneToOne, |
||||
|
PrimaryGeneratedColumn, |
||||
|
} from "typeorm"; |
||||
|
|
||||
import Channel from './channel.entity' |
import Channel from "./channel.entity"; |
||||
import User from 'src/users/entity/user.entity' |
import User from "src/users/entity/user.entity"; |
||||
|
|
||||
@Entity() |
@Entity() |
||||
export default class ConnectedUser { |
export default class ConnectedUser { |
||||
@OneToOne(() => User) |
@OneToOne(() => User) |
||||
user: User |
user: User; |
||||
|
|
||||
@OneToOne(() => Channel) |
@OneToOne(() => Channel) |
||||
@JoinColumn() |
@JoinColumn() |
||||
channel: Channel |
channel: Channel; |
||||
|
|
||||
@PrimaryGeneratedColumn() |
@PrimaryGeneratedColumn() |
||||
socket: string |
socket: string; |
||||
} |
} |
||||
|
@ -1,15 +1,15 @@ |
|||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm' |
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; |
||||
import Message from './message.entity' |
import Message from "./message.entity"; |
||||
import type User from 'src/users/entity/user.entity' |
import type User from "src/users/entity/user.entity"; |
||||
|
|
||||
@Entity() |
@Entity() |
||||
export class Channel { |
export class Channel { |
||||
@PrimaryGeneratedColumn() |
@PrimaryGeneratedColumn() |
||||
id: number |
id: number; |
||||
|
|
||||
@Column() |
@Column() |
||||
users: User[] |
users: User[]; |
||||
|
|
||||
@OneToMany(() => Message, (message) => message.channel) |
@OneToMany(() => Message, (message) => message.channel) |
||||
messages: Message[] |
messages: Message[]; |
||||
} |
} |
||||
|
@ -1,45 +1,45 @@ |
|||||
import { InternalServerErrorException, Logger } from '@nestjs/common' |
import { InternalServerErrorException, Logger } from "@nestjs/common"; |
||||
import { NestFactory } from '@nestjs/core' |
import { NestFactory } from "@nestjs/core"; |
||||
import { AppModule } from './app.module' |
import { AppModule } from "./app.module"; |
||||
import * as session from 'express-session' |
import * as session from "express-session"; |
||||
import * as passport from 'passport' |
import * as passport from "passport"; |
||||
import { type NestExpressApplication } from '@nestjs/platform-express' |
import { type NestExpressApplication } from "@nestjs/platform-express"; |
||||
import * as cookieParser from 'cookie-parser' |
import * as cookieParser from "cookie-parser"; |
||||
import { IoAdapter } from '@nestjs/platform-socket.io' |
import { IoAdapter } from "@nestjs/platform-socket.io"; |
||||
|
|
||||
async function bootstrap(): Promise<void> { |
async function bootstrap(): Promise<void> { |
||||
const logger = new Logger() |
const logger = new Logger(); |
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule) |
const app = await NestFactory.create<NestExpressApplication>(AppModule); |
||||
const port = |
const port = |
||||
process.env.BACK_PORT !== undefined && process.env.BACK_PORT !== '' |
process.env.BACK_PORT !== undefined && process.env.BACK_PORT !== "" |
||||
? +process.env.BACK_PORT |
? +process.env.BACK_PORT |
||||
: 3001 |
: 3001; |
||||
const cors = { |
const cors = { |
||||
origin: /^(http|ws):\/\/localhost(:\d+)?$/, |
origin: /^(http|ws):\/\/localhost(:\d+)?$/, |
||||
methods: 'GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS', |
methods: "GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS", |
||||
preflightContinue: false, |
preflightContinue: false, |
||||
optionsSuccessStatus: 204, |
optionsSuccessStatus: 204, |
||||
credentials: true, |
credentials: true, |
||||
allowedHeaders: ['Accept', 'Content-Type', 'Authorization'] |
allowedHeaders: ["Accept", "Content-Type", "Authorization"], |
||||
} |
}; |
||||
app.use( |
app.use( |
||||
session({ |
session({ |
||||
resave: false, |
resave: false, |
||||
saveUninitialized: false, |
saveUninitialized: false, |
||||
secret: |
secret: |
||||
process.env.JWT_SECRET !== undefined && process.env.JWT_SECRET !== '' |
process.env.JWT_SECRET !== undefined && process.env.JWT_SECRET !== "" |
||||
? process.env.JWT_SECRET |
? process.env.JWT_SECRET |
||||
: 'secret' |
: "secret", |
||||
}) |
}) |
||||
) |
); |
||||
app.use(cookieParser()) |
app.use(cookieParser()); |
||||
app.use(passport.initialize()) |
app.use(passport.initialize()); |
||||
app.use(passport.session()) |
app.use(passport.session()); |
||||
app.enableCors(cors) |
app.enableCors(cors); |
||||
app.useWebSocketAdapter(new IoAdapter(app)) |
app.useWebSocketAdapter(new IoAdapter(app)); |
||||
await app.listen(port) |
await app.listen(port); |
||||
logger.log(`Application listening on port ${port}`) |
logger.log(`Application listening on port ${port}`); |
||||
} |
} |
||||
bootstrap().catch((e) => { |
bootstrap().catch((e) => { |
||||
throw new InternalServerErrorException(e) |
throw new InternalServerErrorException(e); |
||||
}) |
}); |
||||
|
@ -1,12 +1,12 @@ |
|||||
import { type Point, type Rect } from '../game/utils' |
import { type Point, type Rect } from "../game/utils"; |
||||
|
|
||||
export class GameInfo { |
export class GameInfo { |
||||
mapSize!: Point |
mapSize!: Point; |
||||
yourPaddleIndex!: number |
yourPaddleIndex!: number; |
||||
gameId!: string |
gameId!: string; |
||||
walls!: Rect[] |
walls!: Rect[]; |
||||
paddleSize!: Point |
paddleSize!: Point; |
||||
ballSize!: Point |
ballSize!: Point; |
||||
winScore!: number |
winScore!: number; |
||||
ranked!: boolean |
ranked!: boolean; |
||||
} |
} |
||||
|
@ -1,8 +1,8 @@ |
|||||
import { type Point } from '../game/utils' |
import { type Point } from "../game/utils"; |
||||
|
|
||||
export class GameUpdate { |
export class GameUpdate { |
||||
paddlesPositions!: Point[] |
paddlesPositions!: Point[]; |
||||
ballSpeed!: Point |
ballSpeed!: Point; |
||||
ballPosition!: Point |
ballPosition!: Point; |
||||
scores!: number[] |
scores!: number[]; |
||||
} |
} |
||||
|
@ -1,23 +1,23 @@ |
|||||
import { Type } from 'class-transformer' |
import { Type } from "class-transformer"; |
||||
import { |
import { |
||||
ArrayMaxSize, |
ArrayMaxSize, |
||||
IsArray, |
IsArray, |
||||
IsDefined, |
IsDefined, |
||||
IsObject, |
IsObject, |
||||
ValidateNested |
ValidateNested, |
||||
} from 'class-validator' |
} from "class-validator"; |
||||
import { PointDtoValidated } from './PointDtoValidated' |
import { PointDtoValidated } from "./PointDtoValidated"; |
||||
import { RectDtoValidated } from './RectDtoValidated' |
import { RectDtoValidated } from "./RectDtoValidated"; |
||||
|
|
||||
export class MapDtoValidated { |
export class MapDtoValidated { |
||||
@IsObject() |
@IsObject() |
||||
@IsDefined() |
@IsDefined() |
||||
@Type(() => PointDtoValidated) |
@Type(() => PointDtoValidated) |
||||
size!: PointDtoValidated |
size!: PointDtoValidated; |
||||
|
|
||||
@IsArray() |
@IsArray() |
||||
@ArrayMaxSize(5) |
@ArrayMaxSize(5) |
||||
@ValidateNested({ each: true }) |
@ValidateNested({ each: true }) |
||||
@Type(() => RectDtoValidated) |
@Type(() => RectDtoValidated) |
||||
walls!: RectDtoValidated[] |
walls!: RectDtoValidated[]; |
||||
} |
} |
||||
|
@ -1,3 +1,3 @@ |
|||||
export class MatchmakingDto { |
export class MatchmakingDto { |
||||
matchmaking!: boolean |
matchmaking!: boolean; |
||||
} |
} |
||||
|
@ -1,7 +1,7 @@ |
|||||
import { IsBoolean } from 'class-validator' |
import { IsBoolean } from "class-validator"; |
||||
import { MatchmakingDto } from './MatchmakingDto' |
import { MatchmakingDto } from "./MatchmakingDto"; |
||||
|
|
||||
export class MatchmakingDtoValidated extends MatchmakingDto { |
export class MatchmakingDtoValidated extends MatchmakingDto { |
||||
@IsBoolean() |
@IsBoolean() |
||||
matchmaking!: boolean |
matchmaking!: boolean; |
||||
} |
} |
||||
|
@ -1,10 +1,10 @@ |
|||||
import { IsNumber } from 'class-validator' |
import { IsNumber } from "class-validator"; |
||||
import { Point } from '../game/utils' |
import { Point } from "../game/utils"; |
||||
|
|
||||
export class PointDtoValidated extends Point { |
export class PointDtoValidated extends Point { |
||||
@IsNumber() |
@IsNumber() |
||||
x!: number |
x!: number; |
||||
|
|
||||
@IsNumber() |
@IsNumber() |
||||
y!: number |
y!: number; |
||||
} |
} |
||||
|
@ -1,14 +1,14 @@ |
|||||
import { Type } from 'class-transformer' |
import { Type } from "class-transformer"; |
||||
import { ValidateNested } from 'class-validator' |
import { ValidateNested } from "class-validator"; |
||||
import { Rect } from '../game/utils' |
import { Rect } from "../game/utils"; |
||||
import { PointDtoValidated } from './PointDtoValidated' |
import { PointDtoValidated } from "./PointDtoValidated"; |
||||
|
|
||||
export class RectDtoValidated extends Rect { |
export class RectDtoValidated extends Rect { |
||||
@ValidateNested() |
@ValidateNested() |
||||
@Type(() => PointDtoValidated) |
@Type(() => PointDtoValidated) |
||||
center!: PointDtoValidated |
center!: PointDtoValidated; |
||||
|
|
||||
@ValidateNested() |
@ValidateNested() |
||||
@Type(() => PointDtoValidated) |
@Type(() => PointDtoValidated) |
||||
size!: PointDtoValidated |
size!: PointDtoValidated; |
||||
} |
} |
||||
|
@ -1,3 +1,3 @@ |
|||||
export class StringDto { |
export class StringDto { |
||||
value!: string |
value!: string; |
||||
} |
} |
||||
|
@ -1,7 +1,7 @@ |
|||||
import { IsString } from 'class-validator' |
import { IsString } from "class-validator"; |
||||
import { StringDto } from './StringDto' |
import { StringDto } from "./StringDto"; |
||||
|
|
||||
export class StringDtoValidated extends StringDto { |
export class StringDtoValidated extends StringDto { |
||||
@IsString() |
@IsString() |
||||
value!: string |
value!: string; |
||||
} |
} |
||||
|
@ -1,12 +1,12 @@ |
|||||
import { IsString } from 'class-validator' |
import { IsString } from "class-validator"; |
||||
|
|
||||
export class UserDto { |
export class UserDto { |
||||
@IsString() |
@IsString() |
||||
username!: string |
username!: string; |
||||
|
|
||||
@IsString() |
@IsString() |
||||
avatar!: string |
avatar!: string; |
||||
|
|
||||
@IsString() |
@IsString() |
||||
status!: string |
status!: string; |
||||
} |
} |
||||
|
@ -1,64 +1,64 @@ |
|||||
import { type Socket } from 'socket.io' |
import { type Socket } from "socket.io"; |
||||
import { type GameCreationDtoValidated } from '../dtos/GameCreationDtoValidated' |
import { type GameCreationDtoValidated } from "../dtos/GameCreationDtoValidated"; |
||||
import { DEFAULT_BALL_INITIAL_SPEED, DEFAULT_MAP_SIZE } from './constants' |
import { DEFAULT_BALL_INITIAL_SPEED, DEFAULT_MAP_SIZE } from "./constants"; |
||||
import { type Games } from './Games' |
import { type Games } from "./Games"; |
||||
|
|
||||
export class MatchmakingQueue { |
export class MatchmakingQueue { |
||||
games: Games |
games: Games; |
||||
queue: Array<{ name: string, socket: Socket, uuid: string }> |
queue: Array<{ name: string; socket: Socket; uuid: string }>; |
||||
|
|
||||
constructor(games: Games) { |
constructor(games: Games) { |
||||
this.games = games |
this.games = games; |
||||
this.queue = [] |
this.queue = []; |
||||
} |
} |
||||
|
|
||||
addPlayer(name: string, socket: Socket, uuid: string): void { |
addPlayer(name: string, socket: Socket, uuid: string): void { |
||||
if (!this.isInQueue(name)) { |
if (!this.isInQueue(name)) { |
||||
console.log('Adding player to queue: ', name) |
console.log("Adding player to queue: ", name); |
||||
this.queue.push({ name, socket, uuid }) |
this.queue.push({ name, socket, uuid }); |
||||
if (this.canCreateGame()) { |
if (this.canCreateGame()) { |
||||
this.createGame() |
this.createGame(); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
removePlayer(name: string): void { |
removePlayer(name: string): void { |
||||
if (this.isInQueue(name)) { |
if (this.isInQueue(name)) { |
||||
console.log('Removing player from queue: ', name) |
console.log("Removing player from queue: ", name); |
||||
this.queue = this.queue.filter((player) => player.name !== name) |
this.queue = this.queue.filter((player) => player.name !== name); |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
isInQueue(name: string): boolean { |
isInQueue(name: string): boolean { |
||||
return this.queue.some((player) => player.name === name) |
return this.queue.some((player) => player.name === name); |
||||
} |
} |
||||
|
|
||||
canCreateGame(): boolean { |
canCreateGame(): boolean { |
||||
return this.queue.length >= 2 |
return this.queue.length >= 2; |
||||
} |
} |
||||
|
|
||||
createGame(): void { |
createGame(): void { |
||||
const player1 = this.queue.shift() |
const player1 = this.queue.shift(); |
||||
const player2 = this.queue.shift() |
const player2 = this.queue.shift(); |
||||
if (player1 === undefined || player2 === undefined) { |
if (player1 === undefined || player2 === undefined) { |
||||
return |
return; |
||||
} |
} |
||||
const gameCreationDto: GameCreationDtoValidated = { |
const gameCreationDto: GameCreationDtoValidated = { |
||||
playerNames: [player1.name, player2.name], |
playerNames: [player1.name, player2.name], |
||||
map: { |
map: { |
||||
size: DEFAULT_MAP_SIZE, |
size: DEFAULT_MAP_SIZE, |
||||
walls: [] |
walls: [], |
||||
}, |
}, |
||||
initialBallSpeedX: DEFAULT_BALL_INITIAL_SPEED.x, |
initialBallSpeedX: DEFAULT_BALL_INITIAL_SPEED.x, |
||||
initialBallSpeedY: DEFAULT_BALL_INITIAL_SPEED.y |
initialBallSpeedY: DEFAULT_BALL_INITIAL_SPEED.y, |
||||
} |
}; |
||||
const ranked = true |
const ranked = true; |
||||
|
|
||||
this.games.newGame( |
this.games.newGame( |
||||
[player1.socket, player2.socket], |
[player1.socket, player2.socket], |
||||
[player1.uuid, player2.uuid], |
[player1.uuid, player2.uuid], |
||||
gameCreationDto, |
gameCreationDto, |
||||
ranked |
ranked |
||||
) |
); |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,32 +1,32 @@ |
|||||
import { DEFAULT_PADDLE_SIZE } from './constants' |
import { DEFAULT_PADDLE_SIZE } from "./constants"; |
||||
import { type Point, Rect } from './utils' |
import { type Point, Rect } from "./utils"; |
||||
|
|
||||
export class Paddle { |
export class Paddle { |
||||
rect: Rect |
rect: Rect; |
||||
color: string | CanvasGradient | CanvasPattern = 'white' |
color: string | CanvasGradient | CanvasPattern = "white"; |
||||
mapSize: Point |
mapSize: Point; |
||||
|
|
||||
constructor( |
constructor( |
||||
spawn: Point, |
spawn: Point, |
||||
gameSize: Point, |
gameSize: Point, |
||||
size: Point = DEFAULT_PADDLE_SIZE |
size: Point = DEFAULT_PADDLE_SIZE |
||||
) { |
) { |
||||
this.rect = new Rect(spawn, size) |
this.rect = new Rect(spawn, size); |
||||
this.mapSize = gameSize |
this.mapSize = gameSize; |
||||
} |
} |
||||
|
|
||||
draw(context: CanvasRenderingContext2D): void { |
draw(context: CanvasRenderingContext2D): void { |
||||
this.rect.draw(context, this.color) |
this.rect.draw(context, this.color); |
||||
} |
} |
||||
|
|
||||
move(newY: number): void { |
move(newY: number): void { |
||||
const offset: number = this.rect.size.y / 2 |
const offset: number = this.rect.size.y / 2; |
||||
if (newY - offset < 0) { |
if (newY - offset < 0) { |
||||
this.rect.center.y = offset |
this.rect.center.y = offset; |
||||
} else if (newY + offset > this.mapSize.y) { |
} else if (newY + offset > this.mapSize.y) { |
||||
this.rect.center.y = this.mapSize.y - offset |
this.rect.center.y = this.mapSize.y - offset; |
||||
} else { |
} else { |
||||
this.rect.center.y = newY |
this.rect.center.y = newY; |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,22 +1,22 @@ |
|||||
import { Point } from './utils' |
import { Point } from "./utils"; |
||||
|
|
||||
export const GAME_EVENTS = { |
export const GAME_EVENTS = { |
||||
START_GAME: 'START_GAME', |
START_GAME: "START_GAME", |
||||
READY: 'READY', |
READY: "READY", |
||||
GAME_TICK: 'GAME_TICK', |
GAME_TICK: "GAME_TICK", |
||||
PLAYER_MOVE: 'PLAYER_MOVE', |
PLAYER_MOVE: "PLAYER_MOVE", |
||||
GET_GAME_INFO: 'GET_GAME_INFO', |
GET_GAME_INFO: "GET_GAME_INFO", |
||||
CREATE_GAME: 'CREATE_GAME', |
CREATE_GAME: "CREATE_GAME", |
||||
REGISTER_PLAYER: 'REGISTER_PLAYER', |
REGISTER_PLAYER: "REGISTER_PLAYER", |
||||
MATCHMAKING: 'MATCHMAKING', |
MATCHMAKING: "MATCHMAKING", |
||||
LEAVE_GAME: 'LEAVE_GAME' |
LEAVE_GAME: "LEAVE_GAME", |
||||
} |
}; |
||||
|
|
||||
export const DEFAULT_MAP_SIZE = new Point(500, 400) |
export const DEFAULT_MAP_SIZE = new Point(500, 400); |
||||
export const DEFAULT_PADDLE_SIZE = new Point(30, 50) |
export const DEFAULT_PADDLE_SIZE = new Point(30, 50); |
||||
export const DEFAULT_BALL_SIZE = new Point(10, 10) |
export const DEFAULT_BALL_SIZE = new Point(10, 10); |
||||
export const DEFAULT_BALL_INITIAL_SPEED = new Point(10, 2) |
export const DEFAULT_BALL_INITIAL_SPEED = new Point(10, 2); |
||||
export const DEFAULT_MAX_BALL_SPEED = new Point(30, 20) |
export const DEFAULT_MAX_BALL_SPEED = new Point(30, 20); |
||||
export const DEFAULT_BALL_SPEED_INCREMENT = new Point(0.05, 0) |
export const DEFAULT_BALL_SPEED_INCREMENT = new Point(0.05, 0); |
||||
export const DEFAULT_WIN_SCORE = 5 |
export const DEFAULT_WIN_SCORE = 5; |
||||
export const GAME_TICKS = 30 |
export const GAME_TICKS = 30; |
||||
|
@ -1,18 +1,18 @@ |
|||||
import { Test, type TestingModule } from '@nestjs/testing' |
import { Test, type TestingModule } from "@nestjs/testing"; |
||||
import { PongGateway } from './pong.gateway' |
import { PongGateway } from "./pong.gateway"; |
||||
|
|
||||
describe('PongGateway', () => { |
describe("PongGateway", () => { |
||||
let gateway: PongGateway |
let gateway: PongGateway; |
||||
|
|
||||
beforeEach(async () => { |
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
const module: TestingModule = await Test.createTestingModule({ |
||||
providers: [PongGateway] |
providers: [PongGateway], |
||||
}).compile() |
}).compile(); |
||||
|
|
||||
gateway = module.get<PongGateway>(PongGateway) |
gateway = module.get<PongGateway>(PongGateway); |
||||
}) |
}); |
||||
|
|
||||
it('should be defined', () => { |
it("should be defined", () => { |
||||
expect(gateway).toBeDefined() |
expect(gateway).toBeDefined(); |
||||
}) |
}); |
||||
}) |
}); |
||||
|
@ -1,15 +1,15 @@ |
|||||
import { forwardRef, Module } from '@nestjs/common' |
import { forwardRef, Module } from "@nestjs/common"; |
||||
import { PongGateway } from './pong.gateway' |
import { PongGateway } from "./pong.gateway"; |
||||
import Result from './entity/result.entity' |
import Result from "./entity/result.entity"; |
||||
import { TypeOrmModule } from '@nestjs/typeorm' |
import { TypeOrmModule } from "@nestjs/typeorm"; |
||||
import { PongService } from './pong.service' |
import { PongService } from "./pong.service"; |
||||
import { UsersModule } from 'src/users/users.module' |
import { UsersModule } from "src/users/users.module"; |
||||
import { PongController } from './pong.controller' |
import { PongController } from "./pong.controller"; |
||||
|
|
||||
@Module({ |
@Module({ |
||||
imports: [forwardRef(() => UsersModule), TypeOrmModule.forFeature([Result])], |
imports: [forwardRef(() => UsersModule), TypeOrmModule.forFeature([Result])], |
||||
providers: [PongGateway, PongService], |
providers: [PongGateway, PongService], |
||||
controllers: [PongController], |
controllers: [PongController], |
||||
exports: [PongService] |
exports: [PongService], |
||||
}) |
}) |
||||
export class PongModule {} |
export class PongModule {} |
||||
|
@ -1,18 +1,18 @@ |
|||||
import { Test, type TestingModule } from '@nestjs/testing' |
import { Test, type TestingModule } from "@nestjs/testing"; |
||||
import { Games } from './game/Games' |
import { Games } from "./game/Games"; |
||||
|
|
||||
describe('Pong', () => { |
describe("Pong", () => { |
||||
let provider: Games |
let provider: Games; |
||||
|
|
||||
beforeEach(async () => { |
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
const module: TestingModule = await Test.createTestingModule({ |
||||
providers: [Games] |
providers: [Games], |
||||
}).compile() |
}).compile(); |
||||
|
|
||||
provider = module.get<Games>(Games) |
provider = module.get<Games>(Games); |
||||
}) |
}); |
||||
|
|
||||
it('should be defined', () => { |
it("should be defined", () => { |
||||
expect(provider).toBeDefined() |
expect(provider).toBeDefined(); |
||||
}) |
}); |
||||
}) |
}); |
||||
|
@ -1,8 +1,8 @@ |
|||||
declare module 'passport-42' { |
declare module "passport-42" { |
||||
export type Profile = any |
export type Profile = any; |
||||
export type VerifyCallback = any |
export type VerifyCallback = any; |
||||
export class Strategy { |
export class Strategy { |
||||
constructor (options: any, verify: any) |
constructor(options: any, verify: any); |
||||
authenticate (req: any, options: any): any |
authenticate(req: any, options: any): any; |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,31 +1,31 @@ |
|||||
import { IsString, IsNotEmpty, IsPositive, IsOptional } from 'class-validator' |
import { IsString, IsNotEmpty, IsPositive, IsOptional } from "class-validator"; |
||||
|
|
||||
import { ApiProperty } from '@nestjs/swagger' |
import { ApiProperty } from "@nestjs/swagger"; |
||||
import { Express } from 'express' |
import { Express } from "express"; |
||||
|
|
||||
export class UserDto { |
export class UserDto { |
||||
@IsPositive() |
@IsPositive() |
||||
@IsOptional() |
@IsOptional() |
||||
readonly ftId: number |
readonly ftId: number; |
||||
|
|
||||
@IsString() |
@IsString() |
||||
@IsNotEmpty() |
@IsNotEmpty() |
||||
readonly username: string |
readonly username: string; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
readonly status: string |
readonly status: string; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
readonly avatar: string |
readonly avatar: string; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
readonly authToken: string |
readonly authToken: string; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
readonly isVerified: boolean |
readonly isVerified: boolean; |
||||
} |
} |
||||
|
|
||||
export class AvatarUploadDto { |
export class AvatarUploadDto { |
||||
@ApiProperty({ type: 'string', format: 'binary' }) |
@ApiProperty({ type: "string", format: "binary" }) |
||||
file: Express.Multer.File |
file: Express.Multer.File; |
||||
} |
} |
||||
|
@ -1,17 +1,15 @@ |
|||||
import { forwardRef, Module } from '@nestjs/common' |
import { forwardRef, Module } from "@nestjs/common"; |
||||
import { TypeOrmModule } from '@nestjs/typeorm' |
import { TypeOrmModule } from "@nestjs/typeorm"; |
||||
import { User } from './entity/user.entity' |
import { User } from "./entity/user.entity"; |
||||
import { UsersController } from './users.controller' |
import { UsersController } from "./users.controller"; |
||||
import { UsersService } from './users.service' |
import { UsersService } from "./users.service"; |
||||
import { PongModule } from 'src/pong/pong.module' |
import { PongModule } from "src/pong/pong.module"; |
||||
import { ChatModule } from 'src/chat/chat.module' |
import { ChatModule } from "src/chat/chat.module"; |
||||
|
|
||||
@Module({ |
@Module({ |
||||
imports: [ |
imports: [forwardRef(() => PongModule), TypeOrmModule.forFeature([User])], |
||||
forwardRef(() => PongModule), |
|
||||
TypeOrmModule.forFeature([User])], |
|
||||
controllers: [UsersController], |
controllers: [UsersController], |
||||
providers: [UsersService], |
providers: [UsersService], |
||||
exports: [UsersService] |
exports: [UsersService], |
||||
}) |
}) |
||||
export class UsersModule {} |
export class UsersModule {} |
||||
|
@ -0,0 +1,5 @@ |
|||||
|
import ioClient from "socket.io-client"; |
||||
|
|
||||
|
export const io = ioClient("http://localhost:3001", { |
||||
|
withCredentials: true, |
||||
|
}); |
Loading…
Reference in new issue