diff --git a/backend/code/src/auth/constants/constants.ts b/backend/code/src/auth/constants/constants.ts index fa95f40..b299b8a 100644 --- a/backend/code/src/auth/constants/constants.ts +++ b/backend/code/src/auth/constants/constants.ts @@ -1,4 +1,4 @@ export const JwtConsts = { - at_secret: 'at_secret', - rt_secret: 'rt_secret', + at_secret: process.env.AT_SECRET, + rt_secret: process.env.RT_SECRET, }; diff --git a/backend/code/src/game/game.service.ts b/backend/code/src/game/game.service.ts index 49d1aa5..5c9c1d4 100644 --- a/backend/code/src/game/game.service.ts +++ b/backend/code/src/game/game.service.ts @@ -21,17 +21,37 @@ export class GameService { []; @OnEvent('game.start') - async handleGameStartEvent(data: { client: Socket; gameMode: string }) { - const client = data.client; - const gameMode = data.gameMode; - const userId = client.data.user.sub; - const userData = await this.getUser(userId); - client.data.inQueue = true; - if (gameMode === 'cassic') - this.classicwaitingPlayers.push({ socket: client, userData: userData }); - else if (gameMode === 'extra') - this.extraWaitingPlayers.push({ socket: client, userData: userData }); - console.log('client subscribed to the queue'); + async handleGameStartEvent(data: { + client: Socket; + gameMode: string; + mode: string; + }) { + if (data.mode === 'register') { + const client = data.client; + if (client.data.user?.inQueue) return; + const gameMode = data.gameMode; + const userId = client.data.user.sub; + const userData = await this.getUser(userId); + client.data.user.inQueue = true; + + if (gameMode === 'cassic') + this.classicwaitingPlayers.push({ socket: client, userData: userData }); + else if (gameMode === 'extra') + this.extraWaitingPlayers.push({ socket: client, userData: userData }); + console.log('client subscribed to the queue'); + } else if (data.mode === 'unregister') { + const client = data.client; + const gameMode = data.gameMode; + client.data.user.inQueue = false; + if (gameMode === 'cassic') + this.classicwaitingPlayers = this.classicwaitingPlayers.filter( + (player) => player.socket.id !== client.id, + ); + else if (gameMode === 'extra') + this.extraWaitingPlayers = this.extraWaitingPlayers.filter( + (player) => player.socket.id !== client.id, + ); + } } //NOTE: add game modes here diff --git a/backend/code/src/gateways/gateways.gateway.ts b/backend/code/src/gateways/gateways.gateway.ts index 6bdebac..43db25d 100644 --- a/backend/code/src/gateways/gateways.gateway.ts +++ b/backend/code/src/gateways/gateways.gateway.ts @@ -214,9 +214,22 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { @SubscribeMessage('startGame') handleGameStartEvent(client: Socket, data: { gameMode: string }) { - console.log(client.data.user); - this.eventEmitter.emit('game.start', { client, gameMode: data.gameMode }); + this.eventEmitter.emit('game.start', { + client, + gameMode: data.gameMode, + mode: 'register', + }); + } + + @SubscribeMessage('quitQueue') + async handleQuitQueueEvent(client: Socket, data: { gameMode: string }) { + this.eventEmitter.emit('game.start', { + client, + gameMode: data.gameMode, + mode: 'unregister', + }); } + // @SubscribeMessage('getPlayers') // getPlayers() { // this.server.emit("players",[this.p1Data ,this.p2Data]) @@ -299,16 +312,20 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { ); // launch the game - this.eventEmitter.emit('game.launched', [ - { - socket: game_invite.client, - userData: invterData, - }, - { - socket: client, - userData: opponentData, - }, - ]); + this.eventEmitter.emit( + 'game.launched', + [ + { + socket: game_invite.client, + userData: invterData, + }, + { + socket: client, + userData: opponentData, + }, + ], + game_invite.gameMode, + ); } @SubscribeMessage('declineGame') @@ -344,6 +361,7 @@ export class Gateways implements OnGatewayConnection, OnGatewayDisconnect { clients.forEach((client: any) => { client.socket.join(game_channel); client.socket.data.user.inGame = true; + client.socket.data.user.inQueue = false; }); const new_game = new Game(this.eventEmitter, this.server, mode); diff --git a/backend/code/src/messages/messages.service.ts b/backend/code/src/messages/messages.service.ts index 3ea3528..8902226 100644 --- a/backend/code/src/messages/messages.service.ts +++ b/backend/code/src/messages/messages.service.ts @@ -129,7 +129,6 @@ export class MessagesService { HttpStatus.UNAUTHORIZED, ); } - //TESTING: for later testing const messages = await this.prisma.message.findMany({ where: { roomId: channelId, @@ -157,6 +156,54 @@ export class MessagesService { take: limit, }); + // get rppm type of room + const room = await this.prisma.room.findUnique({ + where: { + id: channelId, + }, + select: { + type: true, + }, + }); + + if (room.type === 'dm') { + const blocked = await this.prisma.blockedUsers.findFirst({ + where: { + dmRoomId: channelId, + }, + }); + if (blocked) { + messages.forEach((message) => { + if (message.authorId !== userId) { + message.content = '[REDUCTED]'; + } + }); + } + } else { + // get authors ids without duplicats + const authorsIds = messages.reduce((acc, message) => { + if (!acc.includes(message.authorId)) { + acc.push(message.authorId); + } + return acc; + }, []); + + const usersblocked = await this.prisma.blockedUsers.findMany({ + where: { + id: { + in: authorsIds.map((id) => [id, userId].sort().join('-')), + }, + }, + }); + const blockedUsersIds = usersblocked.map((user) => + user.id.split('-').find((id) => id !== userId), + ); + messages.forEach((message) => { + if (blockedUsersIds.includes(message.authorId)) { + message.content = '[REDUCTED]'; + } + }); + } return messages.map((message) => new MessageFormatDto(message)); } } diff --git a/backend/code/src/profile/profile.service.ts b/backend/code/src/profile/profile.service.ts index 716332d..d97f361 100644 --- a/backend/code/src/profile/profile.service.ts +++ b/backend/code/src/profile/profile.service.ts @@ -28,8 +28,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, false); } @@ -58,8 +58,8 @@ export class ProfileService { wonMatches === 0 ? null : wonMatches >= 100 - ? 2 - : Math.floor(Math.log10(wonMatches)); + ? 2 + : Math.floor(Math.log10(wonMatches)); return new ProfileDto({ ...user, achievement }, true); } diff --git a/backend/code/src/rooms/rooms.service.ts b/backend/code/src/rooms/rooms.service.ts index ea1b7e8..beeb64a 100644 --- a/backend/code/src/rooms/rooms.service.ts +++ b/backend/code/src/rooms/rooms.service.ts @@ -648,8 +648,15 @@ export class RoomsService { select: { content: true, createdAt: true, + authorId: true, }, }); + const blocked = await this.prisma.blockedUsers.findFirst({ + where: { + id: [userId, last_message.authorId].sort().join('-'), + }, + }); + const is_owner = room.ownerId === userId; return { id: room.id, @@ -658,7 +665,7 @@ export class RoomsService { is_admin: room.members[0].is_admin, is_owner, countMembers, - last_message, + last_message: blocked ? null : last_message, }; }), ); @@ -714,6 +721,12 @@ export class RoomsService { createdAt: true, }, }); + const blocked = await this.prisma.blockedUsers.findFirst({ + where: { + id: [userId, secondMember.user.userId].sort().join('-'), + }, + }); + const avatar: PICTURE = { thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${secondMember.user.avatar}`, medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${secondMember.user.avatar}`, @@ -723,7 +736,7 @@ export class RoomsService { id: room.id, name: secondMember.user.firstName + ' ' + secondMember.user.lastName, secondMemberId: secondMember.user.userId, - last_message, + last_message: blocked ? null : last_message, avatar, bio: secondMember.user.discreption, }; @@ -763,6 +776,7 @@ export class RoomsService { const secondMember = room.members.find( (member) => member.user.userId !== userId, ); + const avatar: PICTURE = { thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${secondMember.user.avatar}`, medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${secondMember.user.avatar}`, diff --git a/frontend/code/src/Components/Game/index.tsx b/frontend/code/src/Components/Game/index.tsx index fdfa3d0..e1dcfc9 100644 --- a/frontend/code/src/Components/Game/index.tsx +++ b/frontend/code/src/Components/Game/index.tsx @@ -103,7 +103,7 @@ export const Game = () => { navigate("/home") const divh = document.getElementById('Game')?.offsetHeight const divw = document.getElementById('Game')?.offsetWidth - socketStore.socket.emit("screen",{h:divh,w:divw}) + socketStore.socket.emit("screen",{h:divh,w:divw}) if (divw) {divw <= 742 ? gameState.setMobile(true) : gameState.setMobile(false)} window.addEventListener('resize', () => { diff --git a/frontend/code/src/Components/Play/assets/queuemodal.tsx b/frontend/code/src/Components/Play/assets/queuemodal.tsx new file mode 100644 index 0000000..e42ca67 --- /dev/null +++ b/frontend/code/src/Components/Play/assets/queuemodal.tsx @@ -0,0 +1,35 @@ +import { forwardRef } from "react"; +import { useSocketStore } from "../../Chat/Services/SocketsServices"; + +export const QueueWaitModal = forwardRef( + (props, ref) => { + const socketStore = useSocketStore(); + return ( + +
+
+
+ We are looking for a player for you + loading +
+
+
+ +
+
+
+
+
+ ); + }, +); diff --git a/frontend/code/src/Components/Play/index.tsx b/frontend/code/src/Components/Play/index.tsx index 96fd1c1..c42bc2f 100644 --- a/frontend/code/src/Components/Play/index.tsx +++ b/frontend/code/src/Components/Play/index.tsx @@ -1,40 +1,67 @@ -import VsBot from './assets/VsBot.svg' -import vsUser from './assets/VsUser.svg' -import { useSocketStore } from '../Chat/Services/SocketsServices' -import toast from 'react-hot-toast' +import VsBot from "./assets/VsBot.svg"; +import vsUser from "./assets/VsUser.svg"; +import { useSocketStore } from "../Chat/Services/SocketsServices"; +import toast from "react-hot-toast"; +import { QueueWaitModal } from "./assets/queuemodal"; +import { useRef, useState } from "react"; export const Play = () => { - const socketStore = useSocketStore(); - const subscribeToGame = async() => { - // socketStore.socket.emit - try { - socketStore.socket.emit("startGame",{gameMode:"cassic"}); - toast.success("Match making in Progress you can move until find opponent" - ,{ - duration:5000 - }) - } catch (error) { - toast.error("can not start game") - } + const socketStore = useSocketStore(); + const [gameMode, setGameMode] = useState(""); + const queueModalRef = useRef(null); + const subscribeToGame = async () => { + // socketStore.socket.emit + try { + socketStore.socket.emit("startGame", { gameMode: "cassic" }); + setGameMode("cassic"); + queueModalRef.current?.showModal(); + toast.success( + "Match making in Progress you can move until find opponent", + { + duration: 5000, + }, + ); + } catch (error) { + toast.error("can not start game"); } - const subscribeToGameExtra = async() => { - // socketStore.socket.emit - try { - socketStore.socket.emit("startGame",{gameMode:"extra"}); - toast.success("Match making in Progress you can move until find opponent" - ,{ - duration:5000 - }) - } catch (error) { - toast.error("can not start game") - } + }; + const subscribeToGameExtra = async () => { + // socketStore.socket.emit + try { + socketStore.socket.emit("startGame", { gameMode: "extra" }); + setGameMode("extra"); + queueModalRef.current?.showModal(); + toast.success( + "Match making in Progress you can move until find opponent", + { + duration: 5000, + }, + ); + } catch (error) { + toast.error("can not start game"); } - return( - <> -
-
- -
-
- - ) -} \ No newline at end of file + }; + return ( + <> +
+
+ +
+ +
+ +
+
+ + + ); +}; diff --git a/frontend/code/src/Components/Profile/index.tsx b/frontend/code/src/Components/Profile/index.tsx index a1b055f..93ea200 100644 --- a/frontend/code/src/Components/Profile/index.tsx +++ b/frontend/code/src/Components/Profile/index.tsx @@ -365,7 +365,7 @@ export const Profile = () => { { inviterId: user.id, opponentId: profile.id, - gameMode: "classic", + gameMode: "cassic", }, (data: { error: string | null; @@ -383,6 +383,32 @@ export const Profile = () => { > Invite to a classic game +
  • { + socketStore?.socket?.emit( + "inviteToGame", + { + inviterId: user.id, + opponentId: profile.id, + gameMode: "extra", + }, + (data: { + error: string | null; + gameId: string; + }) => { + if (data.error) { + toast.error(data.error); + return; + } + user.setGameWaitingId(data.gameId); + inviteWaitingModalRef.current?.showModal(); + }, + ); + }} + > + Invite to a custom game +
  • {