nicolas-arnaud
2 years ago
58 changed files with 1757 additions and 1740 deletions
@ -0,0 +1,25 @@ |
|||||
|
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,25 +1,25 @@ |
|||||
import { forwardRef, Module } from "@nestjs/common"; |
import { forwardRef, Module } from '@nestjs/common' |
||||
import { TypeOrmModule } from "@nestjs/typeorm"; |
import { TypeOrmModule } from '@nestjs/typeorm' |
||||
|
|
||||
import { AuthModule } from "src/auth/auth.module"; |
import { AuthModule } from 'src/auth/auth.module' |
||||
import { UsersModule } from "src/users/users.module"; |
import { UsersModule } from 'src/users/users.module' |
||||
import { ChatGateway } from "./chat.gateway"; |
import { ChatGateway } from './chat.gateway' |
||||
import { ChatController } from "./chat.controller"; |
import { ChatController } from './chat.controller' |
||||
import { ChatService } from "./chat.service"; |
import { ChatService } from './chat.service' |
||||
import { MessageService } from "./message.service"; |
import { MessageService } from './message.service' |
||||
|
|
||||
import Channel from "./entity/channel.entity"; |
import Channel from './entity/channel.entity' |
||||
import Message from "./entity/message.entity"; |
import Message from './entity/message.entity' |
||||
import ConnectedUser from "./entity/connection.entity"; |
import ConnectedUser from './entity/connection.entity' |
||||
|
|
||||
@Module({ |
@Module({ |
||||
imports: [ |
imports: [ |
||||
UsersModule, |
UsersModule, |
||||
AuthModule, |
AuthModule, |
||||
TypeOrmModule.forFeature([Channel, Message, ConnectedUser]), |
TypeOrmModule.forFeature([Channel, Message, ConnectedUser]) |
||||
], |
], |
||||
controllers: [ChatController], |
controllers: [ChatController], |
||||
providers: [ChatService, ChatGateway, MessageService], |
providers: [ChatService, ChatGateway, MessageService], |
||||
exports: [ChatService], |
exports: [ChatService] |
||||
}) |
}) |
||||
export class ChatModule {} |
export class ChatModule {} |
||||
|
@ -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,15 +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: number[]; |
data: number[] |
||||
} |
} |
||||
|
@ -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,15 +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: [forwardRef(() => PongModule), TypeOrmModule.forFeature([User])], |
imports: [forwardRef(() => PongModule), TypeOrmModule.forFeature([User])], |
||||
controllers: [UsersController], |
controllers: [UsersController], |
||||
providers: [UsersService], |
providers: [UsersService], |
||||
exports: [UsersService], |
exports: [UsersService] |
||||
}) |
}) |
||||
export class UsersModule {} |
export class UsersModule {} |
||||
|
Loading…
Reference in new issue