Browse Source

*leaderboard no more display 0 rank ppl

*fixed fakeusers creation
*only ranked now change players statss
master
nicolas-arnaud 2 years ago
parent
commit
2f6cb9f2d2
  1. 3
      back/volume/src/pong/entity/result.entity.ts
  2. 2
      back/volume/src/pong/game/Game.ts
  3. 17
      back/volume/src/pong/pong.service.ts
  4. 3
      back/volume/src/users/entity/user.entity.ts
  5. 7
      back/volume/src/users/users.controller.ts
  6. 170
      back/volume/src/users/users.service.ts

3
back/volume/src/pong/entity/result.entity.ts

@ -13,6 +13,9 @@ export default class Result {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number id: number
@Column()
ranked: boolean
@ManyToMany(() => User, (player: User) => player.results, { cascade: true }) @ManyToMany(() => User, (player: User) => player.results, { cascade: true })
players: Array<User | null> // TODO: change to User[] for final version players: Array<User | null> // TODO: change to User[] for final version

2
back/volume/src/pong/game/Game.ts

@ -112,7 +112,7 @@ export class Game {
async stop (): Promise<void> { async stop (): Promise<void> {
if (this.timer !== null) { if (this.timer !== null) {
await this.pongService.saveResult(this.players) await this.pongService.saveResult(this.players, this.ranked)
if (this.players.length !== 0) { if (this.players.length !== 0) {
this.gameStoppedCallback(this.players[0].name) this.gameStoppedCallback(this.players[0].name)
} }

17
back/volume/src/pong/pong.service.ts

@ -14,14 +14,17 @@ export class PongService {
private readonly usersService: UsersService private readonly usersService: UsersService
) {} ) {}
async updatePlayer (i: number, result: Result): Promise<void> { async updateStats (player: User, i: number, result: Result): Promise<void> {
const player: User | null = result.players[i]
if (player == null) return
player.matchs++ player.matchs++
if (result.score[i] > result.score[Math.abs(i - 1)]) player.wins++ if (result.score[i] > result.score[Math.abs(i - 1)]) player.wins++
else player.looses++ else player.looses++
player.winrate = (100 * player.wins) / player.matchs player.winrate = (100 * player.wins) / player.matchs
player.rank = (await this.usersService.getRank(player.ftId)) + 1 player.rank = (await this.usersService.getRank(player.ftId)) + 1
}
async updatePlayer (i: number, result: Result) {
const player: User | null = result.players[i]
if (player == null) return
if (result.ranked) this.updateStats(player, i, result)
player.results.push(result) player.results.push(result)
player.status = "online" player.status = "online"
await this.usersService.save(player) await this.usersService.save(player)
@ -33,11 +36,12 @@ export class PongService {
await this.usersService.save(player) await this.usersService.save(player)
} }
async saveResult (players: Player[]): Promise<void> { async saveResult (players: Player[], ranked: boolean): Promise<void> {
const result = new Result() const result = new Result()
const ply = new Array<User | null>() const ply = new Array<User | null>()
ply.push(await this.usersService.findUserByName(players[0].name)) ply.push(await this.usersService.findUserByName(players[0].name))
ply.push(await this.usersService.findUserByName(players[1].name)) ply.push(await this.usersService.findUserByName(players[1].name))
result.ranked = ranked;
result.players = ply result.players = ply
result.score = [players[0].score, players[1].score] result.score = [players[0].score, players[1].score]
await this.resultsRepository.save(result) await this.resultsRepository.save(result)
@ -45,14 +49,15 @@ export class PongService {
await this.updatePlayer(1, result) await this.updatePlayer(1, result)
} }
async getHistory (): Promise<Result[]> { async getHistory (ranked: boolean): Promise<Result[]> {
return await this.resultsRepository.find({ return await this.resultsRepository.find({
where: { ranked },
order: { date: 'DESC' } order: { date: 'DESC' }
}) })
} }
async getHistoryById (ftId: number): Promise<Result[]> { async getHistoryById (ftId: number): Promise<Result[]> {
const results = await this.usersService.getResults(ftId) const results = await this.usersService.getResultsById(ftId)
return results.sort((a, b) => (a.date < b.date ? 1 : -1)) return results.sort((a, b) => (a.date < b.date ? 1 : -1))
} }
} }

3
back/volume/src/users/entity/user.entity.ts

@ -6,7 +6,6 @@ import {
ManyToMany, ManyToMany,
JoinTable JoinTable
} from 'typeorm' } from 'typeorm'
import { randomUUID } from 'crypto'
import Message from 'src/chat/entity/message.entity' import Message from 'src/chat/entity/message.entity'
import Channel from 'src/chat/entity/channel.entity' import Channel from 'src/chat/entity/channel.entity'
@ -23,7 +22,7 @@ export class User {
@Column({ unique: true }) @Column({ unique: true })
ftId: number ftId: number
@Column({ unique: true, default: randomUUID() }) @Column({ unique: true})
socketKey: string socketKey: string
@Column({ unique: true }) @Column({ unique: true })

7
back/volume/src/users/users.controller.ts

@ -73,10 +73,10 @@ export class UsersController {
return await this.usersService.getRank(id) return await this.usersService.getRank(id)
} }
@Get('history') @Get('rankedHistory')
@UseGuards(AuthenticatedGuard) @UseGuards(AuthenticatedGuard)
async getHistory (): Promise<Result[]> { async getRankedHistory (): Promise<Result[]> {
return await this.pongService.getHistory() return await this.pongService.getHistory(true)
} }
@Get('history/:id') @Get('history/:id')
@ -169,6 +169,7 @@ export class UsersController {
@Param('id', ParseIntPipe) ftId: number @Param('id', ParseIntPipe) ftId: number
): Promise<User | null> { ): Promise<User | null> {
const user = await this.usersService.findUser(ftId) const user = await this.usersService.findUser(ftId)
if (!user) throw new BadRequestException('User unknown.')
user.socketKey = '' user.socketKey = ''
return user return user
} }

170
back/volume/src/users/users.service.ts

@ -1,11 +1,12 @@
import { BadRequestException, Catch, Injectable } from '@nestjs/common' import { BadRequestException, Catch, Injectable } from "@nestjs/common";
import { InjectRepository } from '@nestjs/typeorm' import { InjectRepository } from "@nestjs/typeorm";
import { EntityNotFoundError, QueryFailedError, Repository } from 'typeorm' import { EntityNotFoundError, QueryFailedError, Repository } from "typeorm";
import { User } from './entity/user.entity' import { User } from "./entity/user.entity";
import { type UserDto } from './dto/user.dto' import { type UserDto } from "./dto/user.dto";
import { type Channel } from 'src/chat/entity/channel.entity' import { type Channel } from "src/chat/entity/channel.entity";
import type Result from 'src/pong/entity/result.entity' import type Result from "src/pong/entity/result.entity";
import { Cron } from '@nestjs/schedule' import { Cron } from "@nestjs/schedule";
import { randomUUID } from "crypto";
@Injectable() @Injectable()
@Catch(QueryFailedError, EntityNotFoundError) @Catch(QueryFailedError, EntityNotFoundError)
@ -15,128 +16,127 @@ export class UsersService {
) {} ) {}
async save(user: User): Promise<void> { async save(user: User): Promise<void> {
await this.usersRepository.save(user) await this.usersRepository.save(user);
} }
async findUsers(): Promise<User[]> { async findUsers(): Promise<User[]> {
const users = await this.usersRepository.find({}) const users = await this.usersRepository.find({});
users.forEach((usr) => { users.forEach((usr) => {
usr.socketKey = '' usr.socketKey = "";
}) });
return users return users;
} }
async findUserByName(username: string): Promise<User> { async findUserByName(username: string): Promise<User> {
const user = await this.usersRepository.findOne({ const user = await this.usersRepository.findOne({
where: { username }, where: { username },
relations: { results: true } relations: { results: true },
}) });
if (user == null) throw new BadRequestException('User not found.') if (user == null) throw new BadRequestException("User not found.");
return user return user;
} }
@Cron('0 * * * * *') @Cron("0 * * * * *")
async updateStatus(): Promise<void> { async updateStatus(): Promise<void> {
const users = await this.usersRepository.find({}) const users = await this.usersRepository.find({});
users.forEach((usr) => { users.forEach((usr) => {
if (Date.now() - usr.lastAccess > 60000) { if (Date.now() - usr.lastAccess > 60000) {
usr.status = 'offline' usr.status = "offline";
this.usersRepository.save(usr).catch((err) => { this.usersRepository.save(usr).catch((err) => {
console.log(err) console.log(err);
}) });
} }
}) });
} }
async findUser (ftId: number): Promise<User> { async findUser(ftId: number): Promise<User | null> {
const user = await this.usersRepository.findOneBy({ ftId }) const user = await this.usersRepository.findOneBy({ ftId });
if (user == null) throw new BadRequestException('User not found.') if (user == null) return null;
user.lastAccess = Date.now() user.lastAccess = Date.now();
if (user.status === 'offline') user.status = 'online' if (user.status === "offline") user.status = "online";
await this.usersRepository.save(user) await this.usersRepository.save(user);
return user return user;
} }
async findOnlineUsers(): Promise<User[]> { async findOnlineUsers(): Promise<User[]> {
const users = await this.usersRepository.find({ const users = await this.usersRepository.find({
where: { status: 'online' } where: { status: "online" },
}) });
users.forEach((usr) => { users.forEach((usr) => {
usr.socketKey = '' usr.socketKey = "";
}) });
return users return users;
} }
async create(userData: UserDto): Promise<User | null> { async create(userData: UserDto): Promise<User | null> {
try { try {
const newUser = this.usersRepository.create(userData) const newUser = this.usersRepository.create(userData);
return await this.usersRepository.save(newUser) newUser.socketKey = randomUUID()
return await this.usersRepository.save(newUser);
} catch (err) { } catch (err) {
throw new BadRequestException('User already exists.') throw new BadRequestException("User already exists.");
} }
} }
async findOnlineInChannel(channel: Channel): Promise<User[]> { async findOnlineInChannel(channel: Channel): Promise<User[]> {
return await this.usersRepository return await this.usersRepository
.createQueryBuilder('user') .createQueryBuilder("user")
.where('user.channel = :chan', { chan: channel }) .where("user.channel = :chan", { chan: channel })
.andWhere('user.status := status)', { status: 'online' }) .andWhere("user.status := status)", { status: "online" })
.getMany() .getMany();
} }
async update(user: User, changes: UserDto): Promise<User | null> { async update(user: User, changes: UserDto): Promise<User | null> {
this.usersRepository.merge(user, changes) this.usersRepository.merge(user, changes);
return await this.usersRepository.save(user) return await this.usersRepository.save(user);
} }
async addAvatar(ftId: number, filename: string): Promise<void> { async addAvatar(ftId: number, filename: string): Promise<void> {
await this.usersRepository.update({ ftId }, { avatar: filename }) await this.usersRepository.update({ ftId }, { avatar: filename });
} }
async getFriends(ftId: number): Promise<User[]> { async getFriends(ftId: number): Promise<User[]> {
const user = await this.usersRepository.findOne({ const user = await this.usersRepository.findOne({
where: { ftId }, where: { ftId },
relations: { friends: true } relations: { friends: true },
}) });
if (user == null) throw new BadRequestException('User not found.') if (user == null) throw new BadRequestException("User not found.");
return user.friends return user.friends;
} }
async getInvits(ftId: number): Promise<User[]> { async getInvits(ftId: number): Promise<User[]> {
const user = await this.usersRepository.findOne({ const user = await this.usersRepository.findOne({
where: { ftId }, where: { ftId },
relations: { relations: {
followers: true followers: true,
} },
}) });
if (user == null) throw new BadRequestException('User not found.') if (user == null) throw new BadRequestException("User not found.");
return user.followers return user.followers;
} }
async getResults (ftId: number): Promise<Result[]> { async getResultsById(ftId: number): Promise<Result[]> {
const user = await this.usersRepository.findOne({ const user = await this.usersRepository.findOne({
where: { ftId }, where: { ftId },
relations: { relations: { results: { players: true } },
results: { });
players: true if (user == null) throw new BadRequestException("User not found.");
} return user.results;
}
})
if (user == null) throw new BadRequestException('User not found.')
return user.results
} }
async getLeaderboard(): Promise<User[]> { async getLeaderboard(): Promise<User[]> {
return await this.usersRepository.find({ let leaderboard = await this.usersRepository.find({
order: { order: {
winrate: 'DESC' winrate: "DESC",
} },
}) });
return leaderboard.filter((user) => user.rank !== 0);
} }
async getRank(ftId: number): Promise<number> { async getRank(ftId: number): Promise<number> {
const leader = await this.getLeaderboard() const leader = await this.getLeaderboard();
return leader.findIndex((user) => user.ftId === ftId) return leader.findIndex((user) => user.ftId === ftId);
} }
async invit(ftId: number, targetFtId: number): Promise<void> { async invit(ftId: number, targetFtId: number): Promise<void> {
@ -144,30 +144,30 @@ export class UsersService {
where: { ftId }, where: { ftId },
relations: { relations: {
followers: true, followers: true,
friends: true friends: true,
} },
}) });
if (user == null) throw new BadRequestException('User not found.') if (user == null) throw new BadRequestException("User not found.");
if (user.friends.findIndex((friend) => friend.ftId === targetFtId) !== -1) { if (user.friends.findIndex((friend) => friend.ftId === targetFtId) !== -1) {
throw new BadRequestException('You are already friends.') throw new BadRequestException("You are already friends.");
} }
const target: User | null = await this.usersRepository.findOne({ const target: User | null = await this.usersRepository.findOne({
where: { ftId: targetFtId }, where: { ftId: targetFtId },
relations: { relations: {
followers: true, followers: true,
friends: true friends: true,
} },
}) });
if (target == null) throw new BadRequestException('Target not found.') if (target == null) throw new BadRequestException("Target not found.");
const id = user.followers.findIndex( const id = user.followers.findIndex(
(follower) => follower.ftId === targetFtId (follower) => follower.ftId === targetFtId
) );
if (id !== -1) { if (id !== -1) {
user.friends.push(target) user.friends.push(target);
if (user.ftId !== target.ftId) target.friends.push(user) if (user.ftId !== target.ftId) target.friends.push(user);
user.followers.slice(id, 1) user.followers.slice(id, 1);
await this.usersRepository.save(user) await this.usersRepository.save(user);
} else target.followers.push(user) } else target.followers.push(user);
await this.usersRepository.save(target) await this.usersRepository.save(target);
} }
} }

Loading…
Cancel
Save