From 2720c4b262882b2307c3a5615e67bc97d965a1ea Mon Sep 17 00:00:00 2001 From: jaymar921 Date: Fri, 15 Mar 2024 16:44:17 +0800 Subject: [PATCH] Added 'EndGame' Feature for admin use --- .../Controllers/QuizSetGatewayController.cs | 8 ++++++++ .../Services/QuizHandler.cs | 8 ++++++++ .../Services/SessionHandler.cs | 17 ++++++++++++++++ .../app/room/quiz/components/interval.js | 20 +++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/WebApp/backend/QuizMaster.API.Gatewway/Controllers/QuizSetGatewayController.cs b/WebApp/backend/QuizMaster.API.Gatewway/Controllers/QuizSetGatewayController.cs index ef356241..f34b57dd 100644 --- a/WebApp/backend/QuizMaster.API.Gatewway/Controllers/QuizSetGatewayController.cs +++ b/WebApp/backend/QuizMaster.API.Gatewway/Controllers/QuizSetGatewayController.cs @@ -332,6 +332,14 @@ public IActionResult RoomProceedNextRound(int id) return Ok(new { Message = "Proceed Success"}); } + [QuizMasterAdminAuthorization] + [HttpGet("room/forceExit/{id}")] + public IActionResult RoomForceExit(int id) + { + SessionHandler.ForceExitRoom(id); + return Ok(new { Message = "Proceed Success" }); + } + [QuizMasterAuthorization] [HttpGet("room/getAllRooms")] public async Task GetAllRoomsAsync() diff --git a/WebApp/backend/QuizMaster.API.Gatewway/Services/QuizHandler.cs b/WebApp/backend/QuizMaster.API.Gatewway/Services/QuizHandler.cs index c4763006..79a08960 100644 --- a/WebApp/backend/QuizMaster.API.Gatewway/Services/QuizHandler.cs +++ b/WebApp/backend/QuizMaster.API.Gatewway/Services/QuizHandler.cs @@ -69,8 +69,10 @@ public async Task StartQuiz(SessionHub hub, SessionHandler handler, QuizRoomServ handler.SetPauseRoom(roomId, true); // <- Pause the room when before proceeding to next round handler.AddActiveRoom(room.QRoomPin, room); // register the room to be started | set to active int setIndex = 0; + bool ForcedToExit = false; foreach (var Qset in quizSets) { + if (ForcedToExit) break; // Get the Sets var setRequest = new SetRequest() { Id = Qset.QSetId }; var setReply = await grpcClient.GetQuizAsync(setRequest); @@ -82,6 +84,10 @@ public async Task StartQuiz(SessionHub hub, SessionHandler handler, QuizRoomServ int currentQuestion = 1; foreach (var questionSet in Setquestions) { + // Exit Set + ForcedToExit = handler.IsRoomForcedToExit(roomId); + if(ForcedToExit) break; + roomPin = Qset.QRoom.QRoomPin + ""; // update the participant start-time if haven't, for late joiners UpdateParticipantsStartTime(handler, roomPin); @@ -166,6 +172,7 @@ public async Task StartQuiz(SessionHub hub, SessionHandler handler, QuizRoomServ await SendParticipantsScoresAsync(hub, handler, roomPin, room, adminData, false); // send scores } + // Handling the Pause if(setIndex < quizSets.Count) { int limit = quizSettings.ForceNextRoundTimeout; // DEFAULT (300s) of 5mins, if not clicked `proceed` then continue @@ -203,6 +210,7 @@ public async Task StartQuiz(SessionHub hub, SessionHandler handler, QuizRoomServ // Clear handler.ResetParticipantLinkedConnectionsInAGroup(roomPin); handler.ClearEliminatedParticipants(Convert.ToInt32(roomPin)); + handler.ClearForcedExitRoom(); //await hub.Clients.Group(roomPin).SendAsync("notif", "Quiz Data: "+JsonConvert.SerializeObject(await GetQuizRoomDatasAsync())); //await hub.Clients.Group(roomPin).SendAsync("stop",true); } diff --git a/WebApp/backend/QuizMaster.API.Gatewway/Services/SessionHandler.cs b/WebApp/backend/QuizMaster.API.Gatewway/Services/SessionHandler.cs index 7ede0cbb..8f23b0cc 100644 --- a/WebApp/backend/QuizMaster.API.Gatewway/Services/SessionHandler.cs +++ b/WebApp/backend/QuizMaster.API.Gatewway/Services/SessionHandler.cs @@ -31,6 +31,7 @@ public class SessionHandler private Dictionary SessionId; private readonly ReportServiceHandler ReportHandler; private Dictionary RoomNextSetPaused; + private List RoomForceExitIds; public SessionHandler(ReportServiceHandler reportServiceHandler) { @@ -46,6 +47,7 @@ public SessionHandler(ReportServiceHandler reportServiceHandler) SessionId = new(); RoomNextSetPaused = new(); ReportHandler = reportServiceHandler; + RoomForceExitIds = new(); } public string GenerateSessionId(string roomPin) @@ -73,6 +75,21 @@ public bool GetPausedRoom(int roomId) return result; } + public void ForceExitRoom(int roomId) + { + RoomForceExitIds.Add(roomId); + } + + public bool IsRoomForcedToExit(int roomId) + { + return RoomForceExitIds.Contains(roomId); + } + + public void ClearForcedExitRoom() + { + RoomForceExitIds.Clear(); + } + public async Task AddToGroup(SessionHub hub, string group, string connectionId) { connectionGroupPair[connectionId] = group; diff --git a/WebApp/frontend/quiz_session/app/room/quiz/components/interval.js b/WebApp/frontend/quiz_session/app/room/quiz/components/interval.js index ae51839d..2fcbc07d 100644 --- a/WebApp/frontend/quiz_session/app/room/quiz/components/interval.js +++ b/WebApp/frontend/quiz_session/app/room/quiz/components/interval.js @@ -26,6 +26,25 @@ export default function Interval({ leaderBoard, handleCloseLeaderboard}) { } } + + const handleForceExit = () => { + + const input = prompt("Are you sure you want to end game? Yes or No", "No").toLocaleLowerCase(); + + if(input === "yes" || input === "y"){ + const roomInformationJson = localStorage.getItem("_rI"); + const roomInformation = JSON.parse(roomInformationJson); + + if(roomInformation && roomInformationJson){ + const token = localStorage.getItem("token") + fetch(BASE_URL+`/gateway/api/room/forceExit/${roomInformation.id}`, {headers:{"Authorization": `Bearer ${token}`}}, {credentials: "include"}).catch(e => {alert("Error: ",e)}) + handleCloseLeaderboard() + } + + // Always call + handleNextRound(); + } + } useEffect(() => { // const timer = setInterval(() => { // setSeconds((prevSeconds) => prevSeconds - 1); @@ -62,6 +81,7 @@ export default function Interval({ leaderBoard, handleCloseLeaderboard}) { (
+
)}