(int)$this->userId, "sessionId" => (int)$this->sessionId, "score" => (float)$this->score ?? 0.0, "firePrecision" => (float)$this->firePrecision ?? 0.0, "reactionTime" => (float)$this->reactionTime ?? 0.0, "nbEnemyHit" => (int)$this->nbEnemyHit ?? 0, "nbCivilsHit" => (int)$this->nbCivilsHit ?? 0, "damageTaken" => (int)$this->damageTaken ?? 0, "endStatus" => (int)$this->endStatus ?? 0, "avatar" => $this->avatar ?? "", "weapon" => $this->weapon ?? "", "roleId" => $this->role, "resultsAsString" => $this->results ); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function readRow (array $row) { $this->userId = (int)$row['userId']; $this->sessionId = (int)$row['sessionId']; $this->score = (int)$row['score']; $this->firePrecision = (float)$row['firePrecision']; $this->reactionTime = (float)$row['reactionTime']; $this->nbEnemyHit = (int)$row['nbEnemyHit']; $this->nbCivilsHit = (int)$row['nbCivilsHit']; $this->damageTaken = (int)$row['damageTaken']; $this->endStatus = (int)$row['endStatus']; $this->avatar = $row['avatar']; $this->weapon = $row['weapon']; $this->role = $row['role']; $this->results = $row['results']; //$this->replayFileName = $row['replayFileName']; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function sanitize () { $this->userId=htmlspecialchars(strip_tags($this->userId)); $this->sessionId=htmlspecialchars(strip_tags($this->sessionId)); $this->avatar=htmlspecialchars(strip_tags($this->avatar)); $this->weapon=htmlspecialchars(strip_tags($this->weapon)); $this->role=htmlspecialchars(strip_tags($this->role)); $this->results=htmlspecialchars(strip_tags($this->results)); //$this->nbCivilsHit=htmlspecialchars(strip_tags($this->nbCivilsHit)); //$this->nbEnemyHit=htmlspecialchars(strip_tags($this->nbEnemyHit)); //$this->score=htmlspecialchars(strip_tags($this->score)); //$this->firePrecision=htmlspecialchars(strip_tags($this->firePrecision)); //$this->damageTaken=htmlspecialchars(strip_tags($this->damageTaken)); //$this->replayFileName=htmlspecialchars(strip_tags($this->replayFileName)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function load () { // select all query with user inputed username and password $query = "SELECT * FROM " . $this->table_name . " WHERE userId='" . $this->userId . "' AND sessionId='" . $this->sessionId . "'"; // prepare query statement $stmt = $this->conn->prepare($query); // execute query $stmt->execute(); if($stmt->rowCount() > 0) { // get retrieved row $row = $stmt->fetch(PDO::FETCH_ASSOC); // retrieve session values $this->readRow($row); return true; } return false; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function registerUser () { //$this->sessionId = $session; //$this->userId = $user; //$this->avatar = $avatar; //$this->weapon = $weapon; if ($this->alreadyRegistered()) return false; // query to insert record of new user signup $query = "INSERT INTO " . $this->table_name . " SET sessionId=:sessionId, userId=:userId, avatar=:avatar, weapon=:weapon, role=:role"; // prepare query $stmt = $this->conn->prepare($query); // sanitize $this->sanitize(); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); $stmt->bindParam(":avatar", $this->avatar); $stmt->bindParam(":weapon", $this->weapon); $stmt->bindParam(":role", $this->role); //$stmt->bindParam(":nbCivilsHit", $this->nbCivilsHit); //$stmt->bindParam(":nbEnemyHit", $this->nbEnemyHit); //$stmt->bindParam(":score", $this->score); //$stmt->bindParam(":firePrecision", $this->firePrecision); //$stmt->bindParam(":damageTaken", $this->damageTaken); //$stmt->bindParam(":replayFileName", $this->replayFileName); // execute query return $stmt->execute(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function alreadyRegistered () { $query = "SELECT * FROM " . $this->table_name . " WHERE userId=:userId AND sessionId=:sessionId"; // prepare query statement $stmt = $this->conn->prepare($query); // sanitize $this->userId=htmlspecialchars(strip_tags($this->userId)); $this->sessionId=htmlspecialchars(strip_tags($this->sessionId)); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); // execute query $stmt->execute(); return $stmt->rowCount() > 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function updateUserScores () { //$this->sessionId = $sessionId; //$this->userId = $userId; // load current values $this->load(); $this->score = 0; $query = "SELECT sessionType FROM Sessions WHERE id='" . $this->sessionId . "'"; // prepare query $stmt = $this->conn->prepare($query); $stmt->execute(); if($stmt->rowCount() > 0) { $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row['sessionType'] == 0) // FireRange { $query = "SELECT R.id, R.hitPrecision, R.objectHitLocationX, R.objectHitLocationY, R.distance, R.objectHitTagLocation " . " FROM " . REACTEVENTS_TABLE_NAME . " R, " . TRIGGEREVENTS_TABLE_NAME . " T " . " WHERE R.srcEventSessionId=T.sessionId AND R.srcEventIndex=T.indexCount AND T.srcUserId=:userId AND T.sessionId=:sessionId"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); //$stmt->bindParam(":score", $this->score); //$stmt->bindParam(":role", $role); // execute query $stmt->execute(); $totalPrecision=0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $totalPrecision += $row['hitPrecision']; $this->score = calculate_firerange_v1($totalPrecision); } else { $query = "SELECT R.id, R.hitPrecision, R.distance, R.reactType, P.nbCivilsHit " . " FROM " . REACTEVENTS_TABLE_NAME . " R, " . TRIGGEREVENTS_TABLE_NAME . " T, " . $this->table_name . " P " . " WHERE R.srcEventIndex=T.indexCount AND R.srcEventSessionId=T.sessionId AND P.sessionId=R.srcEventSessionId AND P.userId=T.srcUserId " . " AND R.srcEventSessionId=:sessionId AND T.srcUserId=:userId AND (R.reactType=0 OR R.reactType=4 OR R.reactType=5)"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); //$stmt->bindParam(":score", $this->score); //$stmt->bindParam(":role", $role); // execute query $stmt->execute(); if ($stmt->rowCount() > 0) { $totalPrecision=0; $nbCivilHits=0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $nbCivilHits = $row['nbCivilsHit']; if ($row['reactType']==0) // todo : to keep ? $totalPrecision += $row['hitPrecision']; } $this->score = calculate_v1($totalPrecision, $nbCivilHits); } } } $query = "UPDATE " . $this->table_name . " SET score=:score WHERE sessionId=:sessionId AND userId=:userId"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); $stmt->bindParam(":score", $this->score); // update overall averages for participation user $query_Precision = "SELECT X.UserId AS UserId, SUM(X.NbShotsFired) AS nbFire, SUM(Y.HitPrecision) AS precisionTotal FROM " . " (SELECT P.userID AS UserId, P.sessionId AS SessionId, TE.indexCount AS IndexCount, COUNT(DISTINCT TE.sessionId, TE.indexCount) AS NbShotsFired FROM " . PARTICIPATES_TABLE_NAME . " P, " . TRIGGEREVENTS_TABLE_NAME . " TE " . " WHERE P.sessionId=TE.sessionId AND TE.srcUserId=P.UserId GROUP BY P.UserId, P.sessionId, TE.indexCount) AS X LEFT JOIN (SELECT P.userID AS UserId, P.sessionId AS SessionId, TE.indexCount AS IndexCount, MAX(RE.hitPrecision) AS HitPrecision FROM " . PARTICIPATES_TABLE_NAME . " P, " . TRIGGEREVENTS_TABLE_NAME . " TE, " . REACTEVENTS_TABLE_NAME . " RE WHERE P.sessionId=TE.sessionId AND P.sessionId=RE.srcEventSessionId AND TE.srcUserId=P.UserId AND RE.srcEventIndex=TE.indexCount GROUP BY P.UserId, P.sessionId, TE.indexCount) AS Y ON (X.UserId=Y.UserId AND X.SessionId=Y.SessionId AND X.IndexCount=Y.IndexCount) WHERE X.UserId=:userId GROUP BY UserId"; $query_ReactionTime = "SELECT P.userID AS UserId, SUM(CASE WHEN RE.reactTime>0 THEN 1 ELSE 0 END) AS nbHits, SUM(RE.reactTime) AS reactTimeTotal FROM " . PARTICIPATES_TABLE_NAME . " P, " . TRIGGEREVENTS_TABLE_NAME . " TE, " . REACTEVENTS_TABLE_NAME . " RE WHERE P.sessionId=TE.sessionId AND P.sessionId=RE.srcEventSessionId AND TE.srcUserId=P.UserId AND RE.srcEventIndex=TE.indexCount AND P.UserId=:userId GROUP BY P.UserId"; $stmt_Precision = $this->conn->prepare($query_Precision); $stmt_ReactionTime = $this->conn->prepare($query_ReactionTime); $stmt_Precision->bindParam(":userId", $this->userId); $stmt_ReactionTime->bindParam(":userId", $this->userId); $stmt_Precision->execute(); $stmt_ReactionTime->execute(); $res_UpdatePrecision = true; $res_UpdateReactionTime = true; if ($stmt_Precision->rowCount() > 0 && $this->userId > 0) { // get retrieved row $row = $stmt_Precision->fetch(PDO::FETCH_ASSOC); $shotFired = $row['nbFire']; // retrieve average precision per shot $userPrecision = $row['precisionTotal']/($shotFired == 0 ? 1 : $shotFired); $updatePrecision = "UPDATE " . USERS_TABLE_NAME . " SET avgPrecision=" . $userPrecision . " WHERE id=" . $this->userId; $stmt_UpdatePrecision = $this->conn->prepare($updatePrecision); $res_UpdatePrecision = $stmt_UpdatePrecision->execute(); } if ($stmt_ReactionTime->rowCount() > 0 && $this->userId > 0) { // get retrieved row $row = $stmt_ReactionTime->fetch(PDO::FETCH_ASSOC); $shotHits = $row['nbHits']; // retrieve average reactionTime per shot $userReactionTime = $row['reactTimeTotal']/($shotHits == 0 ? 1 : $shotHits); $updateReactionTime = "UPDATE " . USERS_TABLE_NAME . " SET avgReaction=" . $userReactionTime . " WHERE id=" . $this->userId; $stmt_UpdateReactionTime = $this->conn->prepare($updateReactionTime); $res_UpdateReactionTime = $stmt_UpdateReactionTime->execute(); } return $stmt->execute() && $res_UpdatePrecision && $res_UpdateReactionTime; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function updateObjectives () { // load current values //$this->load(); // sanitize JSON string //$this->results=htmlspecialchars(strip_tags($this->results)); // update participation with objective results in database $query = "UPDATE " . $this->table_name . " SET results=:results WHERE sessionId=:sessionId AND userId=:userId"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); $stmt->bindParam(":results", $this->results); return $stmt->execute(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function userLeaves () { //$this->userId = $userId; //$this->sessionId = $sessionId; // load current values $this->load(); // queries to update user stats $query_NbShotFired = "SELECT COUNT(DISTINCT TE.indexCount) AS nbFire FROM " . TRIGGEREVENTS_TABLE_NAME . " TE WHERE TE.sessionId=:sessionId AND TE.srcUserId=:userId"; $query_NbEnemyHit = "SELECT COUNT(DISTINCT TE.indexCount, RE.hitTargetName) AS nbEnemyHits FROM " . TRIGGEREVENTS_TABLE_NAME . " TE, " . REACTEVENTS_TABLE_NAME . " RE WHERE TE.sessionId=:sessionId AND RE.srcEventSessionId=TE.sessionId AND RE.srcEventIndex=TE.indexCount AND TE.srcUserId=:userId AND RE.reactType=0"; $query_NbCivilHit = "SELECT COUNT(DISTINCT TE.indexCount, RE.hitTargetName) AS nbCivilHits FROM " . TRIGGEREVENTS_TABLE_NAME . " TE, " . REACTEVENTS_TABLE_NAME . " RE WHERE TE.sessionId=:sessionId AND RE.srcEventSessionId=TE.sessionId AND RE.srcEventIndex=TE.indexCount AND TE.srcUserId=:userId AND RE.reactType=1"; $query_PrecisionAndReactionTime = "SELECT SUM(X.precisionByShot) AS precisionTotal, SUM(X.reactTimeByShot) AS reactTimeTotal, COUNT(CASE WHEN X.reactTime > 0 THEN 1 ELSE 0 END) AS shots FROM (SELECT COALESCE(RE.hitPrecision,0) AS precisionByShot, COALESCE(RE.reactTime,0) AS reactTimeByShot, RE.reactTime AS reactTime FROM " . TRIGGEREVENTS_TABLE_NAME . " TE, " . REACTEVENTS_TABLE_NAME . " RE WHERE TE.sessionId=:sessionId AND TE.srcUserId=:userId AND TE.sessionId = RE.srcEventSessionId AND TE.indexCount = RE.srcEventIndex AND (RE.reactType=0 OR RE.reactType=4 OR RE.reactType=5) GROUP BY TE.sessionId, TE.srcUserId, TE.indexCount) AS X"; // prepare queries $stmt_NbShotFired = $this->conn->prepare($query_NbShotFired); $stmt_NbEnemyHit = $this->conn->prepare($query_NbEnemyHit); $stmt_NbCivilHit = $this->conn->prepare($query_NbCivilHit); $stmt_PrecisionAndReactionTime = $this->conn->prepare($query_PrecisionAndReactionTime); // bind values $stmt_NbShotFired->bindParam(":sessionId", $this->sessionId); $stmt_NbShotFired->bindParam(":userId", $this->userId); $stmt_NbEnemyHit->bindParam(":sessionId", $this->sessionId); $stmt_NbEnemyHit->bindParam(":userId", $this->userId); $stmt_NbCivilHit->bindParam(":sessionId", $this->sessionId); $stmt_NbCivilHit->bindParam(":userId", $this->userId); $stmt_PrecisionAndReactionTime->bindParam(":sessionId", $this->sessionId); $stmt_PrecisionAndReactionTime->bindParam(":userId", $this->userId); // execute queries $stmt_NbShotFired->execute(); $stmt_NbEnemyHit->execute(); $stmt_NbCivilHit->execute(); $stmt_PrecisionAndReactionTime->execute(); $shotFired=1; if ($stmt_NbShotFired->rowCount() > 0) { // get retrieved row $row = $stmt_NbShotFired->fetch(PDO::FETCH_ASSOC); // retrieve nbFire value $shotFired = $row['nbFire']; } if ($stmt_NbEnemyHit->rowCount() > 0) { // get retrieved row $row = $stmt_NbEnemyHit->fetch(PDO::FETCH_ASSOC); // retrieve nbEnemyHits value $this->nbEnemyHit = $row['nbEnemyHits']; } if ($stmt_NbCivilHit->rowCount() > 0) { // get retrieved row $row = $stmt_NbCivilHit->fetch(PDO::FETCH_ASSOC); // retrieve nbCivilHits value $this->nbCivilsHit = $row['nbCivilHits']; } if ($stmt_PrecisionAndReactionTime->rowCount() > 0) { // get retrieved row $row = $stmt_PrecisionAndReactionTime->fetch(PDO::FETCH_ASSOC); $shotsWithReactTime = (int)$row['shots']; if ($shotsWithReactTime <= 0) $shotsWithReactTime = 1; // retrieve average precision per shot $this->firePrecision = $row['precisionTotal']/($shotFired == 0 ? 1 : $shotFired); // retrieve average reactionTime per shot $this->reactionTime = $row['reactTimeTotal']/$shotsWithReactTime; } return $this->update() && $stmt_NbShotFired->rowCount() > 0 && $stmt_NbEnemyHit->rowCount() > 0 && $stmt_NbCivilHit->rowCount() > 0 && $stmt_PrecisionAndReactionTime->rowCount() > 0 /* && $stmt_Precision->rowCount() > 0 && $stmt_ReactionTime->rowCount() > 0*/; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function update () { $query = "UPDATE " . $this->table_name . " SET nbEnemyHit=:nbEnemyHit, nbCivilsHit=:nbCivilsHit, firePrecision=:firePrecision, reactionTime=:reactionTime " . " WHERE sessionId='".$this->sessionId."' AND userId='".$this->userId."'"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":nbEnemyHit", $this->nbEnemyHit); $stmt->bindParam(":nbCivilsHit", $this->nbCivilsHit); $stmt->bindParam(":firePrecision", $this->firePrecision); $stmt->bindParam(":reactionTime", $this->reactionTime); // execute query if ($stmt->execute()) { // once it has been updated, we have to update the averagePrecision field in the USERS_TABLE_NAME table $query = "UPDATE " . USERS_TABLE_NAME . " SET avgPrecision=(SELECT AVG(firePrecision) FROM " . PARTICIPATES_TABLE_NAME . " P WHERE P.userId='".$this->userId."'), avgReaction=(SELECT AVG(reactionTime) FROM " . PARTICIPATES_TABLE_NAME . " P WHERE P.userId='".$this->userId."') WHERE users.id='".$this->userId."'"; // prepare query $stmt = $this->conn->prepare($query); // execute query return $stmt->execute(); } return false; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function updateScore () { $query = "UPDATE " . $this->table_name . " SET score=:score WHERE sessionId=:sessionId AND userId=:userId"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); $stmt->bindParam(":userId", $this->userId); $stmt->bindParam(":score", $this->score); return $stmt->execute(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function getAllUsersInSession () { $query = "SELECT DISTINCT userId FROM " . $this->table_name . " WHERE sessionId=:sessionId"; // prepare query $stmt = $this->conn->prepare($query); // bind values $stmt->bindParam(":sessionId", $this->sessionId); // execute query $stmt->execute(); $usersIdForSession = array(); // loop through results while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // retrieve user ids array_push( $usersIdForSession, $row['userId'] ); } return $usersIdForSession; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function copy (UserInGameSession $otherParticipation) { $this->userId = $otherParticipation->userId; $this->sessionId = $otherParticipation->sessionId; $this->score = $otherParticipation->score; // need to call calculateAverages manually $this->firePrecision = $otherParticipation->firePrecision; // need to call calculateAverages manually $this->reactionTime = $otherParticipation->reactionTime; // need to call calculateAverages manually $this->nbEnemyHit = $otherParticipation->nbEnemyHit; // total $this->nbCivilsHit = $otherParticipation->nbCivilsHit; // total $this->damageTaken = $otherParticipation->damageTaken; // total $this->endStatus = $otherParticipation->endStatus; // TODO : mixed ? $this->avatar = $otherParticipation->avatar; $this->weapon = $otherParticipation->weapon; $this->role = $otherParticipation->role; // TODO if ($this->results != null && $otherParticipation->results != null) $this->results = $otherParticipation->results; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function add (UserInGameSession $otherParticipation) { if ($this->userId != $otherParticipation->userId) $this->userId = -1; if ($this->sessionId != $otherParticipation->sessionId) $this->sessionId = -1; $this->score += $otherParticipation->score; // need to call calculateAverages manually $this->firePrecision += $otherParticipation->firePrecision; // need to call calculateAverages manually $this->reactionTime += $otherParticipation->reactionTime; // need to call calculateAverages manually $this->nbEnemyHit += $otherParticipation->nbEnemyHit; // total $this->nbCivilsHit += $otherParticipation->nbCivilsHit; // total $this->damageTaken += $otherParticipation->damageTaken; // total $this->endStatus = $this->endStatus; // TODO : mixed ? if ($this->avatar != $otherParticipation->avatar) $this->avatar = "various avatars"; if ($this->weapon != $otherParticipation->weapon) $this->weapon = "various weapons"; $this->role = $this->role; // TODO $this->addResults($otherParticipation); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function addResults (UserInGameSession $otherParticipation) { // add resultsObject debriefs if ($this->results != null && $otherParticipation->results != null) { $resultsObject = UserInGameSessionResults::fromJsonString($this->results); $otherParticipationResultsObject = UserInGameSessionResults::fromJsonString($otherParticipation->results); if ($resultsObject != null && $otherParticipationResultsObject) { $resultsObject->add($otherParticipationResultsObject); // update results string $this->results = json_encode($resultsObject); } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function calculateAverages ($nb) { if ($nb > 0) { $this->score /= $nb; // average $this->firePrecision /= $nb; // average $this->reactionTime /= $nb; // average $this->nbEnemyHit = $this->nbEnemyHit; // total $this->nbCivilsHit = $this->nbCivilsHit; // total $this->damageTaken = $this->damageTaken; // total // calculate averages for scores of resultsObject $resultsObject = UserInGameSessionResults::fromJsonString($this->results); $resultsObject->calculateAverages($nb); // update results string $this->results = json_encode($resultsObject); } } } ?>